feat: create basic layout for new new event page
This commit is contained in:
parent
e372cf6e90
commit
f69d5696a5
4 changed files with 160 additions and 12 deletions
18
src/app/home/new-event/page.tsx
Normal file
18
src/app/home/new-event/page.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { ThemePicker } from '@/components/user/theme-picker';
|
||||||
|
import { Card, CardContent, CardHeader } from '@/components/ui/card';
|
||||||
|
import EventForm from '@/components/user/event-form';
|
||||||
|
|
||||||
|
export default function NewEvent() {
|
||||||
|
return (
|
||||||
|
<div className='flex flex-col items-center justify-center h-screen'>
|
||||||
|
<div className='absolute top-4 right-4'>{<ThemePicker />}</div>
|
||||||
|
<Card className='w-[80%] max-w-screen p-0 gap-0'>
|
||||||
|
<CardHeader className='p-0 m-0 gap-0' />
|
||||||
|
|
||||||
|
<CardContent>
|
||||||
|
<EventForm />
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
78
src/components/buttons/event-form.tsx
Normal file
78
src/components/buttons/event-form.tsx
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import LabeledInput from '@/components/labeled-input';
|
||||||
|
import { Button } from '@/components/custom-ui/button';
|
||||||
|
import Logo from '../logo';
|
||||||
|
export default function EventForm() {
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
className='flex flex-col gap-5 w-full'
|
||||||
|
action={async (formData) => {
|
||||||
|
'use server';
|
||||||
|
console.log('Form submitted with data:', formData);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='grid grid-row-start:auto gap-4'>
|
||||||
|
<div className='h-full mt-2 mb-6 flex items-center justify-between'>
|
||||||
|
<div>
|
||||||
|
<Logo colorType='monochrome' logoType='submark' width={50} />
|
||||||
|
</div>
|
||||||
|
<div className='items-center ml-auto mr-auto'>
|
||||||
|
<LabeledInput
|
||||||
|
type='text'
|
||||||
|
label='Event Name'
|
||||||
|
placeholder='New Event'
|
||||||
|
name='eventName'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='grid grid-cols-4 gap-4 h-full w-full'>
|
||||||
|
<div>
|
||||||
|
<p>Start Date select here</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>End Date selevt here</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>Location here</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>creatd:</p>
|
||||||
|
<p>updated:</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='h-full w-full grid grid-cols-2 gap-4'>
|
||||||
|
<div className='h-full w-full grid grid-flow-row gap-4'>
|
||||||
|
<div className='h-full w-full'>
|
||||||
|
<p>Organiser:</p>
|
||||||
|
</div>
|
||||||
|
<div className='h-full w-full'>
|
||||||
|
<LabeledInput
|
||||||
|
type='text'
|
||||||
|
label='Event Description'
|
||||||
|
placeholder='What is the event about?'
|
||||||
|
name='eventDescription'
|
||||||
|
big={true}
|
||||||
|
></LabeledInput>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='h-full w-full'>
|
||||||
|
<p>Participants here</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex flex-row gap-2 justify-end mt-4 mb-6'>
|
||||||
|
<div className='w-[20%] grid'>
|
||||||
|
<Button type='submit' variant='secondary'>
|
||||||
|
cancel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='w-[20%] grid'>
|
||||||
|
<Button type='submit' variant='primary'>
|
||||||
|
save event
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input, Textarea } from '@/components/ui/input';
|
||||||
import { Label } from '@/components/ui/label';
|
import { Label } from '@/components/ui/label';
|
||||||
|
|
||||||
export default function LabeledInput({
|
export default function LabeledInput({
|
||||||
|
@ -7,6 +7,7 @@ export default function LabeledInput({
|
||||||
placeholder,
|
placeholder,
|
||||||
value,
|
value,
|
||||||
name,
|
name,
|
||||||
|
big = false, // Add a prop for the bigger variant, default is false
|
||||||
autocomplete,
|
autocomplete,
|
||||||
error,
|
error,
|
||||||
...rest
|
...rest
|
||||||
|
@ -16,13 +17,22 @@ export default function LabeledInput({
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
big?: boolean; // Optional prop for bigger input
|
||||||
autocomplete?: string;
|
autocomplete?: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
} & React.InputHTMLAttributes<HTMLInputElement>) {
|
} & React.InputHTMLAttributes<HTMLInputElement>) {
|
||||||
return (
|
return (
|
||||||
<div className='grid grid-cols-1 gap-1'>
|
<div className='grid grid-cols-1 gap-1'>
|
||||||
<Label htmlFor={name}>{label}</Label>
|
<Label htmlFor={name}>{label}</Label>
|
||||||
|
{big ? (
|
||||||
|
<Textarea
|
||||||
|
placeholder={placeholder}
|
||||||
|
defaultValue={value}
|
||||||
|
id={name}
|
||||||
|
name={name}
|
||||||
|
rows={3}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<Input
|
<Input
|
||||||
type={type}
|
type={type}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
@ -32,6 +42,7 @@ export default function LabeledInput({
|
||||||
autoComplete={autocomplete}
|
autoComplete={autocomplete}
|
||||||
{...rest}
|
{...rest}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
{error && <p className='text-red-500 text-sm mt-1'>{error}</p>}
|
{error && <p className='text-red-500 text-sm mt-1'>{error}</p>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -41,4 +41,45 @@ function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Input };
|
function Textarea({
|
||||||
|
className,
|
||||||
|
rows,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<'textarea'>) {
|
||||||
|
return (
|
||||||
|
<textarea
|
||||||
|
data-slot='input'
|
||||||
|
rows={rows}
|
||||||
|
className={cn(
|
||||||
|
/* Text */
|
||||||
|
'text-text-input selection:text-text md:text-sm placeholder:text-text-muted-input',
|
||||||
|
/* Background */
|
||||||
|
'bg-transparent selection:bg-muted-input',
|
||||||
|
/* Border */
|
||||||
|
'rounded-md border border-input focus-visible:border-ring aria-invalid:border-destructive',
|
||||||
|
/* Font */
|
||||||
|
'',
|
||||||
|
/* Cursor */
|
||||||
|
'disabled:pointer-events-none disabled:cursor-not-allowed',
|
||||||
|
/* Ring */
|
||||||
|
'focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40',
|
||||||
|
/* Outline */
|
||||||
|
'outline-none',
|
||||||
|
/* Shadow */
|
||||||
|
'shadow-md transition-[color,box-shadow]',
|
||||||
|
/* Opacity */
|
||||||
|
'disabled:opacity-50',
|
||||||
|
/* Scaling */
|
||||||
|
'h-32 w-full min-w-0', // Bigger height for textarea
|
||||||
|
/* Spacing */
|
||||||
|
'px-3 py-2',
|
||||||
|
/* Alignment */
|
||||||
|
'',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Input, Textarea };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue