Commit 2061f4d3 authored by Wellton Quirino's avatar Wellton Quirino

feat: create add course page

parent 50a22852
This diff is collapsed.
...@@ -11,26 +11,31 @@ ...@@ -11,26 +11,31 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.13.0", "@emotion/react": "^11.13.0",
"@emotion/styled": "^11.13.0", "@emotion/styled": "^11.13.0",
"@hookform/resolvers": "^3.9.0",
"@mui/material": "^5.16.4", "@mui/material": "^5.16.4",
"@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-checkbox": "^1.1.1", "@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.1.0", "@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-select": "^2.1.1", "@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.1.0",
"axios": "^1.7.2", "axios": "^1.7.2",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.1.5", "embla-carousel-react": "^8.1.5",
"lucide-react": "^0.383.0", "lucide-react": "^0.383.0",
"next": "14.2.3", "next": "14.2.3",
"next-themes": "^0.3.0", "next-themes": "^0.3.0",
"react": "^18", "react": "^18",
"react-day-picker": "^8.10.1",
"react-dom": "^18", "react-dom": "^18",
"react-hook-form": "^7.52.0", "react-hook-form": "^7.52.2",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",
"tailwindcss-animate": "^1.0.7" "tailwindcss-animate": "^1.0.7",
"zod": "^3.23.8"
}, },
"devDependencies": { "devDependencies": {
"@rocketseat/eslint-config": "^2.2.2", "@rocketseat/eslint-config": "^2.2.2",
......
This diff is collapsed.
...@@ -25,8 +25,18 @@ export default function Login() { ...@@ -25,8 +25,18 @@ export default function Login() {
> >
<div className="flex flex-col space-y-6"> <div className="flex flex-col space-y-6">
<div className="flex flex-col space-y-4"> <div className="flex flex-col space-y-4">
<InputMui label="E-mail" variant="outlined" type="email" /> <InputMui
<InputMui label="Senha" variant="outlined" type="password" /> label="E-mail"
variant="outlined"
type="email"
color="white"
/>
<InputMui
label="Senha"
variant="outlined"
type="password"
color="white"
/>
</div> </div>
<div className="flex items-center space-x-2"> <div className="flex items-center space-x-2">
<Checkbox id="remember" /> <Checkbox id="remember" />
......
...@@ -16,7 +16,7 @@ export function Header() { ...@@ -16,7 +16,7 @@ export function Header() {
<header className="w-full md:px-6 py-5"> <header className="w-full md:px-6 py-5">
<div className="container mx-auto flex justify-between gap-4"> <div className="container mx-auto flex justify-between gap-4">
<Link href="/"> <Link href="/">
<LogoComponent width={115} height={32} className="fill-primary" /> <LogoComponent width={230} height={64} className="fill-primary" />
</Link> </Link>
<div className="flex items-center flex-1 lg:flex-none"> <div className="flex items-center flex-1 lg:flex-none">
<div className="hidden lg:block"> <div className="hidden lg:block">
......
...@@ -4,9 +4,10 @@ type InputMuiProps = { ...@@ -4,9 +4,10 @@ type InputMuiProps = {
label: string label: string
variant: 'standard' | 'filled' | 'outlined' variant: 'standard' | 'filled' | 'outlined'
type: string type: string
color: string
} }
export function InputMui({ label, variant, type }: InputMuiProps) { export function InputMui({ label, variant, type, color }: InputMuiProps) {
return ( return (
<TextField <TextField
label={label} label={label}
...@@ -15,24 +16,45 @@ export function InputMui({ label, variant, type }: InputMuiProps) { ...@@ -15,24 +16,45 @@ export function InputMui({ label, variant, type }: InputMuiProps) {
sx={{ sx={{
'& .MuiOutlinedInput-root': { '& .MuiOutlinedInput-root': {
'& fieldset': { '& fieldset': {
borderColor: 'white', // Inicialmente transparente borderColor: color, // Inicialmente transparente
}, },
'&:hover fieldset': { '&:hover fieldset': {
borderColor: 'white', // Mantém transparente ao passar o mouse borderColor: color, // Mantém transparente ao passar o mouse
}, },
'&.Mui-focused fieldset': { '&.Mui-focused fieldset': {
borderColor: 'white', // Mantém transparente ao focar borderColor: color, // Mantém transparente ao focar
}, },
}, },
'& label.Mui-focused': { '& label.Mui-focused': {
color: '#B7B7B7', color,
}, },
'& label': { '& label': {
color: 'white', color,
}, },
'& input': { '& input': {
color,
},
'& .MuiInputBase-input': {
color: 'white', color: 'white',
}, },
'& .MuiInput-underline:before': {
borderBottomColor: color,
},
'& .MuiInput-underline:hover:before': {
borderBottomColor: `${color} !important`,
},
'& .MuiInput-underline:after': {
borderBottomColor: color,
},
'& .MuiFilledInput-underline:before': {
borderBottomColor: color,
},
'& .MuiFilledInput-underline:hover:before': {
borderBottomColor: `${color} !important`,
},
'& .MuiFilledInput-underline:after': {
borderBottomColor: color,
},
}} }}
/> />
) )
......
import { Autocomplete, TextField } from '@mui/material'
type SelectMuiProps = {
label: string
variant?: 'standard' | 'filled' | 'outlined'
color: string
}
const options = [
{ label: 'The Godfather', id: 1 },
{ label: 'Pulp Fiction', id: 2 },
]
export function SelectMui({ label, color }: SelectMuiProps) {
return (
<Autocomplete
options={options}
sx={{
'& .MuiOutlinedInput-root': {
'& fieldset': {
borderColor: color, // Inicialmente transparente
},
'&:hover fieldset': {
borderColor: color, // Mantém transparente ao passar o mouse
},
'&.Mui-focused fieldset': {
borderColor: color, // Mantém transparente ao focar
},
},
'& label.Mui-focused': {
color,
},
'& label': {
color,
},
'& input': {
color,
},
'& .MuiInputBase-input': {
color: 'white',
},
'& .MuiInput-underline:before': {
borderBottomColor: color,
},
'& .MuiInput-underline:hover:before': {
borderBottomColor: `${color} !important`,
},
'& .MuiInput-underline:after': {
borderBottomColor: color,
},
'& .MuiFilledInput-underline:before': {
borderBottomColor: color,
},
'& .MuiFilledInput-underline:hover:before': {
borderBottomColor: `${color} !important`,
},
'& .MuiFilledInput-underline:after': {
borderBottomColor: color,
},
}}
renderInput={(params) => (
<TextField {...params} label={label} variant="standard" />
)}
/>
)
}
export function StyledInputs(color: string) {
return {
'& .MuiOutlinedInput-root': {
'& fieldset': {
borderColor: color, // Inicialmente transparente
},
'&:hover fieldset': {
borderColor: color, // Mantém transparente ao passar o mouse
},
'&.Mui-focused fieldset': {
borderColor: color, // Mantém transparente ao focar
},
},
'& label.Mui-focused': {
color,
},
'& label': {
color,
},
'& input': {
color,
},
'& .MuiInputBase-input': {
color: 'white',
},
'& .MuiInput-underline:before': {
borderBottomColor: color,
},
'& .MuiInput-underline:hover:before': {
borderBottomColor: `${color} !important`,
},
'& .MuiInput-underline:after': {
borderBottomColor: color,
},
'& .MuiFilledInput-underline:before': {
borderBottomColor: color,
},
'& .MuiFilledInput-underline:hover:before': {
borderBottomColor: `${color} !important`,
},
'& .MuiFilledInput-underline:after': {
borderBottomColor: color,
},
}
}
"use client"
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
export type CalendarProps = React.ComponentProps<typeof DayPicker>
function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: CalendarProps) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
classNames={{
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
month: "space-y-4",
caption: "flex justify-center pt-1 relative items-center",
caption_label: "text-sm font-medium",
nav: "space-x-1 flex items-center",
nav_button: cn(
buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
),
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-y-1",
head_row: "flex",
head_cell:
"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
day: cn(
buttonVariants({ variant: "ghost" }),
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
),
day_range_end: "day-range-end",
day_selected:
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
day_today: "bg-accent text-accent-foreground",
day_outside:
"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
day_disabled: "text-muted-foreground opacity-50",
day_range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
...classNames,
}}
components={{
IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
}}
{...props}
/>
)
}
Calendar.displayName = "Calendar"
export { Calendar }
"use client"
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"
import { cn } from "@/lib/utils"
import { Label } from "@/components/ui/label"
const Form = FormProvider
type FormFieldContextValue<
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = {
name: TName
}
const FormFieldContext = React.createContext<FormFieldContextValue>(
{} as FormFieldContextValue
)
const FormField = <
TFieldValues extends FieldValues = FieldValues,
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
>({
...props
}: ControllerProps<TFieldValues, TName>) => {
return (
<FormFieldContext.Provider value={{ name: props.name }}>
<Controller {...props} />
</FormFieldContext.Provider>
)
}
const useFormField = () => {
const fieldContext = React.useContext(FormFieldContext)
const itemContext = React.useContext(FormItemContext)
const { getFieldState, formState } = useFormContext()
const fieldState = getFieldState(fieldContext.name, formState)
if (!fieldContext) {
throw new Error("useFormField should be used within <FormField>")
}
const { id } = itemContext
return {
id,
name: fieldContext.name,
formItemId: `${id}-form-item`,
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
...fieldState,
}
}
type FormItemContextValue = {
id: string
}
const FormItemContext = React.createContext<FormItemContextValue>(
{} as FormItemContextValue
)
const FormItem = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => {
const id = React.useId()
return (
<FormItemContext.Provider value={{ id }}>
<div ref={ref} className={cn("space-y-2", className)} {...props} />
</FormItemContext.Provider>
)
})
FormItem.displayName = "FormItem"
const FormLabel = React.forwardRef<
React.ElementRef<typeof LabelPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>
>(({ className, ...props }, ref) => {
const { error, formItemId } = useFormField()
return (
<Label
ref={ref}
className={cn(error && "text-destructive", className)}
htmlFor={formItemId}
{...props}
/>
)
})
FormLabel.displayName = "FormLabel"
const FormControl = React.forwardRef<
React.ElementRef<typeof Slot>,
React.ComponentPropsWithoutRef<typeof Slot>
>(({ ...props }, ref) => {
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
return (
<Slot
ref={ref}
id={formItemId}
aria-describedby={
!error
? `${formDescriptionId}`
: `${formDescriptionId} ${formMessageId}`
}
aria-invalid={!!error}
{...props}
/>
)
})
FormControl.displayName = "FormControl"
const FormDescription = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, ...props }, ref) => {
const { formDescriptionId } = useFormField()
return (
<p
ref={ref}
id={formDescriptionId}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
)
})
FormDescription.displayName = "FormDescription"
const FormMessage = React.forwardRef<
HTMLParagraphElement,
React.HTMLAttributes<HTMLParagraphElement>
>(({ className, children, ...props }, ref) => {
const { error, formMessageId } = useFormField()
const body = error ? String(error?.message) : children
if (!body) {
return null
}
return (
<p
ref={ref}
id={formMessageId}
className={cn("text-sm font-medium text-destructive", className)}
{...props}
>
{body}
</p>
)
})
FormMessage.displayName = "FormMessage"
export {
useFormField,
Form,
FormItem,
FormLabel,
FormControl,
FormDescription,
FormMessage,
FormField,
}
"use client"
import * as React from "react"
import * as PopoverPrimitive from "@radix-ui/react-popover"
import { cn } from "@/lib/utils"
const Popover = PopoverPrimitive.Root
const PopoverTrigger = PopoverPrimitive.Trigger
const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
</PopoverPrimitive.Portal>
))
PopoverContent.displayName = PopoverPrimitive.Content.displayName
export { Popover, PopoverTrigger, PopoverContent }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment