updated meeting form functionality & add preview meeting form section
This commit is contained in:
parent
db5ea0770e
commit
a5f49f643c
6 changed files with 146 additions and 9 deletions
|
@ -18,7 +18,6 @@ const MeetingForm = ({setFormEvent}) => {
|
|||
const [locationMeeting, setLocationMeeting] = useState();
|
||||
const [urlMeeting, setUrlMeeting] = useState();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
setFormEvent({
|
||||
eventName: eventName,
|
||||
|
@ -30,7 +29,6 @@ const MeetingForm = ({setFormEvent}) => {
|
|||
}, [eventName, timeDuration, locationMeeting, urlMeeting, themeColor])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className='px-5 lg:px-10 py-10'>
|
||||
<Link href={'/dashboard'}><p className='flex gap-1 text-red-500 hover:text-red-600'><ChevronLeft/>Go back</p></Link>
|
||||
|
@ -55,7 +53,7 @@ const MeetingForm = ({setFormEvent}) => {
|
|||
<p className='font-semibold'>Location <span className='text-red-500'>*</span></p>
|
||||
<div className='grid grid-cols-4 gap-2'>
|
||||
{LocationOption.map((option, index) => (
|
||||
<div onClick={() => setLocationMeeting(option.name)} className={`border rounded-md flex flex-col justify-center items-center text-center p-2 hover:bg-gray-200 cursor-pointer ${locationMeeting == option.name && 'bg-gray-200'}`}>
|
||||
<div key={index} onClick={() => setLocationMeeting(option.name)} className={`border rounded-md flex flex-col justify-center items-center text-center p-2 hover:bg-gray-200 cursor-pointer ${locationMeeting == option.name && 'bg-gray-200'}`}>
|
||||
<Image src={option.icon} width={20} height={20} alt={option.name}/>
|
||||
<p className='text-xs mt-2 font-semibold'>{option.name}</p>
|
||||
</div>
|
||||
|
@ -63,14 +61,14 @@ const MeetingForm = ({setFormEvent}) => {
|
|||
</div>
|
||||
{locationMeeting &&
|
||||
<div>
|
||||
<p className='font-semibold'> Add {locationMeeting} url <span className='text-red-500'>*</span></p>
|
||||
<p className='font-semibold'> Add {locationMeeting} url or number <span className='text-red-500'>*</span></p>
|
||||
<Input onChange={(ev) => setUrlMeeting(ev.target.value)} placeholder='Add url' className='text-sm'/>
|
||||
</div>
|
||||
}
|
||||
<p className='font-semibold'>Select Color</p>
|
||||
<div className='flex justify-evenly'>
|
||||
{ThemeOption.map((color,index) => (
|
||||
<div onClick={() => setThemeColor(color)} className={`h-6 w-6 rounded-full ${themeColor == color && 'border-2 border-black'}`} style={{backgroundColor:color}}></div>
|
||||
<div key={index} onClick={() => setThemeColor(color)} className={`h-6 w-6 rounded-full ${themeColor == color && 'border-2 border-black'}`} style={{backgroundColor:color}}></div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,59 @@
|
|||
import React from 'react'
|
||||
import { GoClock } from "react-icons/go";
|
||||
import { PiMapPinLight } from "react-icons/pi";
|
||||
import { Calendar } from "@/components/ui/calendar"
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import Link from "next/link";
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
const PreviewMeeting = () => {
|
||||
const PreviewMeeting = ({formEvent}) => {
|
||||
const [date, setDate] = useState(new Date());
|
||||
const [timeSlots, setTimeSlots] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
formEvent?.timeDuration && createTimeSlot(formEvent?.timeDuration)
|
||||
}, [formEvent])
|
||||
//create time slot
|
||||
const createTimeSlot = (interval) => {
|
||||
const startTime = 8 * 60;
|
||||
const endTime = 22 * 60;
|
||||
const totalSlots = (endTime - startTime) / interval;
|
||||
const slots = Array.from({length: totalSlots}, (_, i) => {
|
||||
const totalMinutes = startTime + i * interval;
|
||||
const hours = Math.floor(totalMinutes / 60);
|
||||
const minutes = totalMinutes % 60;
|
||||
const formattedHours = hours > 12 ? hours - 12: hours;
|
||||
const period = hours >= 12? 'PM' : 'AM';
|
||||
return `${String(formattedHours).padStart(2, '0')} : ${String(minutes).padStart(2, '0')} ${period}`
|
||||
});
|
||||
setTimeSlots(slots);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div>This is a preview meeting section</div>
|
||||
<div className='px-5 py-10 shadow-md m-4 border-t-8'>
|
||||
<p className='text-xl uppercase font-semibold tracking-wide'>Schedule.Me</p>
|
||||
<div className='grid grid-cols-1 md:grid-cols-3 mt-5'>
|
||||
<div className='border-r'>
|
||||
<p className='font-semibold'>Event Name: <span className="font-normal">{formEvent?.eventName?formEvent?.eventName:'Meeting/Event Name'}</span></p>
|
||||
<div className='mt-5 flex flex-col gap-2'>
|
||||
<p className='flex gap-1 items-center'><GoClock/>{formEvent?.timeDuration} minutes</p>
|
||||
<p className='flex gap-1 items-center'><PiMapPinLight/>{formEvent?.locationMeeting}</p>
|
||||
<Link href={formEvent?.urlMeeting?formEvent?.urlMeeting:''} className="text-gray-500 underline text-sm">{formEvent?.urlMeeting}</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex px-5 md:col-span-2'>
|
||||
<div className="flex flex-col">
|
||||
<p className="font-semibold">Select your meeting date & time</p>
|
||||
<Calendar mode="single" selected={date} onSelect={setDate} className="rounded-md border mt-5"/>
|
||||
</div>
|
||||
<div>
|
||||
{timeSlots?.map((time, index) => (
|
||||
<Button variant="outline">{time}</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ const CreateMeeting = () => {
|
|||
<MeetingForm setFormEvent={(value) => setFormEvent(value)}/>
|
||||
</div>
|
||||
<div className='md:col-span-2'>
|
||||
<PreviewMeeting/>
|
||||
<PreviewMeeting formEvent={formEvent}/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
62
scheduler_app/components/ui/calendar.jsx
Normal file
62
scheduler_app/components/ui/calendar.jsx
Normal file
|
@ -0,0 +1,62 @@
|
|||
"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"
|
||||
|
||||
function Calendar({
|
||||
className,
|
||||
classNames,
|
||||
showOutsideDays = true,
|
||||
...props
|
||||
}) {
|
||||
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 }
|
24
scheduler_app/package-lock.json
generated
24
scheduler_app/package-lock.json
generated
|
@ -13,11 +13,13 @@
|
|||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^3.6.0",
|
||||
"firebase": "^10.11.0",
|
||||
"lucide-react": "^0.373.0",
|
||||
"next": "14.2.3",
|
||||
"next-themes": "^0.3.0",
|
||||
"react": "^18",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18",
|
||||
"react-icons": "^5.1.0",
|
||||
"sonner": "^1.4.41",
|
||||
|
@ -3513,6 +3515,15 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
|
||||
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/kossnocorp"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
|
@ -4441,6 +4452,19 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-day-picker": {
|
||||
"version": "8.10.1",
|
||||
"resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz",
|
||||
"integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==",
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/gpbl"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"date-fns": "^2.28.0 || ^3.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^3.6.0",
|
||||
"firebase": "^10.11.0",
|
||||
"lucide-react": "^0.373.0",
|
||||
"next": "14.2.3",
|
||||
"next-themes": "^0.3.0",
|
||||
"react": "^18",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18",
|
||||
"react-icons": "^5.1.0",
|
||||
"sonner": "^1.4.41",
|
||||
|
|
Loading…
Add table
Reference in a new issue