Commit 1e2e278b authored by Wellton Quirino's avatar Wellton Quirino

feat: improving pages admin routes

parent 4f7e1d0b
......@@ -18,6 +18,7 @@
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-radio-group": "^1.2.1",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
......@@ -1804,6 +1805,81 @@
}
}
},
"node_modules/@radix-ui/react-radio-group": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.1.tgz",
"integrity": "sha512-kdbv54g4vfRjja9DNWPMxKvXblzqbpEC8kspEkZ6dVP7kQksGCn+iZHkcCz2nb00+lPdRvxrqy4WrvvV1cNqrQ==",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-context": "1.1.1",
"@radix-ui/react-direction": "1.1.0",
"@radix-ui/react-presence": "1.1.1",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-roving-focus": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0",
"@radix-ui/react-use-previous": "1.1.0",
"@radix-ui/react-use-size": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-roving-focus": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
"integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
"dependencies": {
"@radix-ui/primitive": "1.1.0",
"@radix-ui/react-collection": "1.1.0",
"@radix-ui/react-compose-refs": "1.1.0",
"@radix-ui/react-context": "1.1.0",
"@radix-ui/react-direction": "1.1.0",
"@radix-ui/react-id": "1.1.0",
"@radix-ui/react-primitive": "2.0.0",
"@radix-ui/react-use-callback-ref": "1.1.0",
"@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
"integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-select": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.1.tgz",
......
import { api } from '@/lib/axios'
export type CategoriesProps = {
id: string
name: string
}
export async function getCategories() {
const categories = await api.get<CategoriesProps[]>('/categories')
return categories
}
......@@ -29,7 +29,8 @@ export default function Home() {
label="O que você quer aprender hoje?"
variant="standard"
type="text"
className="w-full #fafafa"
className="w-full"
themeColor="#fafafa"
/>
<Search size={24} />
</div>
......
......@@ -3,6 +3,7 @@
import { AreasProps, deleteArea, editArea, getAreasId } from '@/api/areas'
import BreadcrumbComponent from '@/components/breadcrumb-component'
import InputFile from '@/components/input-file'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import ModalDialog from '@/components/modal-dialog'
import { AlertDialog, AlertDialogTrigger } from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
......@@ -24,8 +25,8 @@ export default function AreaId() {
const queryClient = useQueryClient()
const { data: area, isLoading, isPending } = useQuery({
queryKey: ['area'],
const { data: area, isLoading } = useQuery({
queryKey: ['area', params.id],
queryFn: () => getAreasId(params.id),
enabled: !!params.id,
})
......@@ -60,14 +61,13 @@ export default function AreaId() {
mutationDelete.mutate(params.id)
}
if(isLoading) {
console.log('isloading')
return <span>isLoading TEST...</span>
}
if(isPending) {
console.log('isPeding')
return <span>isPending TEST...</span>
if (isLoading) {
return (
<div className="flex w-full h-[500px] items-center justify-center">
<LoadingSpinIcon />
<span>Loading...</span>
</div>
)
}
return (
......@@ -76,7 +76,13 @@ export default function AreaId() {
<form onSubmit={handleSubmit(onSubmit)}>
<div className="flex items-center gap-6">
<h1 className="text-3xl font-bold">Editar Área</h1>
<Button variant="secondary" type='submit' className="uppercase rounded-sm">
<Button
variant="secondary"
type="submit"
className="uppercase rounded-sm"
disabled={isLoading}
>
{mutationEdit.isPending && <LoadingSpinIcon />}
Salvar e publicar
</Button>
<AlertDialog>
......
......@@ -2,6 +2,7 @@
import { AreasProps, createAreas } from '@/api/areas'
import InputFile from '@/components/input-file'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import { StyledInputs } from '@/components/mui/styled-inputs'
import { Button } from '@/components/ui/button'
import { TextField } from '@mui/material'
......@@ -39,6 +40,7 @@ export default function Area() {
<div className="flex items-center gap-6">
<h1 className="text-3xl font-bold">Criar Área</h1>
<Button variant="secondary" className="uppercase rounded-sm">
{mutation.isPending && <LoadingSpinIcon />}
Salvar e publicar
</Button>
</div>
......
......@@ -29,7 +29,7 @@ export default function EditCourse() {
<section className="container py-10">
<form>
<div className="flex items-center gap-6">
<h1 className="text-green-700 text-3xl font-bold">Editar curso</h1>
<h1 className="text-3xl font-bold">Editar curso</h1>
{/* <Button variant="third" className="uppercase">
Salvar como rascunho
</Button> */}
......@@ -50,9 +50,20 @@ export default function EditCourse() {
Informações sobre o curso
</h6>
<InputMui label="Nome do curso" variant="standard" type="text" />
<InputMui
label="Nome do curso"
variant="standard"
type="text"
themeColor="#26AAA7"
/>
<InputMui type="text" variant="standard" label="Área" select>
<InputMui
type="text"
variant="standard"
label="Área"
select
themeColor="#26AAA7"
>
{options.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
......@@ -66,12 +77,14 @@ export default function EditCourse() {
type="text"
multiline
rows={4}
themeColor="#26AAA7"
/>
<InputMui
label="Nome dos(as) Professores(as):"
variant="standard"
type="text"
themeColor="#26AAA7"
/>
<div className="flex justify-between flex-wrap gap-6">
......@@ -119,7 +132,7 @@ export default function EditCourse() {
<Button
variant={'ghost'}
className={cn(
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0',
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0 border-green-400',
!date && 'text-muted-foreground',
)}
>
......@@ -159,7 +172,7 @@ export default function EditCourse() {
<Button
variant={'ghost'}
className={cn(
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0',
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0 border-green-400',
!date && 'text-muted-foreground',
)}
>
......@@ -189,7 +202,12 @@ export default function EditCourse() {
<h6 className="text-xl text-purple-100 mb-4">Módulos</h6>
<div className="flex flex-col p-4 gap-6 border border-gray-100">
<InputMui label="Título" variant="standard" type="text" />
<InputMui
label="Título"
variant="standard"
type="text"
themeColor="#26AAA7"
/>
<InputMui
label="Descrição"
......@@ -197,6 +215,7 @@ export default function EditCourse() {
type="text"
multiline
rows={4}
themeColor="#26AAA7"
/>
</div>
......@@ -207,6 +226,7 @@ export default function EditCourse() {
<PlusIcon size={20} /> <span>Adicionar Módulo</span>
</Button>
</div>
<div className="w-[380px] pl-6 flex flex-col gap-4">
<h6 className="text-xl text-purple-100 mb-4">
Qual o público alvo?
......
'use client'
import { InputMui } from '@/components/mui/inputs'
import { getAreas } from '@/api/areas'
import { getAudiences } from '@/api/audiences'
import { getCategories } from '@/api/categories'
import InputFile from '@/components/input-file'
import { LoadingSpinIcon } from '@/components/loading-spin-icon'
import { StyledInputs } from '@/components/mui/styled-inputs'
import { Button } from '@/components/ui/button'
import { Calendar } from '@/components/ui/calendar'
import { Checkbox } from '@/components/ui/checkbox'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
} from '@/components/ui/form'
import { Label } from '@/components/ui/label'
import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover'
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'
import { Separator } from '@/components/ui/separator'
import { cn } from '@/lib/utils'
import { MenuItem } from '@mui/material'
import { Box, Chip, MenuItem, TextField } from '@mui/material'
import { useQuery } from '@tanstack/react-query'
import { format } from 'date-fns'
import { CalendarIcon, PlusIcon, Trash } from 'lucide-react'
import { CalendarIcon, PlusIcon } from 'lucide-react'
import { useState } from 'react'
import { Controller, useForm } from 'react-hook-form'
import { z } from 'zod'
// type CoursesProps = {
// name: string
// description: string
// desktopBanner: string
// mobileBanner: string
// duration: number
// startDate: Date
// endDate: Date
// professors: string[]
// workload: number
// areaId: string
// audienceId: string
// categoryId: string
// moduleIds: string[]
// }
const options = [
{ label: 'The Godfather', value: 1 },
{ label: 'Pulp Fiction', value: 2 },
]
const FormSchema = z.object({
name: z.string(),
description: z.string(),
desktopBanner: z.string(),
mobileBanner: z.string(),
duration: z.number(),
startDate: z.date().optional(),
endDate: z.date().optional(),
professors: z.array(z.string()),
workload: z.number(),
areaId: z.string(),
audienceId: z.string(),
categoryId: z.string(),
moduleIds: z.array(z.string()),
})
export default function Curso() {
const [date, setDate] = useState<Date>()
const [checkedStart, setCheckedStart] = useState<boolean>(false)
const [checkedEnd, setCheckedEnd] = useState<boolean>(false)
const [dateStart, setDateStart] = useState<Date>()
const [dateEnd, setDateEnd] = useState<Date>()
const [inputValue, setInputValue] = useState<string>('')
// const { form.register, watch, handleSubmit, control } = useForm<CoursesProps>()
const form = useForm<z.infer<typeof FormSchema>>({
// resolver: zodResolver(FormSchema),
defaultValues: {
areaId: '',
professors: [],
},
})
const values = form.watch()
const valueDesktopBanner = values?.desktopBanner?.['0']
const valueMobileBanner = values?.mobileBanner?.['0']
const { data: areas } = useQuery({
queryKey: ['areas'],
queryFn: getAreas,
})
const { data: audiences, isLoading: audiencesLoading } = useQuery({
queryKey: ['audiences'],
queryFn: getAudiences,
})
const { data: categories, isLoading: categoriesLoading } = useQuery({
queryKey: ['categories'],
queryFn: getCategories,
})
function onSubmit(data: z.infer<typeof FormSchema>) {
const body = {
...data,
startDate: dateStart?.toLocaleDateString() || '',
endDate: dateEnd?.toLocaleDateString() || '',
}
console.log(body)
}
function onCheckedStart(checkedStart: boolean) {
setCheckedStart(checkedStart)
}
function onCheckedEnd(checkedEnd: boolean) {
setCheckedEnd(checkedEnd)
}
const handleKeyDown = (event: React.KeyboardEvent) => {
if (event.key === 'Enter' && inputValue.trim()) {
event.preventDefault()
form.setValue('professors', [...values.professors, inputValue.trim()])
setInputValue('')
}
}
const handleDelete = (professorToDelete: string) => {
form.setValue(
'professors',
values.professors.filter((str) => str !== professorToDelete),
)
}
return (
<section className="container py-10">
<form>
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div className="flex items-center gap-6">
<h1 className="text-green-700 text-3xl font-bold">Criar curso</h1>
{/* <Button variant="third" className="uppercase">
Salvar como rascunho
</Button> */}
<Button variant="secondary" className="uppercase">
<h1 className="text-3xl font-bold">Criar curso</h1>
<Button type="submit" variant="secondary" className="uppercase">
Salvar e publicar
</Button>
<Button
variant="ghost"
className="uppercase flex items-center gap-2 text-orange-100 hover:text-orange-100"
>
<span>Apagar curso</span>
<Trash />
</Button>
</div>
<div className="flex w-full mt-10">
<div className="flex-1 flex flex-col border-r border-gray-50 pr-6 space-y-4">
......@@ -50,52 +148,109 @@ export default function Curso() {
Informações sobre o curso
</h6>
<InputMui label="Nome do curso" variant="standard" type="text" />
<TextField
label="Nome do curso"
variant="standard"
type="text"
{...form.register('name')}
sx={StyledInputs({ color: '#26AAA7' })}
/>
<InputMui type="text" variant="standard" label="Área" select>
{options.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
<TextField
type="text"
variant="standard"
label="Área"
select
sx={StyledInputs({ color: '#26AAA7' })}
defaultValue={''}
{...form.register('areaId')}
>
<MenuItem value="" className="hidden">
Selecione a área
</MenuItem>
{areas?.data.map((option) => (
<MenuItem key={option.id} value={option.id}>
{option.name}
</MenuItem>
))}
</InputMui>
</TextField>
<InputMui
<TextField
label="Descrição do Curso"
variant="standard"
type="text"
multiline
rows={4}
sx={StyledInputs({ color: '#26AAA7' })}
{...form.register('description')}
/>
<InputMui
{/* <TextField
label="Nome dos(as) Professores(as):"
variant="standard"
type="text"
sx={StyledInputs({ color: '#26AAA7' })}
{...form.register('professors')}
/> */}
<Controller
control={form.control}
name="professors"
render={({ field }) => (
<Box
sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}
>
<TextField
label="Digite os nomes dos professores e pressione Enter"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
onKeyDown={handleKeyDown}
variant="standard"
sx={StyledInputs({ color: '#26AAA7' })}
/>
<Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
{field.value.map((str, index) => (
<Chip
key={index}
label={str}
onDelete={() => handleDelete(str)}
variant="outlined"
color="secondary"
sx={{ color: 'white' }}
/>
))}
</Box>
</Box>
)}
/>
<div className="flex justify-between flex-wrap gap-6">
<div className="flex justify-between flex-wrap gap-6 py-6">
<div className="flex flex-col flex-1 mt-6">
<h6 className="text-xl text-purple-100">Banner Desktop</h6>
<span className="mt-4">Dimensões recomendadas: </span>
<span className="mt-4">
Dimensões recomendadas: 1512 x 300
</span>
<span>Formatos aceitos: .png, .jpg</span>
<Button
variant="third"
className="border border-dotted border-green-400 rounded-sm mt-6 mx-auto md:w-[436px]"
>
Adicionar banner
</Button>
<InputFile
id="desktopBanner"
values={valueDesktopBanner}
label="Adicionar banner"
{...form.register('desktopBanner')}
/>
</div>
<div className="flex flex-col flex-1 mt-6">
<h6 className="text-xl text-purple-100">Banner Mobile</h6>
<span className="mt-4">Dimensões recomendadas: </span>
<span className="mt-4">
Dimensões recomendadas: 390 x 300
</span>
<span>Formatos aceitos: .png, .jpg</span>
<Button
variant="third"
className="border border-dotted border-green-400 rounded-sm mt-6 mx-auto md:w-[436px]"
>
Adicionar banner
</Button>
<InputFile
id="mobileBanner"
values={valueMobileBanner}
label="Adicionar banner"
{...form.register('mobileBanner')}
/>
</div>
</div>
......@@ -104,7 +259,7 @@ export default function Curso() {
<div className="flex flex-col space-y-6">
<div className="flex justify-between items-center">
<div className="flex items-center gap-2">
<Checkbox id="start" />
<Checkbox id="start" onCheckedChange={onCheckedStart} />
<label
htmlFor="start"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
......@@ -112,6 +267,7 @@ export default function Curso() {
Definir data de início
</label>
</div>
{checkedStart && (
<div className="flex flex-col">
<Label>Data de início</Label>
<Popover>
......@@ -119,12 +275,12 @@ export default function Curso() {
<Button
variant={'ghost'}
className={cn(
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0',
!date && 'text-muted-foreground',
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0 border-green-400',
!dateStart && 'text-muted-foreground',
)}
>
{date ? (
format(date, 'dd/MM/yyyy')
{dateStart ? (
format(dateStart, 'dd/MM/yyyy')
) : (
<span className="text-gray-600">MM/DD/YYYY</span>
)}
......@@ -134,17 +290,18 @@ export default function Curso() {
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
selected={dateStart}
onSelect={setDateStart}
initialFocus
/>
</PopoverContent>
</Popover>
</div>
)}
</div>
<div className="flex justify-between items-center">
<div className="flex items-center gap-2">
<Checkbox id="closure" />
<Checkbox id="end" onCheckedChange={onCheckedEnd} />
<label
htmlFor="closure"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
......@@ -152,6 +309,7 @@ export default function Curso() {
Definir data de encerramento
</label>
</div>
{checkedEnd && (
<div className="flex flex-col">
<Label>Data de encerramento</Label>
<Popover>
......@@ -159,12 +317,12 @@ export default function Curso() {
<Button
variant={'ghost'}
className={cn(
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0',
!date && 'text-muted-foreground',
'lg:w-[450px] justify-start text-left font-normal border-b rounded-none pl-0 border-green-400',
!dateEnd && 'text-muted-foreground',
)}
>
{date ? (
format(date, 'dd/MM/yyyy')
{dateEnd ? (
format(dateEnd, 'dd/MM/yyyy')
) : (
<span className="text-gray-600">MM/DD/YYYY</span>
)}
......@@ -174,13 +332,15 @@ export default function Curso() {
<PopoverContent className="w-auto p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
selected={dateEnd}
onSelect={setDateEnd}
initialFocus
{...form.register('endDate')}
/>
</PopoverContent>
</Popover>
</div>
)}
</div>
</div>
......@@ -189,14 +349,20 @@ export default function Curso() {
<h6 className="text-xl text-purple-100 mb-4">Módulos</h6>
<div className="flex flex-col p-4 gap-6 border border-gray-100">
<InputMui label="Título" variant="standard" type="text" />
<TextField
label="Título"
variant="standard"
type="text"
sx={StyledInputs({ color: '#26AAA7' })}
/>
<InputMui
<TextField
label="Descrição"
variant="standard"
type="text"
multiline
rows={4}
sx={StyledInputs({ color: '#26AAA7' })}
/>
</div>
......@@ -211,66 +377,73 @@ export default function Curso() {
<h6 className="text-xl text-purple-100 mb-4">
Qual o público alvo?
</h6>
{audiencesLoading && <LoadingSpinIcon className="ml-10" />}
<div className="flex items-center gap-2 ml-4">
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Estudante
</label>
</div>
<div className="flex items-center gap-2 ml-4">
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
<FormField
control={form.control}
name="audienceId"
render={({ field }) => (
<FormControl>
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value}
className="flex flex-col space-y-4"
>
Profissionais
</label>
</div>
<div className="flex items-center gap-2 ml-4">
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
{audiences?.data.map((audience) => (
<FormItem
className="flex items-center space-x-3 space-y-0"
key={audience.id}
>
Empresas
</label>
<FormControl>
<RadioGroupItem value={audience.id} />
</FormControl>
<FormLabel className="font-normal">
{audience.name}
</FormLabel>
</FormItem>
))}
</RadioGroup>
</FormControl>
)}
/>
</div>
<h6 className="text-xl text-purple-100 my-4">
Qual o tipo de curso?
</h6>
{categoriesLoading && <LoadingSpinIcon className="ml-10" />}
<div className="flex items-center gap-2 ml-4">
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Curso rápido
</label>
</div>
<div className="flex items-center gap-2 ml-4">
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
<FormField
control={form.control}
name="categoryId"
render={({ field }) => (
<FormControl>
<RadioGroup
onValueChange={field.onChange}
defaultValue={field.value}
className="flex flex-col space-y-4"
>
Curso de aprofundamento
</label>
</div>
<div className="flex items-center gap-2 ml-4">
<Checkbox id="terms" />
<label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
{categories?.data.map((category) => (
<FormItem
className="flex items-center space-x-3 space-y-0"
key={category.id}
>
Curso Corporativo
</label>
<FormControl>
<RadioGroupItem value={category.id} />
</FormControl>
<FormLabel className="font-normal">
{category.name}
</FormLabel>
</FormItem>
))}
</RadioGroup>
</FormControl>
)}
/>
</div>
</div>
</div>
</form>
</Form>
</section>
)
}
......@@ -115,6 +115,7 @@ export default function Admin() {
type="text"
variant="standard"
className="w-full"
themeColor="#fafafa"
/>
<Search size={24} className="-ml-6" />
</div>
......
import { cn } from '@/lib/utils'
type SpinProps = {
className?: React.HTMLProps<HTMLElement>['className']
}
export function LoadingSpinIcon({ className }: SpinProps) {
return (
<svg
className={cn('animate-spin -ml-1 mr-3 h-5 w-5 text-white', className)}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
)
}
import {
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
......@@ -7,6 +6,7 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from './ui/alert-dialog'
import { Button } from './ui/button'
type AlertDialogProps = {
title: string
......@@ -27,7 +27,13 @@ export default function ModalDialog({
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancelar</AlertDialogCancel>
<AlertDialogAction onClick={handleClick}>Continue</AlertDialogAction>
<Button
onClick={handleClick}
variant="outline"
className="text-gray-50 bg-red-500 hover:bg-red-500/80"
>
Continue
</Button>
</AlertDialogFooter>
</AlertDialogContent>
)
......
......@@ -7,6 +7,7 @@ import { ReactNode } from 'react'
type InputMuiProps = TextFieldProps & {
label: string
variant: 'standard' | 'filled' | 'outlined'
themeColor?: string
children?: ReactNode
}
......@@ -14,11 +15,12 @@ export function InputMui({
label,
variant,
children,
themeColor = '#fafafa',
...props
}: InputMuiProps) {
const themeConfig = useThemeClient()
const color = themeConfig === 'dark' ? '#fafafa' : '#3C3C3C'
const color = themeConfig === 'dark' ? themeColor : '#3C3C3C'
return (
<TextField
......@@ -44,10 +46,10 @@ export function InputMui({
color: `${color}`,
},
'& input': {
color: `${color}`,
color: `#fafafa`,
},
'& .MuiInputBase-input': {
color: `${color}`,
color: `#fafafa`,
},
'& .MuiInput-underline:before': {
borderBottomColor: color,
......
"use client"
import * as React from "react"
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group"
import { Circle } from "lucide-react"
import { cn } from "@/lib/utils"
const RadioGroup = React.forwardRef<
React.ElementRef<typeof RadioGroupPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>
>(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Root
className={cn("grid gap-2", className)}
{...props}
ref={ref}
/>
)
})
RadioGroup.displayName = RadioGroupPrimitive.Root.displayName
const RadioGroupItem = React.forwardRef<
React.ElementRef<typeof RadioGroupPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
>(({ className, ...props }, ref) => {
return (
<RadioGroupPrimitive.Item
ref={ref}
className={cn(
"aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
>
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
<Circle className="h-2.5 w-2.5 fill-current text-current" />
</RadioGroupPrimitive.Indicator>
</RadioGroupPrimitive.Item>
)
})
RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName
export { RadioGroup, RadioGroupItem }
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