updated meeting form functionality & add preview meeting form section

This commit is contained in:
Juthatip McDevitt 2024-04-27 22:58:29 -05:00
parent db5ea0770e
commit a5f49f643c
6 changed files with 146 additions and 9 deletions

View file

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

View file

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

View file

@ -12,7 +12,7 @@ const CreateMeeting = () => {
<MeetingForm setFormEvent={(value) => setFormEvent(value)}/>
</div>
<div className='md:col-span-2'>
<PreviewMeeting/>
<PreviewMeeting formEvent={formEvent}/>
</div>
</div>
)

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

View file

@ -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",

View file

@ -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",