Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

style: improve question submission form UI #164

Merged
merged 6 commits into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 89 additions & 33 deletions src/components/QuestionSubmissionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,39 @@ interface QuestionSubmissionFormInputs {
company: string;
position: string;
location: string;
recency: string;
asked_month: number;
asked_year: number;
question: string;
'question-details': string;
'stay-anonymous': boolean;
question_details: string;
stay_anonymous: boolean;
}

const months = [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December',
] as const;

export function QuestionSubmissionForm() {
// reference: https://react-hook-form.com/get-started#Quickstart
const { register, handleSubmit, reset } = useForm<QuestionSubmissionFormInputs>();
const { register, handleSubmit, reset, formState } = useForm<QuestionSubmissionFormInputs>();

const onSubmit: SubmitHandler<QuestionSubmissionFormInputs> = data => {
console.log(data);
console.log({ computed_asked_date: new Date(data.asked_year, data.asked_month, 1), ...data });
reset();
};

return (
<div className='w-full bg-white p-4 shadow-lg sm:w-4/5 md:w-2/3 lg:w-1/2'>
<div className='w-full rounded-md bg-white p-4 shadow-md sm:w-4/5 md:w-2/3 lg:w-1/2'>
<form className='space-y-8 divide-y divide-gray-200' onSubmit={handleSubmit(onSubmit)}>
<div className='space-y-8 divide-y divide-gray-200'>
<div>
Expand All @@ -29,79 +45,119 @@ export function QuestionSubmissionForm() {
</div>

<div className='mt-6 grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-6'>
<div className='sm:col-span-4'>
<div className='sm:col-span-6'>
<label htmlFor='company' className='block text-sm font-medium text-gray-700'>
Company
</label>
<div className='mt-1 flex rounded-md shadow-sm'>
<div className='mt-1 flex flex-col gap-y-1'>
<input
type='text'
id='company'
className='block w-full min-w-0 flex-1 rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
{...register('company', { required: true })}
/>
{formState.errors.company && <span className='text-xs text-red-500'>Company is required</span>}
</div>
</div>

<div className='sm:col-span-4'>
<div className='sm:col-span-6'>
<label htmlFor='position' className='block text-sm font-medium text-gray-700'>
Position
</label>
<div className='mt-1 flex rounded-md shadow-sm'>
<div className='mt-1 flex flex-col gap-y-1'>
<input
type='text'
{...register('position', { required: true })}
id='position'
className='block w-full min-w-0 flex-1 rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
/>
{formState.errors.position && <span className='text-xs text-red-500'>Position is required</span>}
</div>
</div>

<div className='sm:col-span-4'>
<div className='sm:col-span-6'>
<label htmlFor='location' className='block text-sm font-medium text-gray-700'>
Location
</label>
<div className='mt-1 flex rounded-md shadow-sm'>
<div className='mt-1 flex flex-col gap-y-1'>
<input
type='text'
{...register('location', { required: true })}
id='location'
className='block w-full min-w-0 flex-1 rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
/>
{formState.errors.location && <span className='text-xs text-red-500'>Location is required</span>}
</div>
</div>

<div className='sm:col-span-3'>
<label htmlFor='recency' className='block text-sm font-medium text-gray-700'>
How recently was this asked?
</label>
<div className='mt-1'>
<select
id='recency'
{...register('recency', { required: true })}
className='block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
>
<option>Within the past week</option>
<option>Within the past month</option>
<option>1-2 months ago</option>
<option>3-6 months ago</option>
<option>7-12 months ago</option>
<option>1+ year ago</option>
</select>
<fieldset className='sm:col-span-6'>
<legend>When was this asked?</legend>
<div className='mt-2 flex flex-row gap-x-1'>
<div className='w-2/3 flex-auto'>
<label htmlFor='asked-month' className='block text-xs font-medium text-gray-500'>
Month
</label>
<div className='mt-1 flex flex-col gap-y-1'>
<select
{...register('asked_month', { required: true, valueAsNumber: true })}
id='asked-month'
defaultValue={new Date().getMonth()}
className='block w-full min-w-0 flex-1 rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
>
{months.map((month, index) => (
<option key={month} value={index}>
{month}
</option>
))}
</select>
{formState.errors.asked_month && <span className='text-xs text-red-500'>Month is required</span>}
</div>
</div>
<div className='w-1/3 flex-auto'>
<label htmlFor='asked-year' className='block text-xs font-medium text-gray-500'>
Year
</label>
<div className='mt-1 flex flex-col gap-y-1'>
<input
type='tel'
defaultValue={new Date().getFullYear()}
{...register('asked_year', {
required: true,
validate: value => {
const valueAsString = value.toString();
if (!valueAsString) return false;
const matches = valueAsString.match(/^\d{4}$/);
if (!matches) return false;
return matches.length > 0;
},
valueAsNumber: true,
})}
id='asked-year'
className='block w-full min-w-0 flex-1 rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
/>
{formState.errors.asked_year && formState.errors.asked_year.type === 'required' && (
<span className='text-xs text-red-500'>Year is required</span>
)}
{formState.errors.asked_year && formState.errors.asked_year.type === 'validate' && (
<span className='text-xs text-red-500'>Not a valid year</span>
)}
</div>
</div>
</div>
</div>
</fieldset>

<div className='sm:col-span-6'>
<label htmlFor='question' className='block text-sm font-medium text-gray-700'>
Question
</label>
<div className='mt-1 flex rounded-md shadow-sm'>
<div className='mt-1 flex flex-col gap-y-1'>
<input
type='text'
{...register('question', { required: true })}
id='question'
className='block w-full min-w-0 flex-1 rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
/>
{formState.errors.question && <span className='text-xs text-red-500'>Question is required</span>}
</div>
</div>

Expand All @@ -112,7 +168,7 @@ export function QuestionSubmissionForm() {
<div className='mt-1'>
<textarea
id='question-details'
{...register('question-details')}
{...register('question_details')}
rows={3}
className='block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'
defaultValue={''}
Expand All @@ -124,7 +180,7 @@ export function QuestionSubmissionForm() {
<div className='flex h-5 items-center'>
<input
id='stay-anonymous'
{...register('stay-anonymous')}
{...register('stay_anonymous')}
type='checkbox'
className='h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500'
/>
Expand Down
17 changes: 17 additions & 0 deletions supabase.sql
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,20 @@ $$;
create trigger on_auth_user_created
after insert on auth.users
for each row execute procedure public.handle_new_user();

-- Create a table for questions
create table questions (
id uuid default uuid_generate_v4() primary key,
created_at timestamp with time zone default timezone('utc'::text, now()) not null,
created_by uuid references auth.users(id) not null,
company text,
location text,
asked_month smallint,
iShibi marked this conversation as resolved.
Show resolved Hide resolved
asked_year smallint,
computed_asked_date date,
question text,
question_details text,
stay_anonymous boolean,
position text,
is_approved boolean default false
);