Last active
January 9, 2026 16:10
-
-
Save azeezat/a2262bcaee1556107d44c6e0950188cb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 'use client'; | |
| import React from 'react'; | |
| import { Form } from 'radix-ui'; | |
| import { Flex } from '@radix-ui/themes'; | |
| import { | |
| RequestCategory, | |
| RequestInput, | |
| } from '@/backend/graphql/generated/types.generated'; | |
| import { SearchableDropdown } from '@/frontend/components/dropdown/searchable-dropdown'; | |
| import { FileUpload } from './upload-file'; | |
| interface RequestFormProps { | |
| createRequestData: RequestInput; | |
| setCreateRequestData: (createRequestData: RequestInput) => void; | |
| requestCategories: RequestCategory[]; | |
| loadingCategories: boolean; | |
| files: File[]; | |
| setFiles: (value: File[]) => void; | |
| hideUpload?: boolean; | |
| errors: Record<string, string>; | |
| } | |
| export const RequestForm = ({ | |
| createRequestData, | |
| setCreateRequestData, | |
| requestCategories, | |
| loadingCategories, | |
| files, | |
| setFiles, | |
| hideUpload, | |
| errors, | |
| }: RequestFormProps) => { | |
| return ( | |
| <Form.Root> | |
| <Form.Field className="Field" name="title"> | |
| <Flex justify="between" align="baseline"> | |
| <Form.Label className="Label">Title</Form.Label> | |
| <Form.Message className="Message" match="valueMissing"> | |
| Please enter your title | |
| </Form.Message> | |
| <Form.Message className="Message" match="typeMismatch"> | |
| Please provide a valid title | |
| </Form.Message> | |
| </Flex> | |
| <Form.Control asChild> | |
| <input | |
| className="Input" | |
| value={createRequestData.title} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| title: e.target.value, | |
| }) | |
| } | |
| //required | |
| /> | |
| </Form.Control> | |
| {errors?.['title'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['title']} | |
| </Form.Message> | |
| )} | |
| </Form.Field> | |
| <Form.Field className="Field" name="description"> | |
| <Flex justify="between" align="baseline"> | |
| <Form.Label className="Label">Description</Form.Label> | |
| <Form.Message className="Message" match="valueMissing"> | |
| Please enter request description | |
| </Form.Message> | |
| <Form.Message className="Message" match="typeMismatch"> | |
| Please provide a valid description | |
| </Form.Message> | |
| </Flex> | |
| <Form.Control asChild> | |
| <textarea | |
| className="Textarea" | |
| value={createRequestData.description} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| description: e.target.value || '', | |
| }) | |
| } | |
| //required | |
| /> | |
| </Form.Control> | |
| {errors?.['description'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['description']} | |
| </Form.Message> | |
| )} | |
| </Form.Field> | |
| <Form.Field className="Field" name="budget"> | |
| <Flex justify="between" align="baseline"> | |
| <Form.Label className="Label">Budget Per Companion</Form.Label> | |
| <Form.Message className="Message" match="valueMissing"> | |
| Please enter a budget | |
| </Form.Message> | |
| <Form.Message className="Message" match="typeMismatch"> | |
| Please provide a valid budget | |
| </Form.Message> | |
| </Flex> | |
| <Form.Control asChild> | |
| <input | |
| className="Input" | |
| type="number" | |
| min={1} | |
| value={createRequestData.budget} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| budget: e.target.value || '', | |
| }) | |
| } | |
| //required | |
| /> | |
| </Form.Control> | |
| {errors?.['budget'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['budget']} | |
| </Form.Message> | |
| )} | |
| </Form.Field> | |
| <Form.Field className="Field" name="date"> | |
| <Flex justify="between" align="baseline"> | |
| <Form.Label className="Label">Date</Form.Label> | |
| <Form.Message className="Message" match="valueMissing"> | |
| Please enter start date | |
| </Form.Message> | |
| <Form.Message className="Message" match="typeMismatch"> | |
| Please provide a valid start date | |
| </Form.Message> | |
| </Flex> | |
| <Form.Control asChild> | |
| <Flex direction="row" gap="2" align="center"> | |
| <div> | |
| <input | |
| className="Input" | |
| type="datetime-local" | |
| value={createRequestData.startDateTime as string} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| startDateTime: e.target.value || '', | |
| }) | |
| } | |
| //required | |
| /> | |
| {errors?.['startDateTime'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['startDateTime']} | |
| </Form.Message> | |
| )} | |
| </div> | |
| <div> | |
| <input | |
| className="Input" | |
| type="datetime-local" | |
| value={createRequestData.endDateTime as string} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| endDateTime: e.target.value || '', | |
| }) | |
| } | |
| //required | |
| /> | |
| {errors?.['endDateTime'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['endDateTime']} | |
| </Form.Message> | |
| )} | |
| </div> | |
| </Flex> | |
| </Form.Control> | |
| </Form.Field> | |
| <Form.Field className="Field" name="location"> | |
| <Flex justify="between" align="baseline"> | |
| <Form.Label className="Label">Location</Form.Label> | |
| <Form.Message className="Message" match="valueMissing"> | |
| Please enter location | |
| </Form.Message> | |
| <Form.Message className="Message" match="typeMismatch"> | |
| Please provide a valid location | |
| </Form.Message> | |
| </Flex> | |
| <Form.Control asChild> | |
| <input | |
| className="Input" | |
| type="text" | |
| value={createRequestData.location} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| location: e.target.value || '', | |
| }) | |
| } | |
| //required | |
| /> | |
| </Form.Control> | |
| {errors?.['location'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['location']} | |
| </Form.Message> | |
| )} | |
| </Form.Field> | |
| <Form.Field className="Field" name="title"> | |
| <Flex justify="between" align="baseline"> | |
| <Form.Label className="Label">Number of companions</Form.Label> | |
| <Form.Message className="Message" match="valueMissing"> | |
| Please enter your number of companions | |
| </Form.Message> | |
| <Form.Message className="Message" match="typeMismatch"> | |
| Please provide a valid number | |
| </Form.Message> | |
| </Flex> | |
| <Form.Control asChild> | |
| <input | |
| className="Input" | |
| type="number" | |
| value={createRequestData.numberOfCompanions} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| numberOfCompanions: Number(e.target.value || 0), | |
| }) | |
| } | |
| //required | |
| /> | |
| </Form.Control> | |
| {errors?.['numberOfCompanions'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['numberOfCompanions']} | |
| </Form.Message> | |
| )} | |
| </Form.Field> | |
| <Form.Field name="category"> | |
| <Form.Label className="Label">Category</Form.Label> | |
| <SearchableDropdown | |
| options={ | |
| requestCategories?.map((item) => ({ | |
| label: item.name as string, | |
| value: item.id as number, | |
| })) || [] | |
| } | |
| value={{ | |
| value: createRequestData.categoryId, | |
| label: requestCategories.find(() => createRequestData.categoryId) | |
| ?.name as string, | |
| }} | |
| onChange={(category: any) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| categoryId: category.value, | |
| }) | |
| } | |
| //required | |
| isDisabled={loadingCategories} | |
| /> | |
| {errors?.['categoryId'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['categoryId']} | |
| </Form.Message> | |
| )} | |
| </Form.Field> | |
| <Form.Field className="Field" name="companionDistance"> | |
| <Flex justify="between" align="baseline"> | |
| <Form.Label className="Label">Companion distance</Form.Label> | |
| <Form.Message className="Message" match="valueMissing"> | |
| Please enter your companion distance | |
| </Form.Message> | |
| <Form.Message className="Message" match="typeMismatch"> | |
| Please provide a valid companion distance | |
| </Form.Message> | |
| </Flex> | |
| <Form.Control asChild> | |
| <input | |
| className="Input" | |
| min={1} | |
| value={createRequestData.companionDistance || 0} | |
| onChange={(e) => | |
| setCreateRequestData({ | |
| ...createRequestData, | |
| companionDistance: Number(e.target.value), | |
| }) | |
| } | |
| /> | |
| </Form.Control> | |
| {errors?.['companionDistance'] && ( | |
| <Form.Message className="text-[13px] text-red-500 opacity-80"> | |
| {errors['companionDistance']} | |
| </Form.Message> | |
| )} | |
| </Form.Field> | |
| {!hideUpload && ( | |
| <Form.Field name="files"> | |
| <FileUpload files={files} setFiles={setFiles} /> | |
| </Form.Field> | |
| )} | |
| </Form.Root> | |
| ); | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment