feat: create basic layout for new new event page

This commit is contained in:
micha 2025-06-11 16:52:53 +02:00
parent e372cf6e90
commit f69d5696a5
4 changed files with 160 additions and 12 deletions

View 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>
);
}

View 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>
);
}

View file

@ -1,4 +1,4 @@
import { Input } from '@/components/ui/input';
import { Input, Textarea } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
export default function LabeledInput({
@ -7,6 +7,7 @@ export default function LabeledInput({
placeholder,
value,
name,
big = false, // Add a prop for the bigger variant, default is false
autocomplete,
error,
...rest
@ -16,22 +17,32 @@ export default function LabeledInput({
placeholder?: string;
value?: string;
name?: string;
big?: boolean; // Optional prop for bigger input
autocomplete?: string;
error?: string;
} & React.InputHTMLAttributes<HTMLInputElement>) {
return (
<div className='grid grid-cols-1 gap-1'>
<Label htmlFor={name}>{label}</Label>
<Input
type={type}
placeholder={placeholder}
defaultValue={value}
id={name}
name={name}
autoComplete={autocomplete}
{...rest}
/>
{big ? (
<Textarea
placeholder={placeholder}
defaultValue={value}
id={name}
name={name}
rows={3}
/>
) : (
<Input
type={type}
placeholder={placeholder}
defaultValue={value}
id={name}
name={name}
autoComplete={autocomplete}
{...rest}
/>
)}
{error && <p className='text-red-500 text-sm mt-1'>{error}</p>}
</div>
);

View file

@ -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 };