Skip to content

Commit

Permalink
[feat] Create custom form components + change naming of components fr…
Browse files Browse the repository at this point in the history
…om shadcn-ui
  • Loading branch information
romashka-dev committed Jan 1, 2025
1 parent 07cf870 commit 7d65c16
Show file tree
Hide file tree
Showing 37 changed files with 484 additions and 88 deletions.
2 changes: 1 addition & 1 deletion app/(dashboard)/add-job/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import CreateJobForm from '@/components/ui/CreateJobForm'
import { CreateJobForm } from '../../../components/ui/CreateJobForm'

const AddJobPage = () => {
return (
Expand Down
2 changes: 1 addition & 1 deletion app/(dashboard)/jobs/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Spinner from '@/components/ui/Spinner'
import { Spinner } from '../../../components/ui/Spinner'

const JobPage = () => {
return (
Expand Down
6 changes: 3 additions & 3 deletions app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Navbar from '../../components/ui/Navbar'
import Sidebar from '../../components/ui/Sidebar'
import { Navbar } from '../../components/ui/Navbar'
import { Sidebar } from '../../components/ui/Sidebar'

import { PropsWithChildren } from 'react'

Expand All @@ -10,12 +10,12 @@ const layout = ({ children }: PropsWithChildren) => {
<div className="hidden lg:block lg:col-span-1 lg:min-h-screen">
<Sidebar />
</div>

{/* second-col hide dropdown on big screen */}
<div className="lg:col-span-4">
<Navbar />
<div className="py-16 px-14 sm:px-8 lg:px-16">{children}</div>
</div>
{children}
</main>
)
}
Expand Down
2 changes: 1 addition & 1 deletion app/(dashboard)/stats/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Spinner from '@/components/ui/Spinner'
import { Spinner } from '../../../components/ui/Spinner'

const StatsPage = () => {
return (
Expand Down
2 changes: 1 addition & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Metadata } from 'next'
import { Geist, Geist_Mono } from 'next/font/google'
import './globals.css'
import { ClerkProvider } from '@clerk/nextjs'
import Providers from './providers'
import { Providers } from './providers'

const geistSans = Geist({
variable: '--font-geist-sans',
Expand Down
2 changes: 1 addition & 1 deletion app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Image from 'next/image'
import LandingImg from '../assets/main-illustration.png'
import Logo from '../assets/logo.svg'
import { Button } from '@/components/ui/button'
import { Button } from '@/components/ui/Button/Button'
import Link from 'next/link'

export default function Home() {
Expand Down
4 changes: 2 additions & 2 deletions app/providers.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import ThemeProvider from '@/components/ui/ThemeProvider'
import { ThemeProvider } from '@/components/ui/ThemeProvider'

const Providers = ({ children }: { children: React.ReactNode }) => {
return (
Expand All @@ -17,4 +17,4 @@ const Providers = ({ children }: { children: React.ReactNode }) => {
)
}

export default Providers
export { Providers }
File renamed without changes.
1 change: 1 addition & 0 deletions components/ui/Button/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Button, buttonVariants } from './Button'
88 changes: 48 additions & 40 deletions components/ui/CreateJobForm/CreateJobForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,69 @@

import { zodResolver } from '@hookform/resolvers/zod'
import { useForm } from 'react-hook-form'
import * as z from 'zod'

import { Button } from '@/components/ui/button'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'

const formSchema = z.object({
username: z.string().min(2, {
message: 'Username must be at least 2 characters.',
}),
})
JobStatus,
JobMode,
createAndEditJobSchema,
CreateAndEditJobType,
} from '@/utils/types'

import { Button } from '../Button'
import { Form } from '../Form'

import { CustomFormField, CustomFormSelect } from '../FormComponents'

const CreateJobForm = () => {
// 1. Define your form.
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
const form = useForm<CreateAndEditJobType>({
resolver: zodResolver(createAndEditJobSchema),
defaultValues: {
username: '',
position: '',
company: '',
location: '',
status: JobStatus.Pending,
mode: JobMode.FullTime,
},
})

// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof formSchema>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values)
const onSubmit = (value: CreateAndEditJobType) => {
console.log(value)
}

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="username"
render={({ field }) => (
<FormItem>
<FormLabel>Username</FormLabel>
<FormControl>
<Input placeholder="shadcn" {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
<form onSubmit={form.handleSubmit(onSubmit)} className="bg-muted p-8">
<h2 className="capitalize font-semibold text-4xl mb-6">add job</h2>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3 items-start">
{/* position */}
<CustomFormField name="position" control={form.control} />
{/* company */}
<CustomFormField name="company" control={form.control} />
{/* location */}
<CustomFormField name="location" control={form.control} />

{/* job status */}
<CustomFormSelect
name="status"
control={form.control}
labelText="job status"
items={Object.values(JobStatus)}
/>
{/* job mode */}
<CustomFormSelect
name="mode"
control={form.control}
labelText="job mode"
items={Object.values(JobMode)}
/>
<Button type="submit" className="self-end capitalize">
create job
</Button>
</div>
</form>
</Form>
)
}

export default CreateJobForm
export { CreateJobForm }
2 changes: 1 addition & 1 deletion components/ui/CreateJobForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default } from './CreateJobForm'
export { CreateJobForm } from './CreateJobForm'
File renamed without changes.
17 changes: 17 additions & 0 deletions components/ui/DropDownMenu.tsx/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuGroup,
DropdownMenuPortal,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuRadioGroup,
} from './DropDownMenu'
34 changes: 17 additions & 17 deletions components/ui/form.tsx → components/ui/Form/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
"use client"
'use client'

import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { Slot } from "@radix-ui/react-slot"
import * as React from 'react'
import * as LabelPrimitive from '@radix-ui/react-label'
import { Slot } from '@radix-ui/react-slot'
import {
Controller,
ControllerProps,
FieldPath,
FieldValues,
FormProvider,
useFormContext,
} from "react-hook-form"
} from 'react-hook-form'

import { cn } from "@/lib/utils"
import { Label } from "@/components/ui/label"
import { cn } from '@/lib/utils'
import { Label } from '../Label'

const Form = FormProvider

Expand Down Expand Up @@ -49,7 +49,7 @@ const useFormField = () => {
const fieldState = getFieldState(fieldContext.name, formState)

if (!fieldContext) {
throw new Error("useFormField should be used within <FormField>")
throw new Error('useFormField should be used within <FormField>')
}

const { id } = itemContext
Expand Down Expand Up @@ -80,11 +80,11 @@ const FormItem = React.forwardRef<

return (
<FormItemContext.Provider value={{ id }}>
<div ref={ref} className={cn("space-y-2", className)} {...props} />
<div ref={ref} className={cn('space-y-2', className)} {...props} />
</FormItemContext.Provider>
)
})
FormItem.displayName = "FormItem"
FormItem.displayName = 'FormItem'

const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
Expand All @@ -95,13 +95,13 @@ const FormLabel = React.forwardRef<
return (
<Label
ref={ref}
className={cn(error && "text-destructive", className)}
className={cn(error && 'text-destructive', className)}
htmlFor={formItemId}
{...props}
/>
)
})
FormLabel.displayName = "FormLabel"
FormLabel.displayName = 'FormLabel'

const FormControl = React.forwardRef<
React.ElementRef<typeof Slot>,
Expand All @@ -123,7 +123,7 @@ const FormControl = React.forwardRef<
/>
)
})
FormControl.displayName = "FormControl"
FormControl.displayName = 'FormControl'

const FormDescription = React.forwardRef<
HTMLParagraphElement,
Expand All @@ -135,12 +135,12 @@ const FormDescription = React.forwardRef<
<p
ref={ref}
id={formDescriptionId}
className={cn("text-sm text-muted-foreground", className)}
className={cn('text-sm text-muted-foreground', className)}
{...props}
/>
)
})
FormDescription.displayName = "FormDescription"
FormDescription.displayName = 'FormDescription'

const FormMessage = React.forwardRef<
HTMLParagraphElement,
Expand All @@ -157,14 +157,14 @@ const FormMessage = React.forwardRef<
<p
ref={ref}
id={formMessageId}
className={cn("text-sm font-medium text-destructive", className)}
className={cn('text-sm font-medium text-destructive', className)}
{...props}
>
{body}
</p>
)
})
FormMessage.displayName = "FormMessage"
FormMessage.displayName = 'FormMessage'

export {
useFormField,
Expand Down
10 changes: 10 additions & 0 deletions components/ui/Form/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export {
useFormField,
Form,
FormItem,
FormLabel,
FormControl,
FormDescription,
FormMessage,
FormField,
} from './Form'
Loading

0 comments on commit 7d65c16

Please sign in to comment.