diff --git a/.env b/.env index 81ec38e..db7dc34 100644 --- a/.env +++ b/.env @@ -4,4 +4,5 @@ MY_AWS_ACCESS_KEY="AKIAT2UDOJMC4RSXQO5Y" MY_AWS_SECRET_KEY="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" REGION="us-east-1" S3_BUCKET_URL="https://flockstr.s3.amazonaws.com" -NEXT_PUBLIC_S3_BUCKET_URL="https://flockstr.s3.amazonaws.com" \ No newline at end of file +NEXT_PUBLIC_S3_BUCKET_URL="https://flockstr.s3.amazonaws.com" +NEXT_PUBLIC_GOOGLE_MAPS_KEY=AIzaSyDehwC0_6GIfPRZgNm4cpWuQ_Dz1HcEoYg \ No newline at end of file diff --git a/app/globals.css b/app/globals.css index 1a50fcd..ee75d34 100644 --- a/app/globals.css +++ b/app/globals.css @@ -123,3 +123,7 @@ @apply flex items-center justify-center; } } +input[type="time"]::-webkit-calendar-picker-indicator { + background: none; + display: none; +} diff --git a/bun.lockb b/bun.lockb index 3917105..63d42df 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components/EventIcons/DateIcon.tsx b/components/EventIcons/DateIcon.tsx new file mode 100644 index 0000000..9c7f32d --- /dev/null +++ b/components/EventIcons/DateIcon.tsx @@ -0,0 +1,19 @@ +import { formatDate } from "@/lib/utils/dates"; + +type SmallCalendarIconProps = { + date: Date; +}; +export default function SmallCalendarIcon({ date }: SmallCalendarIconProps) { + return ( +
+
+
+ {formatDate(date, "MMM")} +
+
+ {formatDate(date, "D")} +
+
+
+ ); +} diff --git a/components/EventIcons/LocationIcon.tsx b/components/EventIcons/LocationIcon.tsx new file mode 100644 index 0000000..eb4e0e6 --- /dev/null +++ b/components/EventIcons/LocationIcon.tsx @@ -0,0 +1,13 @@ +import { HiOutlineMapPin } from "react-icons/hi2"; + +export default function LocationIcon() { + return ( +
+
+
+ +
+
+
+ ); +} diff --git a/components/LocationSearch/index.tsx b/components/LocationSearch/index.tsx new file mode 100644 index 0000000..645b158 --- /dev/null +++ b/components/LocationSearch/index.tsx @@ -0,0 +1,121 @@ +"use client"; +import { useMemo } from "react"; +import usePlacesAutocomplete from "use-places-autocomplete"; +import { Input } from "../ui/input"; +import { cn } from "@/lib/utils"; +import { HiOutlineBuildingStorefront } from "react-icons/hi2"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import { Button } from "@/components/ui/button"; +import { + Command, + CommandEmpty, + CommandGroup, + CommandItem, + CommandInput, + CommandList, + CommandSeparator, +} from "@/components/ui/command"; +import { useLoadScript } from "@react-google-maps/api"; + +export default function LocationSearchInput() { + const libraries = useMemo(() => ["places"], []); + const { isLoaded, loadError } = useLoadScript({ + googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY as string, + libraries: libraries as any, + }); + const { + ready, + value, + suggestions: { status, data }, // results from Google Places API for the given search term + setValue, // use this method to link input value with the autocomplete hook + clearSuggestions, + } = usePlacesAutocomplete({ + requestOptions: { componentRestrictions: { country: "us" } }, // restrict search to US + debounce: 300, + cache: 86400, + }); + if (loadError) { + return

hello{JSON.stringify(loadError)}

; + } + if (!isLoaded) { + return

Loading...

; + } + return ; +} +function CommandSearch() { + const { + ready, + value, + suggestions: { status, data }, // results from Google Places API for the given search term + setValue, // use this method to link input value with the autocomplete hook + clearSuggestions, + } = usePlacesAutocomplete({ + requestOptions: { componentRestrictions: { country: "us" } }, // restrict search to US + debounce: 300, + cache: 86400, + }); + return ( + + + + + + + + setValue((e.target as unknown as { value: string }).value) + } + value={value} + placeholder="Search places..." + /> + + No results found. + + {data.map( + ({ + description, + place_id, + structured_formatting: { main_text, secondary_text }, + }) => ( + + + {main_text} + {description} + + ), + )} + + {/* + + + + Profile + + + + Mail + + + + Settings + + */} + + + + + ); +} diff --git a/components/Modals/CreateCalendarEvent.tsx b/components/Modals/CreateCalendarEvent.tsx new file mode 100644 index 0000000..b345cbb --- /dev/null +++ b/components/Modals/CreateCalendarEvent.tsx @@ -0,0 +1,207 @@ +"use client"; + +import { useState, useRef, useEffect } from "react"; +import Template from "./Template"; +import { Textarea } from "@/components/ui/textarea"; +import useAutosizeTextArea from "@/lib/hooks/useAutoSizeTextArea"; +import { Button } from "@/components/ui/button"; +import { HiX } from "react-icons/hi"; +import { cn } from "@/lib/utils"; +import { + addMinutesToDate, + convertToTimezoneDate, + convertToTimezone, +} from "@/lib/utils/dates"; +import { DatePicker } from "@/components/ui/date-picker"; +import { TimePicker } from "@/components/ui/time-picker"; +import { TimezoneSelector } from "../ui/timezone"; +import SmallCalendarIcon from "../EventIcons/DateIcon"; +import LocationIcon from "../EventIcons/LocationIcon"; +import LocationSearchInput from "../LocationSearch"; +import { useModal } from "@/app/_providers/modal/provider"; + +export default function CreateCalendarEventModal() { + const modal = useModal(); + const now = new Date(new Date().setHours(12, 0, 0, 0)); + const [title, setTitle] = useState(""); + const [startDate, setStartDate] = useState(now); + const startTime = `${ + startDate?.getHours().toLocaleString().length === 1 + ? "0" + startDate?.getHours().toLocaleString() + : startDate?.getHours() + }:${ + startDate?.getMinutes().toLocaleString().length === 1 + ? "0" + startDate?.getMinutes().toLocaleString() + : startDate?.getMinutes() + }`; + const [endDate, setEndDate] = useState( + new Date(new Date().setHours(13)), + ); + const endTime = `${ + endDate?.getHours().toLocaleString().length === 1 + ? "0" + endDate?.getHours().toLocaleString() + : endDate?.getHours() + }:${ + endDate?.getMinutes().toLocaleString().length === 1 + ? "0" + endDate?.getMinutes().toLocaleString() + : endDate?.getMinutes() + }`; + const [timezone, setTimezone] = useState( + Intl.DateTimeFormat().resolvedOptions().timeZone, + ); + + useEffect(() => { + if (startDate && endDate) { + if (startDate.getTime() > endDate.getTime()) { + setEndDate(addMinutesToDate(startDate, 60)); + } + } + }, [startDate]); + + const titleRef = useRef(null); + useAutosizeTextArea(titleRef.current, title); + + console.log(Intl.DateTimeFormat().resolvedOptions().timeZone); + + return ( +
+ +
+