From fad65913dcd353a7531bc44b9f722b26caea1084 Mon Sep 17 00:00:00 2001 From: BK2004 Date: Sun, 8 Sep 2024 12:43:08 -0500 Subject: [PATCH 01/37] event picture select grayed out; select start and end time by date only --- .../[clubId]/create/CreateEventForm.tsx | 4 +- src/app/manage/[clubId]/create/TimeSelect.tsx | 55 +++---------------- 2 files changed, 12 insertions(+), 47 deletions(-) diff --git a/src/app/manage/[clubId]/create/CreateEventForm.tsx b/src/app/manage/[clubId]/create/CreateEventForm.tsx index 70168b22..28542274 100644 --- a/src/app/manage/[clubId]/create/CreateEventForm.tsx +++ b/src/app/manage/[clubId]/create/CreateEventForm.tsx @@ -24,6 +24,8 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub resolver: zodResolver(createEventSchema), defaultValues: { clubId: clubId, + startTime: new Date(Date.now()), + endTime: new Date(Date.now()), }, mode: "onSubmit", }); @@ -89,7 +91,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub

Event Picture

Drag or choose file to upload

-
+

JPEG, PNG, or SVG

diff --git a/src/app/manage/[clubId]/create/TimeSelect.tsx b/src/app/manage/[clubId]/create/TimeSelect.tsx index 05ea7d24..820a6770 100644 --- a/src/app/manage/[clubId]/create/TimeSelect.tsx +++ b/src/app/manage/[clubId]/create/TimeSelect.tsx @@ -16,69 +16,32 @@ interface Props { } const TimeSelect = ({ register, setValue, getValues, watchStartTime }: Props) => { - const [multiDay, setMultiDay] = useState(false); - const [numHours, setNumHours] = useState(2); - useEffect(() => { - // If not multi-day, set end time to start time + numHours - if (!multiDay && watchStartTime !== undefined) { - const date = new Date(watchStartTime); - date.setHours(date.getHours() + numHours); - setValue("endTime", date); - } - // If start time is after end time, set end time to start time - if (new Date(watchStartTime) > new Date(getValues('endTime'))) { + if ((new Date(watchStartTime) > new Date(getValues('endTime')))) { setValue('endTime', watchStartTime); } - }, [setValue, getValues, watchStartTime, multiDay, numHours]) + }, [setValue, getValues, watchStartTime]) return (<> -
-
-

Multi-Day Event

-

Does the event last longer than one day?

-
-
-
-
{ - // If switching to multiDay, clear endTime - if (!multiDay) { - setValue('endTime', new Date(NaN)); - } - setMultiDay(!multiDay); - }} >
-

{multiDay ? "Yes" : "No"}

-
-
-

Duration

- +
- { multiDay ?
- { if (new Date(e.currentTarget.value) < new Date(watchStartTime)) setValue('endTime', watchStartTime); }} - min={watchStartTime?.toString()} + min={watchStartTime?.toString()} className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]" />
- : -
- - -
- }
); } From 57d094569769c56b0008b0f323f0ee8d12d4a209 Mon Sep 17 00:00:00 2001 From: BK2004 Date: Sun, 8 Sep 2024 12:52:00 -0500 Subject: [PATCH 02/37] end time defaults to start time when empty in TimeSelect --- src/app/manage/[clubId]/create/CreateEventForm.tsx | 2 -- src/app/manage/[clubId]/create/TimeSelect.tsx | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/manage/[clubId]/create/CreateEventForm.tsx b/src/app/manage/[clubId]/create/CreateEventForm.tsx index 28542274..d2117976 100644 --- a/src/app/manage/[clubId]/create/CreateEventForm.tsx +++ b/src/app/manage/[clubId]/create/CreateEventForm.tsx @@ -24,8 +24,6 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub resolver: zodResolver(createEventSchema), defaultValues: { clubId: clubId, - startTime: new Date(Date.now()), - endTime: new Date(Date.now()), }, mode: "onSubmit", }); diff --git a/src/app/manage/[clubId]/create/TimeSelect.tsx b/src/app/manage/[clubId]/create/TimeSelect.tsx index 820a6770..af30988a 100644 --- a/src/app/manage/[clubId]/create/TimeSelect.tsx +++ b/src/app/manage/[clubId]/create/TimeSelect.tsx @@ -18,7 +18,9 @@ interface Props { const TimeSelect = ({ register, setValue, getValues, watchStartTime }: Props) => { useEffect(() => { // If start time is after end time, set end time to start time - if ((new Date(watchStartTime) > new Date(getValues('endTime')))) { + console.log(getValues("endTime")); + if ((new Date(watchStartTime) > new Date(getValues('endTime'))) + || (watchStartTime !== undefined && getValues('endTime').toString() === "")) { setValue('endTime', watchStartTime); } }, [setValue, getValues, watchStartTime]) From 5962921bd7c674c52c91e092fe0299161a51ea18 Mon Sep 17 00:00:00 2001 From: BK2004 Date: Sun, 8 Sep 2024 13:10:48 -0500 Subject: [PATCH 03/37] Create API route returns event id; successful event creation redirects to event page; added protection against create event spam while redirecting --- src/app/manage/[clubId]/create/CreateEventForm.tsx | 8 ++++++-- src/server/api/routers/event.ts | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/app/manage/[clubId]/create/CreateEventForm.tsx b/src/app/manage/[clubId]/create/CreateEventForm.tsx index d2117976..95da69d6 100644 --- a/src/app/manage/[clubId]/create/CreateEventForm.tsx +++ b/src/app/manage/[clubId]/create/CreateEventForm.tsx @@ -29,6 +29,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub }); const router = useRouter(); const [watchDescription, watchStartTime] = watch(['description', 'startTime']); + const [redirecting, setRedirecting] = useState(false); const [eventPreview, setEventPreview] = useState({ name: "", clubId, @@ -65,11 +66,14 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub }, [router, watch, officerClubs]); const createMutation = api.event.create.useMutation({ - onSuccess: () => { location.reload(); } + onSuccess: (data) => { if (data) { + setRedirecting(true); + router.push(`/event/${data}`); + } } }) const onSubmit = handleSubmit((data: z.infer) => { - if (!createMutation.isPending) { + if (!createMutation.isPending && !redirecting) { createMutation.mutate(data); } }); diff --git a/src/server/api/routers/event.ts b/src/server/api/routers/event.ts index e883f40e..454af6e4 100644 --- a/src/server/api/routers/event.ts +++ b/src/server/api/routers/event.ts @@ -262,7 +262,9 @@ export const eventRouter = createTRPCRouter({ throw new TRPCError({ code: 'UNAUTHORIZED' }); } - await ctx.db.insert(events).values({ ...input }); + const res = await ctx.db.insert(events).values({ ...input }).returning({ id: events.id }); + if (res.length == 0) throw "Failed to add event"; + return res[0]?.id; }), byName: publicProcedure.input(byNameSchema).query(async ({ input, ctx }) => { const { name, sortByDate } = input; From 518ef41b8079430b9d6b55c20d12024112dfc3e6 Mon Sep 17 00:00:00 2001 From: BK2004 Date: Sun, 8 Sep 2024 13:12:24 -0500 Subject: [PATCH 04/37] remove unused dependency --- src/app/manage/[clubId]/create/TimeSelect.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/manage/[clubId]/create/TimeSelect.tsx b/src/app/manage/[clubId]/create/TimeSelect.tsx index af30988a..b446831a 100644 --- a/src/app/manage/[clubId]/create/TimeSelect.tsx +++ b/src/app/manage/[clubId]/create/TimeSelect.tsx @@ -1,5 +1,5 @@ 'use client' -import { useEffect, useState } from "react"; +import { useEffect } from "react"; import type { UseFormRegister, UseFormSetValue, From d91f446a4d783c196d5207b0880fab8567f7cfe6 Mon Sep 17 00:00:00 2001 From: BK2004 Date: Thu, 19 Sep 2024 20:12:34 -0500 Subject: [PATCH 05/37] start time updates end time to start time + one hour if needed; grayed out create event button while processing --- .../[clubId]/create/CreateEventForm.tsx | 24 ++++--- src/app/manage/[clubId]/create/TimeSelect.tsx | 63 ++++++++++++------- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/app/manage/[clubId]/create/CreateEventForm.tsx b/src/app/manage/[clubId]/create/CreateEventForm.tsx index 95da69d6..b257eedb 100644 --- a/src/app/manage/[clubId]/create/CreateEventForm.tsx +++ b/src/app/manage/[clubId]/create/CreateEventForm.tsx @@ -20,6 +20,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub watch, setValue, getValues, + control, } = useForm>({ resolver: zodResolver(createEventSchema), defaultValues: { @@ -29,7 +30,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub }); const router = useRouter(); const [watchDescription, watchStartTime] = watch(['description', 'startTime']); - const [redirecting, setRedirecting] = useState(false); + const [loading, setLoading] = useState(false); const [eventPreview, setEventPreview] = useState({ name: "", clubId, @@ -53,8 +54,8 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub location: location || "", liked: false, id: "", - startTime: startTime?.toString() === "" || startTime == undefined ? new Date(Date.now()) : new Date(startTime), - endTime: endTime?.toString() === "" || endTime?.toString() == "Invalid Date" || !endTime ? new Date(Date.now()) : new Date(endTime), + startTime: startTime?.toString() === "" || startTime === undefined ? new Date(Date.now()) : new Date(startTime), + endTime: endTime?.toString() === "" || endTime?.toString() === "Invalid Date" || !endTime ? new Date(Date.now()) : new Date(endTime), club, }); } @@ -67,13 +68,16 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub const createMutation = api.event.create.useMutation({ onSuccess: (data) => { if (data) { - setRedirecting(true); router.push(`/event/${data}`); - } } + } }, + onError: (e) => { + setLoading(false); + } }) const onSubmit = handleSubmit((data: z.infer) => { - if (!createMutation.isPending && !redirecting) { + if (!createMutation.isPending && !loading) { + setLoading(true); createMutation.mutate(data); } }); @@ -122,8 +126,12 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub placeholder="Event description" />
- - + +

Preview

diff --git a/src/app/manage/[clubId]/create/TimeSelect.tsx b/src/app/manage/[clubId]/create/TimeSelect.tsx index b446831a..9674b2aa 100644 --- a/src/app/manage/[clubId]/create/TimeSelect.tsx +++ b/src/app/manage/[clubId]/create/TimeSelect.tsx @@ -1,48 +1,67 @@ 'use client' -import { useEffect } from "react"; import type { UseFormRegister, UseFormSetValue, UseFormGetValues, + Control +} from "react-hook-form"; +import { + Controller } from "react-hook-form"; import type { createEventSchema } from "@src/utils/formSchemas"; import type { z } from "zod"; interface Props { - register: UseFormRegister>, setValue: UseFormSetValue>, getValues: UseFormGetValues>, watchStartTime: Date, + control: Control>, } -const TimeSelect = ({ register, setValue, getValues, watchStartTime }: Props) => { - useEffect(() => { - // If start time is after end time, set end time to start time - console.log(getValues("endTime")); - if ((new Date(watchStartTime) > new Date(getValues('endTime'))) - || (watchStartTime !== undefined && getValues('endTime').toString() === "")) { - setValue('endTime', watchStartTime); - } - }, [setValue, getValues, watchStartTime]) - +const TimeSelect = ({ setValue, getValues, watchStartTime, control }: Props) => { return (<>

Duration

- + ( + { + if (!getValues("endTime") || new Date(e.currentTarget.value) > getValues("endTime")) { + // Add 1 hr to new start time + setValue("endTime", new Date(new Date(e.currentTarget.value).getTime() + 60 * 60 * 1000)); + } + onChange(new Date(e.currentTarget.value)); + }} + className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]" /> + )} + rules={{ + required: true, + }} />
- { if (new Date(e.currentTarget.value) < new Date(watchStartTime)) setValue('endTime', watchStartTime); }} - min={watchStartTime?.toString()} - className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]" - /> + ( + onChange(new Date(e.currentTarget.value))} + className="outline-none w-full block p-2 text-xs rounded-md text-[#7D8FB3]" /> + )} + rules={{ + required: true, + }} />
); From 8c41e9a3085bb13e63761f5dc7acde1c62dd8d9c Mon Sep 17 00:00:00 2001 From: BK2004 Date: Thu, 19 Sep 2024 20:14:38 -0500 Subject: [PATCH 06/37] fixed build errors --- src/app/manage/[clubId]/create/CreateEventForm.tsx | 2 +- src/app/manage/[clubId]/create/TimeSelect.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/manage/[clubId]/create/CreateEventForm.tsx b/src/app/manage/[clubId]/create/CreateEventForm.tsx index b257eedb..fb3fbf0e 100644 --- a/src/app/manage/[clubId]/create/CreateEventForm.tsx +++ b/src/app/manage/[clubId]/create/CreateEventForm.tsx @@ -70,7 +70,7 @@ const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClub onSuccess: (data) => { if (data) { router.push(`/event/${data}`); } }, - onError: (e) => { + onError: () => { setLoading(false); } }) diff --git a/src/app/manage/[clubId]/create/TimeSelect.tsx b/src/app/manage/[clubId]/create/TimeSelect.tsx index 9674b2aa..4e9f942a 100644 --- a/src/app/manage/[clubId]/create/TimeSelect.tsx +++ b/src/app/manage/[clubId]/create/TimeSelect.tsx @@ -1,6 +1,5 @@ 'use client' import type { - UseFormRegister, UseFormSetValue, UseFormGetValues, Control From 95d66591f0da45ef80793e32e65a6387e34d63fd Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 09:05:36 -0500 Subject: [PATCH 07/37] seperate different search bars each search bar is now it's own file --- .../edit/officers/EditOfficerForm.tsx | 2 +- src/components/BaseHeader.tsx | 3 +- src/components/OfficerSelector.tsx | 2 +- src/components/SearchBar.tsx | 198 ------------------ src/components/admin/AddOfficer.tsx | 2 +- src/components/admin/OrgSearch.tsx | 4 +- src/components/searchBar/ClubSearchBar.tsx | 26 +++ .../searchBar/DebouncedSearchBar.tsx | 69 ++++++ .../searchBar/EventClubSearchBar.tsx | 38 ++++ src/components/searchBar/EventSearchBar.tsx | 34 +++ src/components/searchBar/UserSearchBar.tsx | 42 ++++ src/components/searchBar/index.tsx | 20 ++ 12 files changed, 236 insertions(+), 204 deletions(-) delete mode 100644 src/components/SearchBar.tsx create mode 100644 src/components/searchBar/ClubSearchBar.tsx create mode 100644 src/components/searchBar/DebouncedSearchBar.tsx create mode 100644 src/components/searchBar/EventClubSearchBar.tsx create mode 100644 src/components/searchBar/EventSearchBar.tsx create mode 100644 src/components/searchBar/UserSearchBar.tsx create mode 100644 src/components/searchBar/index.tsx diff --git a/src/app/manage/[clubId]/edit/officers/EditOfficerForm.tsx b/src/app/manage/[clubId]/edit/officers/EditOfficerForm.tsx index bf18ee28..f0f027d7 100644 --- a/src/app/manage/[clubId]/edit/officers/EditOfficerForm.tsx +++ b/src/app/manage/[clubId]/edit/officers/EditOfficerForm.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ 'use client'; import { zodResolver } from '@hookform/resolvers/zod'; -import { UserSearchBar } from '@src/components/SearchBar'; +import { UserSearchBar } from '@src/components/searchBar/UserSearchBar'; import { api } from '@src/trpc/react'; import { editOfficerSchema } from '@src/utils/formSchemas'; import { useRouter } from 'next/navigation'; diff --git a/src/components/BaseHeader.tsx b/src/components/BaseHeader.tsx index 93d0a874..ac43c322 100644 --- a/src/components/BaseHeader.tsx +++ b/src/components/BaseHeader.tsx @@ -1,7 +1,8 @@ import type { ReactNode } from 'react'; import { ProfileDropDown } from './ProfileDropDown'; import { getServerAuthSession } from '@src/server/auth'; -import { ClubSearchBar, EventSearchBar } from './SearchBar'; +import { ClubSearchBar } from './searchBar/ClubSearchBar'; +import { EventSearchBar } from './searchBar/EventSearchBar'; import SignInButton from './signInButton'; import MobileNav from './MobileNav'; import { api } from '@src/trpc/server'; diff --git a/src/components/OfficerSelector.tsx b/src/components/OfficerSelector.tsx index 230828fa..b40a7e57 100644 --- a/src/components/OfficerSelector.tsx +++ b/src/components/OfficerSelector.tsx @@ -7,7 +7,7 @@ import { type FieldErrors, } from 'react-hook-form'; import { type z } from 'zod'; -import { UserSearchBar } from './SearchBar'; +import { UserSearchBar } from './searchBar/UserSearchBar'; type OfficerSelectorProps = { control: Control>; diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx deleted file mode 100644 index fb219eb2..00000000 --- a/src/components/SearchBar.tsx +++ /dev/null @@ -1,198 +0,0 @@ -'use client'; -import { - type Dispatch, - type SetStateAction, - useState, - type ChangeEvent, - useEffect, -} from 'react'; -import { SearchIcon } from '../icons/Icons'; -import { useRouter } from 'next/navigation'; -import type { - SelectClub as Club, - SelectUserMetadata, -} from '@src/server/db/models'; -import { api } from '@src/trpc/react'; -import type { SelectEvent as Event } from '@src/server/db/models'; - -type SearchElement = { - id: string; - name: string; -}; -type SearchBarProps = { - placeholder: string; - value?: string; - setSearch: Dispatch>; - searchResults?: Array; - onClick?: (input: T) => void; -}; - -export const SearchBar = ({ - placeholder, - value, - setSearch, - searchResults, - onClick, -}: SearchBarProps) => { - const [input, setInput] = useState(value ?? ''); - const [focused, setFocused] = useState(false); - const handleSearch = (e: ChangeEvent) => { - setInput(e.target.value); - }; - useEffect(() => { - const handler = setTimeout(() => { - setSearch(input); - }, 300); - return () => { - clearTimeout(handler); - }; - }, [input, setSearch]); - - return ( -
-
- - - - setFocused(true)} - onBlur={() => setTimeout(() => setFocused(false), 300)} - /> - {input && focused && searchResults && searchResults.length > 0 && ( -
- {searchResults.map((item) => ( - - ))} -
- )} -
-
- ); -}; - -export const ClubSearchBar = () => { - const router = useRouter(); - const [search, setSearch] = useState(''); - const { data } = api.club.byName.useQuery( - { name: search }, - { enabled: !!search }, - ); - const onClickSearchResult = (club: Club) => { - router.push(`/directory/${club.id}`); - }; - return ( - - ); -}; -export const EventSearchBar = () => { - const router = useRouter(); - const [search, setSearch] = useState(''); - const [res, setRes] = useState([]); - - const eventQuery = api.event.byName.useQuery( - { - name: search, - sortByDate: true, - }, - { enabled: !!search }, - ); - useEffect(() => { - if (eventQuery.data) setRes(eventQuery.data); - }, [eventQuery.data]); - - return ( - { - router.push(`/event/${event.id}`); - }} - /> - ); -}; -type EventClubSearchBarProps = { - addClub: (value: string) => void; -}; -export const EventClubSearchBar = ({ addClub }: EventClubSearchBarProps) => { - const [search, setSearch] = useState(''); - const [res, setRes] = useState([]); - const utils = api.useUtils(); - const clubQuery = api.club.byName.useQuery( - { name: search }, - { - enabled: !!search, - }, - ); - useEffect(() => { - if (clubQuery.data) { - setRes(clubQuery.data); - } - }, [clubQuery.data]); - return ( - { - void utils.club.byId.prefetch({ id: club.id }); - addClub(club.id); - setSearch(''); - }} - /> - ); -}; -type UserSearchBarProps = { - passUser: (user: { id: string; name: string }) => void; -}; -type User = { - name: string; -} & SelectUserMetadata; -export const UserSearchBar = ({ passUser }: UserSearchBarProps) => { - const [search, setSearch] = useState(''); - const [res, setRes] = useState([]); - const userQuery = api.userMetadata.searchByName.useQuery( - { name: search }, - { - enabled: !!search, - }, - ); - useEffect(() => { - if (userQuery.data) { - const newData = userQuery.data.map((val) => { - return { name: val.firstName + ' ' + val.lastName, ...val }; - }); - setRes(newData); - } - }, [userQuery.data]); - return ( - { - passUser({ id: user.id, name: user.name }); - setSearch(''); - }} - /> - ); -}; diff --git a/src/components/admin/AddOfficer.tsx b/src/components/admin/AddOfficer.tsx index f4125260..3545811f 100644 --- a/src/components/admin/AddOfficer.tsx +++ b/src/components/admin/AddOfficer.tsx @@ -1,7 +1,7 @@ 'use client'; import { api } from '@src/trpc/react'; -import { UserSearchBar } from '../SearchBar'; +import { UserSearchBar } from '../searchBar/UserSearchBar'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; diff --git a/src/components/admin/OrgSearch.tsx b/src/components/admin/OrgSearch.tsx index 505a710f..9caf805d 100644 --- a/src/components/admin/OrgSearch.tsx +++ b/src/components/admin/OrgSearch.tsx @@ -2,7 +2,7 @@ import { api } from '@src/trpc/react'; import { useState } from 'react'; -import { SearchBar } from '../SearchBar'; +import { DebouncedSearchBar } from '../searchBar/DebouncedSearchBar'; import { type SelectClub } from '@src/server/db/models'; type Props = { @@ -21,7 +21,7 @@ export default function OrgSearch({ setOrg }: Props) { setSearch(''); }; return ( - { + const router = useRouter(); + const [search, setSearch] = useState(''); + const { data } = api.club.byName.useQuery( + { name: search }, + { enabled: !!search }, + ); + const onClickSearchResult = (club: Club) => { + router.push(`/directory/${club.id}`); + }; + return ( + + ); +}; diff --git a/src/components/searchBar/DebouncedSearchBar.tsx b/src/components/searchBar/DebouncedSearchBar.tsx new file mode 100644 index 00000000..395f898c --- /dev/null +++ b/src/components/searchBar/DebouncedSearchBar.tsx @@ -0,0 +1,69 @@ +'use client'; +import { + useState, + type ChangeEvent, + useEffect, + type Dispatch, + type SetStateAction, +} from 'react'; +import { SearchBar } from '.'; + +export type SearchElement = { + id: string; + name: string; +}; +export type DebouncedSearchBarProps = { + placeholder: string; + value?: string; + setSearch: Dispatch>; + searchResults?: Array; + onClick?: (input: T) => void; +}; +export const DebouncedSearchBar = ({ + placeholder, + value, + setSearch, + searchResults, + onClick, +}: DebouncedSearchBarProps) => { + const [input, setInput] = useState(value ?? ''); + const [focused, setFocused] = useState(false); + const handleSearch = (e: ChangeEvent) => { + setInput(e.target.value); + }; + useEffect(() => { + const handler = setTimeout(() => { + setSearch(input); + }, 300); + return () => { + clearTimeout(handler); + }; + }, [input, setSearch]); + + return ( +
+ setFocused(true)} + onBlur={() => setTimeout(() => setFocused(false), 300)} + /> + {input && focused && searchResults && searchResults.length > 0 && ( +
+ {searchResults.map((item) => ( + + ))} +
+ )} +
+ ); +}; +export default DebouncedSearchBar; diff --git a/src/components/searchBar/EventClubSearchBar.tsx b/src/components/searchBar/EventClubSearchBar.tsx new file mode 100644 index 00000000..afce98f5 --- /dev/null +++ b/src/components/searchBar/EventClubSearchBar.tsx @@ -0,0 +1,38 @@ +'use client'; +import { useState, useEffect } from 'react'; +import type { SelectClub as Club } from '@src/server/db/models'; +import { api } from '@src/trpc/react'; +import { DebouncedSearchBar } from './DebouncedSearchBar'; + +type EventClubSearchBarProps = { + addClub: (value: string) => void; +}; +export const EventClubSearchBar = ({ addClub }: EventClubSearchBarProps) => { + const [search, setSearch] = useState(''); + const [res, setRes] = useState([]); + const utils = api.useUtils(); + const clubQuery = api.club.byName.useQuery( + { name: search }, + { + enabled: !!search, + }, + ); + useEffect(() => { + if (clubQuery.data) { + setRes(clubQuery.data); + } + }, [clubQuery.data]); + return ( + { + void utils.club.byId.prefetch({ id: club.id }); + addClub(club.id); + setSearch(''); + }} + /> + ); +}; diff --git a/src/components/searchBar/EventSearchBar.tsx b/src/components/searchBar/EventSearchBar.tsx new file mode 100644 index 00000000..04adb555 --- /dev/null +++ b/src/components/searchBar/EventSearchBar.tsx @@ -0,0 +1,34 @@ +'use client'; +import { useState, useEffect } from 'react'; +import { useRouter } from 'next/navigation'; +import { api } from '@src/trpc/react'; +import type { SelectEvent as Event } from '@src/server/db/models'; +import { DebouncedSearchBar } from './DebouncedSearchBar'; + +export const EventSearchBar = () => { + const router = useRouter(); + const [search, setSearch] = useState(''); + const [res, setRes] = useState([]); + + const eventQuery = api.event.byName.useQuery( + { + name: search, + sortByDate: true, + }, + { enabled: !!search }, + ); + useEffect(() => { + if (eventQuery.data) setRes(eventQuery.data); + }, [eventQuery.data]); + + return ( + { + router.push(`/event/${event.id}`); + }} + /> + ); +}; diff --git a/src/components/searchBar/UserSearchBar.tsx b/src/components/searchBar/UserSearchBar.tsx new file mode 100644 index 00000000..487d4f40 --- /dev/null +++ b/src/components/searchBar/UserSearchBar.tsx @@ -0,0 +1,42 @@ +'use client'; +import { type SelectUserMetadata } from '@src/server/db/models'; +import { api } from '@src/trpc/react'; +import { useState, useEffect } from 'react'; +import { DebouncedSearchBar } from './DebouncedSearchBar'; + +type UserSearchBarProps = { + passUser: (user: { id: string; name: string }) => void; +}; +type User = { + name: string; +} & SelectUserMetadata; +export const UserSearchBar = ({ passUser }: UserSearchBarProps) => { + const [search, setSearch] = useState(''); + const [res, setRes] = useState([]); + const userQuery = api.userMetadata.searchByName.useQuery( + { name: search }, + { + enabled: !!search, + }, + ); + useEffect(() => { + if (userQuery.data) { + const newData = userQuery.data.map((val) => { + return { name: val.firstName + ' ' + val.lastName, ...val }; + }); + setRes(newData); + } + }, [userQuery.data]); + return ( + { + passUser({ id: user.id, name: user.name }); + setSearch(''); + }} + /> + ); +}; diff --git a/src/components/searchBar/index.tsx b/src/components/searchBar/index.tsx new file mode 100644 index 00000000..2fbe4389 --- /dev/null +++ b/src/components/searchBar/index.tsx @@ -0,0 +1,20 @@ +import { SearchIcon } from '@src/icons/Icons'; +import { ComponentProps } from 'react'; + +type SearchBarProps = Omit, 'type'>; + +export const SearchBar = (props: SearchBarProps) => { + return ( +
+ + + + +
+ ); +}; +export default SearchBar; From 322ec200a462fa3082451c2100eedede313c1029 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 09:08:32 -0500 Subject: [PATCH 08/37] relocate EventLikeButton --- src/components/events/EventCard.tsx | 2 +- src/components/{ => events}/EventLikeButton.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/components/{ => events}/EventLikeButton.tsx (94%) diff --git a/src/components/events/EventCard.tsx b/src/components/events/EventCard.tsx index 75008289..091256fa 100644 --- a/src/components/events/EventCard.tsx +++ b/src/components/events/EventCard.tsx @@ -4,7 +4,7 @@ import Image from 'next/image'; import Link from 'next/link'; import { MoreIcon } from '../../icons/Icons'; import { type RouterOutputs } from '@src/trpc/shared'; -import EventLikeButton from '../EventLikeButton'; +import EventLikeButton from './EventLikeButton'; import { getServerAuthSession } from '@src/server/auth'; import dynamic from 'next/dynamic'; diff --git a/src/components/EventLikeButton.tsx b/src/components/events/EventLikeButton.tsx similarity index 94% rename from src/components/EventLikeButton.tsx rename to src/components/events/EventLikeButton.tsx index 59588782..a22b05a4 100644 --- a/src/components/EventLikeButton.tsx +++ b/src/components/events/EventLikeButton.tsx @@ -1,6 +1,6 @@ 'use client'; /* eslint-disable @typescript-eslint/no-misused-promises */ -import { CheckIcon, PlusIcon } from '../icons/Icons'; +import { CheckIcon, PlusIcon } from '../../icons/Icons'; import { api } from '@src/trpc/react'; import { useRouter } from 'next/navigation'; From 2d31a147db18bd54beb18dc8a56ed4bf6958ac8c Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 09:14:50 -0500 Subject: [PATCH 09/37] relocate sidebar/nav to own folder --- src/app/layout.tsx | 2 +- src/components/BaseHeader.tsx | 2 +- src/components/{ => nav}/MobileNav.tsx | 0 src/components/{ => nav}/NavMenu.tsx | 0 src/components/{ => nav}/Sidebar.tsx | 0 src/components/{ => nav}/SidebarItems.tsx | 2 +- 6 files changed, 3 insertions(+), 3 deletions(-) rename src/components/{ => nav}/MobileNav.tsx (100%) rename src/components/{ => nav}/NavMenu.tsx (100%) rename src/components/{ => nav}/Sidebar.tsx (100%) rename src/components/{ => nav}/SidebarItems.tsx (97%) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 504ac436..4a14d4fb 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,7 +4,7 @@ import { Inter } from 'next/font/google'; import { headers } from 'next/headers'; import { TRPCReactProvider } from '@src/trpc/react'; -import Sidebar from '@src/components/Sidebar'; +import Sidebar from '@src/components/nav/Sidebar'; import { type Metadata } from 'next'; import { Analytics } from '@vercel/analytics/react'; diff --git a/src/components/BaseHeader.tsx b/src/components/BaseHeader.tsx index ac43c322..1d8e0c48 100644 --- a/src/components/BaseHeader.tsx +++ b/src/components/BaseHeader.tsx @@ -4,7 +4,7 @@ import { getServerAuthSession } from '@src/server/auth'; import { ClubSearchBar } from './searchBar/ClubSearchBar'; import { EventSearchBar } from './searchBar/EventSearchBar'; import SignInButton from './signInButton'; -import MobileNav from './MobileNav'; +import MobileNav from './nav/MobileNav'; import { api } from '@src/trpc/server'; export const BaseHeader = async ({ children }: { children: ReactNode }) => { diff --git a/src/components/MobileNav.tsx b/src/components/nav/MobileNav.tsx similarity index 100% rename from src/components/MobileNav.tsx rename to src/components/nav/MobileNav.tsx diff --git a/src/components/NavMenu.tsx b/src/components/nav/NavMenu.tsx similarity index 100% rename from src/components/NavMenu.tsx rename to src/components/nav/NavMenu.tsx diff --git a/src/components/Sidebar.tsx b/src/components/nav/Sidebar.tsx similarity index 100% rename from src/components/Sidebar.tsx rename to src/components/nav/Sidebar.tsx diff --git a/src/components/SidebarItems.tsx b/src/components/nav/SidebarItems.tsx similarity index 97% rename from src/components/SidebarItems.tsx rename to src/components/nav/SidebarItems.tsx index 1adaefda..fdf1cc89 100644 --- a/src/components/SidebarItems.tsx +++ b/src/components/nav/SidebarItems.tsx @@ -2,7 +2,7 @@ import { type FC, useState } from 'react'; import { useRouter, usePathname } from 'next/navigation'; import { IconMap, type allCats, routeMap } from '@src/constants/categories'; -import { RightChevron } from '../icons/Icons'; +import { RightChevron } from '../../icons/Icons'; const SidebarItems: FC<{ cat: allCats[number] }> = ({ cat }) => { const Icon = IconMap[cat]; From 07661b41feedd4d477847a72568604346cd63487 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 10:25:18 -0500 Subject: [PATCH 10/37] relocate ClubSelector --- src/components/{ => settings}/ClubSelector.tsx | 0 src/components/settings/FormCard.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/components/{ => settings}/ClubSelector.tsx (100%) diff --git a/src/components/ClubSelector.tsx b/src/components/settings/ClubSelector.tsx similarity index 100% rename from src/components/ClubSelector.tsx rename to src/components/settings/ClubSelector.tsx diff --git a/src/components/settings/FormCard.tsx b/src/components/settings/FormCard.tsx index 70749e16..c3744de1 100644 --- a/src/components/settings/FormCard.tsx +++ b/src/components/settings/FormCard.tsx @@ -7,7 +7,7 @@ import SettingsInput from './SettingsInput'; import { useForm } from 'react-hook-form'; import { z } from 'zod'; import { zodResolver } from '@hookform/resolvers/zod'; -import ClubSelector from '@src/components/ClubSelector'; +import ClubSelector from '@src/components/settings/ClubSelector'; import { api } from '@src/trpc/react'; import DeleteButton from './DeleteButton'; import { useRouter } from 'next/navigation'; From 1b34d4caf4d4dd965d77a495b9b179d4b9247596 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:01:26 -0500 Subject: [PATCH 11/37] relocate ProviderButtons since it's only used for sign in --- src/{components => app/auth}/ProviderButtons.tsx | 0 src/app/auth/page.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{components => app/auth}/ProviderButtons.tsx (100%) diff --git a/src/components/ProviderButtons.tsx b/src/app/auth/ProviderButtons.tsx similarity index 100% rename from src/components/ProviderButtons.tsx rename to src/app/auth/ProviderButtons.tsx diff --git a/src/app/auth/page.tsx b/src/app/auth/page.tsx index 72370832..02bdf246 100644 --- a/src/app/auth/page.tsx +++ b/src/app/auth/page.tsx @@ -1,4 +1,4 @@ -import ProviderButton from '@src/components/ProviderButtons'; +import ProviderButton from '@src/app/auth/ProviderButtons'; import { getServerAuthSession } from '@src/server/auth'; import { getProviders } from 'next-auth/react'; import { redirect } from 'next/navigation'; From bd87f3066f876f9187d4e12e161e735fc799f1f9 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:02:22 -0500 Subject: [PATCH 12/37] relocate directory components and rename DirectoryOrgs --- src/app/page.tsx | 4 ++-- src/components/{DirectoryOrgs.tsx => club/ClubCard.tsx} | 8 ++++---- .../{ => club/directory}/InfiniteScrollGrid.tsx | 6 +++--- src/components/{ => club/directory}/OrgDirectoryGrid.tsx | 4 ++-- src/components/{ => club/directory}/TagFilter.tsx | 0 src/components/{ => club/listing}/ContactButtons.tsx | 2 +- src/components/{ => club/listing}/OrgHeader.tsx | 0 src/components/{ => club/listing}/OrgInfoSegment.tsx | 0 src/components/{ => club/listing}/OrgUpcomingEvents.tsx | 0 9 files changed, 12 insertions(+), 12 deletions(-) rename src/components/{DirectoryOrgs.tsx => club/ClubCard.tsx} (91%) rename src/components/{ => club/directory}/InfiniteScrollGrid.tsx (92%) rename src/components/{ => club/directory}/OrgDirectoryGrid.tsx (90%) rename src/components/{ => club/directory}/TagFilter.tsx (100%) rename src/components/{ => club/listing}/ContactButtons.tsx (94%) rename src/components/{ => club/listing}/OrgHeader.tsx (100%) rename src/components/{ => club/listing}/OrgInfoSegment.tsx (100%) rename src/components/{ => club/listing}/OrgUpcomingEvents.tsx (100%) diff --git a/src/app/page.tsx b/src/app/page.tsx index 34978715..c482e4fc 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,7 @@ import Header from '../components/BaseHeader'; import Carousel from '../components/Carousel'; -import TagFilter from '../components/TagFilter'; -import OrgDirectoryGrid from '../components/OrgDirectoryGrid'; +import TagFilter from '../components/club/directory/TagFilter'; +import OrgDirectoryGrid from '../components/club/directory/OrgDirectoryGrid'; import type { Metadata } from 'next'; import { api } from '@src/trpc/server'; diff --git a/src/components/DirectoryOrgs.tsx b/src/components/club/ClubCard.tsx similarity index 91% rename from src/components/DirectoryOrgs.tsx rename to src/components/club/ClubCard.tsx index 882b0410..9624db0b 100644 --- a/src/components/DirectoryOrgs.tsx +++ b/src/components/club/ClubCard.tsx @@ -1,13 +1,13 @@ import { type FC } from 'react'; import Image from 'next/image'; import type { SelectClub as Club } from '@src/server/db/models'; -import JoinButton from './JoinButton'; +import JoinButton from '../JoinButton'; import Link from 'next/link'; import { type Session } from 'next-auth'; type Props = { club: Club; session: Session | null; priority: boolean }; -const OrgDirectoryCards: FC = ({ club, session, priority }) => { +const ClubCard: FC = ({ club, session, priority }) => { const desc = club.description.length > 50 ? club.description.slice(0, 150) + '...' @@ -45,7 +45,7 @@ const OrgDirectoryCards: FC = ({ club, session, priority }) => { ); }; -export const OrgDirectoryCardSkeleton: FC = () => { +export const ClubCardSkeleton: FC = () => { return (
@@ -59,4 +59,4 @@ export const OrgDirectoryCardSkeleton: FC = () => { ); }; -export default OrgDirectoryCards; +export default ClubCard; diff --git a/src/components/InfiniteScrollGrid.tsx b/src/components/club/directory/InfiniteScrollGrid.tsx similarity index 92% rename from src/components/InfiniteScrollGrid.tsx rename to src/components/club/directory/InfiniteScrollGrid.tsx index 2a3e6189..1be06703 100644 --- a/src/components/InfiniteScrollGrid.tsx +++ b/src/components/club/directory/InfiniteScrollGrid.tsx @@ -2,7 +2,7 @@ import { api } from '@src/trpc/react'; import { type Session } from 'next-auth'; import { useEffect, useRef } from 'react'; -import DirectoryOrgs, { OrgDirectoryCardSkeleton } from './DirectoryOrgs'; +import DirectoryOrgs, { ClubCardSkeleton } from '../ClubCard'; type Props = { session: Session | null; @@ -67,11 +67,11 @@ export default function InfiniteScrollGrid({ session, tag }: Props) { }), ) : Array.from({ length: 4 }, (_, index) => ( - + ))} {isFetchingNextPage && Array.from({ length: 4 }, (_, index) => ( - + ))} ); diff --git a/src/components/OrgDirectoryGrid.tsx b/src/components/club/directory/OrgDirectoryGrid.tsx similarity index 90% rename from src/components/OrgDirectoryGrid.tsx rename to src/components/club/directory/OrgDirectoryGrid.tsx index c3be3c13..cdb4d0af 100644 --- a/src/components/OrgDirectoryGrid.tsx +++ b/src/components/club/directory/OrgDirectoryGrid.tsx @@ -1,9 +1,9 @@ import { type FC } from 'react'; -import DirectoryOrgs from './DirectoryOrgs'; +import DirectoryOrgs from '../ClubCard'; import { api } from '@src/trpc/server'; import { getServerAuthSession } from '@src/server/auth'; import InfiniteScrollGrid from './InfiniteScrollGrid'; -import ScrollTop from './ScrollTop'; +import ScrollTop from '../../ScrollTop'; interface Props { tag?: string; diff --git a/src/components/TagFilter.tsx b/src/components/club/directory/TagFilter.tsx similarity index 100% rename from src/components/TagFilter.tsx rename to src/components/club/directory/TagFilter.tsx diff --git a/src/components/ContactButtons.tsx b/src/components/club/listing/ContactButtons.tsx similarity index 94% rename from src/components/ContactButtons.tsx rename to src/components/club/listing/ContactButtons.tsx index b961ca01..b526a45c 100644 --- a/src/components/ContactButtons.tsx +++ b/src/components/club/listing/ContactButtons.tsx @@ -1,5 +1,5 @@ import type { SelectContact as Contacts } from '@src/server/db/models'; -import { logo } from './ContactIcons'; +import { logo } from '../../ContactIcons'; import Link from 'next/link'; type contentButtonProps = { diff --git a/src/components/OrgHeader.tsx b/src/components/club/listing/OrgHeader.tsx similarity index 100% rename from src/components/OrgHeader.tsx rename to src/components/club/listing/OrgHeader.tsx diff --git a/src/components/OrgInfoSegment.tsx b/src/components/club/listing/OrgInfoSegment.tsx similarity index 100% rename from src/components/OrgInfoSegment.tsx rename to src/components/club/listing/OrgInfoSegment.tsx diff --git a/src/components/OrgUpcomingEvents.tsx b/src/components/club/listing/OrgUpcomingEvents.tsx similarity index 100% rename from src/components/OrgUpcomingEvents.tsx rename to src/components/club/listing/OrgUpcomingEvents.tsx From 0d00a1ea95a2ce56f0737c66d48e113ce1ff3584 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:15:23 -0500 Subject: [PATCH 13/37] colocate create club components --- .../directory/create}/CreateContactSelector.tsx | 2 +- src/{components => app/directory/create}/OfficerSelector.tsx | 2 +- src/app/directory/create/createForm.tsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/{components => app/directory/create}/CreateContactSelector.tsx (99%) rename src/{components => app/directory/create}/OfficerSelector.tsx (97%) diff --git a/src/components/CreateContactSelector.tsx b/src/app/directory/create/CreateContactSelector.tsx similarity index 99% rename from src/components/CreateContactSelector.tsx rename to src/app/directory/create/CreateContactSelector.tsx index cfd09ed7..5d5f7071 100644 --- a/src/components/CreateContactSelector.tsx +++ b/src/app/directory/create/CreateContactSelector.tsx @@ -16,7 +16,7 @@ import { Website, Youtube, type logoProps, -} from './ContactIcons'; +} from '@src/components/ContactIcons'; import { type Control, type UseFormRegister, diff --git a/src/components/OfficerSelector.tsx b/src/app/directory/create/OfficerSelector.tsx similarity index 97% rename from src/components/OfficerSelector.tsx rename to src/app/directory/create/OfficerSelector.tsx index b40a7e57..06b9ccf0 100644 --- a/src/components/OfficerSelector.tsx +++ b/src/app/directory/create/OfficerSelector.tsx @@ -7,7 +7,7 @@ import { type FieldErrors, } from 'react-hook-form'; import { type z } from 'zod'; -import { UserSearchBar } from './searchBar/UserSearchBar'; +import { UserSearchBar } from '../../../components/searchBar/UserSearchBar'; type OfficerSelectorProps = { control: Control>; diff --git a/src/app/directory/create/createForm.tsx b/src/app/directory/create/createForm.tsx index b9342196..e9c89543 100644 --- a/src/app/directory/create/createForm.tsx +++ b/src/app/directory/create/createForm.tsx @@ -1,8 +1,8 @@ 'use client'; /* eslint-disable @typescript-eslint/no-misused-promises */ import { zodResolver } from '@hookform/resolvers/zod'; -import ContactSelector from '@src/components/CreateContactSelector'; -import OfficerSelector from '@src/components/OfficerSelector'; +import ContactSelector from '@src/app/directory/create/CreateContactSelector'; +import OfficerSelector from '@src/app/directory/create/OfficerSelector'; import { api } from '@src/trpc/react'; import { createClubSchema } from '@src/utils/formSchemas'; import { useRouter } from 'next/navigation'; From ac93254a75185bbe5b3ae4c6a50ec6377761a73c Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:15:50 -0500 Subject: [PATCH 14/37] relocate JoinButton for ClubCard --- src/components/club/ClubCard.tsx | 2 +- src/components/{ => club}/JoinButton.tsx | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/components/{ => club}/JoinButton.tsx (100%) diff --git a/src/components/club/ClubCard.tsx b/src/components/club/ClubCard.tsx index 9624db0b..3fa4755f 100644 --- a/src/components/club/ClubCard.tsx +++ b/src/components/club/ClubCard.tsx @@ -1,7 +1,7 @@ import { type FC } from 'react'; import Image from 'next/image'; import type { SelectClub as Club } from '@src/server/db/models'; -import JoinButton from '../JoinButton'; +import JoinButton from './JoinButton'; import Link from 'next/link'; import { type Session } from 'next-auth'; diff --git a/src/components/JoinButton.tsx b/src/components/club/JoinButton.tsx similarity index 100% rename from src/components/JoinButton.tsx rename to src/components/club/JoinButton.tsx From c1cdb46fb1289abb013eb05eb066fb92cf22fe07 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:16:14 -0500 Subject: [PATCH 15/37] colocate RegisterButton for event page --- src/{components => app/event/[id]}/RegisterButton.tsx | 0 src/app/event/[id]/page.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{components => app/event/[id]}/RegisterButton.tsx (100%) diff --git a/src/components/RegisterButton.tsx b/src/app/event/[id]/RegisterButton.tsx similarity index 100% rename from src/components/RegisterButton.tsx rename to src/app/event/[id]/RegisterButton.tsx diff --git a/src/app/event/[id]/page.tsx b/src/app/event/[id]/page.tsx index 405c6452..87e9455e 100644 --- a/src/app/event/[id]/page.tsx +++ b/src/app/event/[id]/page.tsx @@ -8,7 +8,7 @@ import Image from 'next/image'; import CountdownTimer from './CountdownTimer'; import Link from 'next/link'; import { getServerAuthSession } from '@src/server/auth'; -import RegisterButton from '@src/components/RegisterButton'; +import RegisterButton from '@src/app/event/[id]/RegisterButton'; type Params = { params: { id: string } }; From a1d3016ba96a5cc0c4557ddfe294148ad9105620 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:19:30 -0500 Subject: [PATCH 16/37] relocate carousel and return to top with other directory components squash --- src/app/page.tsx | 2 +- src/components/{ => club/directory}/Carousel.tsx | 2 +- src/components/club/directory/OrgDirectoryGrid.tsx | 2 +- src/components/{ => club/directory}/ScrollTop.tsx | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/components/{ => club/directory}/Carousel.tsx (98%) rename src/components/{ => club/directory}/ScrollTop.tsx (100%) diff --git a/src/app/page.tsx b/src/app/page.tsx index c482e4fc..db3754f6 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,5 +1,5 @@ import Header from '../components/BaseHeader'; -import Carousel from '../components/Carousel'; +import Carousel from '../components/club/directory/Carousel'; import TagFilter from '../components/club/directory/TagFilter'; import OrgDirectoryGrid from '../components/club/directory/OrgDirectoryGrid'; import type { Metadata } from 'next'; diff --git a/src/components/Carousel.tsx b/src/components/club/directory/Carousel.tsx similarity index 98% rename from src/components/Carousel.tsx rename to src/components/club/directory/Carousel.tsx index 71e9c429..3edb1159 100644 --- a/src/components/Carousel.tsx +++ b/src/components/club/directory/Carousel.tsx @@ -1,7 +1,7 @@ 'use client'; import Image from 'next/image'; import { useState, type TouchEventHandler } from 'react'; -import { LeftArrowIcon, RightArrowIcon } from '../icons/Icons'; +import { LeftArrowIcon, RightArrowIcon } from '../../../icons/Icons'; import Link from 'next/link'; import { type SelectClub } from '@src/server/db/models'; diff --git a/src/components/club/directory/OrgDirectoryGrid.tsx b/src/components/club/directory/OrgDirectoryGrid.tsx index cdb4d0af..8a84de19 100644 --- a/src/components/club/directory/OrgDirectoryGrid.tsx +++ b/src/components/club/directory/OrgDirectoryGrid.tsx @@ -3,7 +3,7 @@ import DirectoryOrgs from '../ClubCard'; import { api } from '@src/trpc/server'; import { getServerAuthSession } from '@src/server/auth'; import InfiniteScrollGrid from './InfiniteScrollGrid'; -import ScrollTop from '../../ScrollTop'; +import ScrollTop from './ScrollTop'; interface Props { tag?: string; diff --git a/src/components/ScrollTop.tsx b/src/components/club/directory/ScrollTop.tsx similarity index 100% rename from src/components/ScrollTop.tsx rename to src/components/club/directory/ScrollTop.tsx From de580ead61f8c5920a5d3b87b78314abef4000fd Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:21:53 -0500 Subject: [PATCH 17/37] relocate contact editor with contact edit form --- src/app/manage/[clubId]/edit/EditContactForm.tsx | 2 +- .../manage/[clubId]/edit}/EditContactSelector.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/{components => app/manage/[clubId]/edit}/EditContactSelector.tsx (99%) diff --git a/src/app/manage/[clubId]/edit/EditContactForm.tsx b/src/app/manage/[clubId]/edit/EditContactForm.tsx index 87a7dade..1b8df4f4 100644 --- a/src/app/manage/[clubId]/edit/EditContactForm.tsx +++ b/src/app/manage/[clubId]/edit/EditContactForm.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-misused-promises */ 'use client'; import { zodResolver } from '@hookform/resolvers/zod'; -import EditContactSelector from '@src/components/EditContactSelector'; +import EditContactSelector from '@src/app/manage/[clubId]/edit/EditContactSelector'; import { type SelectClub, type SelectContact } from '@src/server/db/models'; import { api } from '@src/trpc/react'; import { editClubContactSchema } from '@src/utils/formSchemas'; diff --git a/src/components/EditContactSelector.tsx b/src/app/manage/[clubId]/edit/EditContactSelector.tsx similarity index 99% rename from src/components/EditContactSelector.tsx rename to src/app/manage/[clubId]/edit/EditContactSelector.tsx index 70583365..8bd2d1d4 100644 --- a/src/components/EditContactSelector.tsx +++ b/src/app/manage/[clubId]/edit/EditContactSelector.tsx @@ -23,7 +23,7 @@ import { Website, Youtube, type logoProps, -} from './ContactIcons'; +} from '@src/components/ContactIcons'; import { type modifyDeletedAction } from '@src/app/manage/[clubId]/edit/EditContactForm'; import { type editClubContactSchema } from '@src/utils/formSchemas'; From a5014a88d264f5b38b7a59ce671acd88de4d7939 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:28:53 -0500 Subject: [PATCH 18/37] relocate header components and back button fix back button imports --- src/app/about/page.tsx | 2 +- src/app/community/page.tsx | 2 +- src/app/directory/[id]/page.tsx | 2 +- src/app/directory/create/page.tsx | 2 +- src/app/event/[id]/page.tsx | 2 +- src/app/events/page.tsx | 2 +- src/app/feedback/page.tsx | 2 +- .../manage/[clubId]/(dashboard)/layout.tsx | 6 +-- src/app/manage/[clubId]/create/page.tsx | 54 ++++++++++--------- .../manage/[clubId]/edit/officers/page.tsx | 6 +-- src/app/manage/[clubId]/edit/page.tsx | 6 +-- src/app/manage/page.tsx | 2 +- src/app/page.tsx | 2 +- src/app/settings/page.tsx | 2 +- src/components/BlueBackButton.tsx | 20 ------- src/components/NotFound.tsx | 2 +- src/components/backButton.tsx | 16 ++++++ src/components/{ => header}/BaseHeader.tsx | 6 +-- .../{ => header}/ProfileDropDown.tsx | 0 src/components/{ => header}/signInButton.tsx | 0 20 files changed, 67 insertions(+), 69 deletions(-) delete mode 100644 src/components/BlueBackButton.tsx rename src/components/{ => header}/BaseHeader.tsx (88%) rename src/components/{ => header}/ProfileDropDown.tsx (100%) rename src/components/{ => header}/signInButton.tsx (100%) diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index 44259a53..2a0e1b80 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -1,4 +1,4 @@ -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import type { Metadata } from 'next'; export const metadata: Metadata = { diff --git a/src/app/community/page.tsx b/src/app/community/page.tsx index c3fb56cf..497350aa 100644 --- a/src/app/community/page.tsx +++ b/src/app/community/page.tsx @@ -1,4 +1,4 @@ -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import { getServerAuthSession } from '@src/server/auth'; import { type Metadata } from 'next'; import Image from 'next/image'; diff --git a/src/app/directory/[id]/page.tsx b/src/app/directory/[id]/page.tsx index 51de93ad..e42b484b 100644 --- a/src/app/directory/[id]/page.tsx +++ b/src/app/directory/[id]/page.tsx @@ -1,4 +1,4 @@ -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import OrgHeader from '@src/components/OrgHeader'; import OrgInfoSegment from '@src/components/OrgInfoSegment'; import OrgUpcomingEvents from '@src/components/OrgUpcomingEvents'; diff --git a/src/app/directory/create/page.tsx b/src/app/directory/create/page.tsx index da5b2791..819bc121 100644 --- a/src/app/directory/create/page.tsx +++ b/src/app/directory/create/page.tsx @@ -1,4 +1,4 @@ -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import CreateClubForm from './createForm'; import { getServerAuthSession } from '@src/server/auth'; import { redirect } from 'next/navigation'; diff --git a/src/app/event/[id]/page.tsx b/src/app/event/[id]/page.tsx index 87e9455e..9943eb68 100644 --- a/src/app/event/[id]/page.tsx +++ b/src/app/event/[id]/page.tsx @@ -1,4 +1,4 @@ -import { EventHeader } from '@src/components/BaseHeader'; +import { EventHeader } from '@src/components/header/BaseHeader'; import { db } from '@src/server/db'; import { and, eq } from 'drizzle-orm'; import { type Metadata } from 'next'; diff --git a/src/app/events/page.tsx b/src/app/events/page.tsx index 8036676e..79bc45dd 100644 --- a/src/app/events/page.tsx +++ b/src/app/events/page.tsx @@ -1,4 +1,4 @@ -import { EventHeader } from '@src/components/BaseHeader'; +import { EventHeader } from '@src/components/header/BaseHeader'; import { api } from '@src/trpc/server'; import EventView from './eventView'; import { type Metadata } from 'next'; diff --git a/src/app/feedback/page.tsx b/src/app/feedback/page.tsx index 38feaa5d..069ed2f9 100644 --- a/src/app/feedback/page.tsx +++ b/src/app/feedback/page.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import { type Metadata } from 'next'; import Form from '@src/app/feedback/Form'; diff --git a/src/app/manage/[clubId]/(dashboard)/layout.tsx b/src/app/manage/[clubId]/(dashboard)/layout.tsx index 6879ec2b..478e2375 100644 --- a/src/app/manage/[clubId]/(dashboard)/layout.tsx +++ b/src/app/manage/[clubId]/(dashboard)/layout.tsx @@ -1,5 +1,5 @@ -import Header from '@src/components/BaseHeader'; -import BackButton from '@src/components/BlueBackButton'; +import Header from '@src/components/header/BaseHeader'; +import { BlueBackButton } from '@src/components/backButton'; import { getServerAuthSession } from '@src/server/auth'; import { api } from '@src/trpc/server'; import { signInRoute } from '@src/utils/redirect'; @@ -30,7 +30,7 @@ const Layout = async ({
- +

{club.name}

diff --git a/src/app/manage/[clubId]/create/page.tsx b/src/app/manage/[clubId]/create/page.tsx index 95765a0e..03745126 100644 --- a/src/app/manage/[clubId]/create/page.tsx +++ b/src/app/manage/[clubId]/create/page.tsx @@ -1,30 +1,32 @@ -import Header from "@src/components/BaseHeader"; -import { getServerAuthSession } from "@src/server/auth"; -import { api } from "@src/trpc/server"; -import { signInRoute } from "@src/utils/redirect"; -import { redirect, notFound } from "next/navigation"; -import CreateEventForm from "./CreateEventForm"; +import Header from '@src/components/header/BaseHeader'; +import { getServerAuthSession } from '@src/server/auth'; +import { api } from '@src/trpc/server'; +import { signInRoute } from '@src/utils/redirect'; +import { redirect, notFound } from 'next/navigation'; +import CreateEventForm from './CreateEventForm'; const Page = async ({ params }: { params: { clubId: string } }) => { - const session = await getServerAuthSession(); - if (!session) { - redirect(signInRoute(`manage/${params.clubId}/create`)); - } + const session = await getServerAuthSession(); + if (!session) { + redirect(signInRoute(`manage/${params.clubId}/create`)); + } - const officerClubs = await api.club.getOfficerClubs(); - const currentClub = officerClubs.filter(val => { - return val.id == params.clubId - })[0]; - if (!currentClub) { - notFound(); - } + const officerClubs = await api.club.getOfficerClubs(); + const currentClub = officerClubs.filter((val) => { + return val.id == params.clubId; + })[0]; + if (!currentClub) { + notFound(); + } + + return ( +
+
+
+ +
+
+ ); +}; +export default Page; - return (
-
-
- -
- -
) -} -export default Page; \ No newline at end of file diff --git a/src/app/manage/[clubId]/edit/officers/page.tsx b/src/app/manage/[clubId]/edit/officers/page.tsx index 42718ded..df7955dd 100644 --- a/src/app/manage/[clubId]/edit/officers/page.tsx +++ b/src/app/manage/[clubId]/edit/officers/page.tsx @@ -1,5 +1,5 @@ -import Header from '@src/components/BaseHeader'; -import BackButton from '@src/components/BlueBackButton'; +import Header from '@src/components/header/BaseHeader'; +import { BlueBackButton } from '@src/components/backButton'; import EditOfficerForm from './EditOfficerForm'; import { api } from '@src/trpc/server'; import { getServerAuthSession } from '@src/server/auth'; @@ -28,7 +28,7 @@ export default async function Page({
- +

Edit club officers

diff --git a/src/app/manage/[clubId]/edit/page.tsx b/src/app/manage/[clubId]/edit/page.tsx index e52b7619..7ee9f734 100644 --- a/src/app/manage/[clubId]/edit/page.tsx +++ b/src/app/manage/[clubId]/edit/page.tsx @@ -1,9 +1,9 @@ import { api } from '@src/trpc/server'; import EditClubForm from './EditClubForm'; -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import { notFound } from 'next/navigation'; import EditContactForm from './EditContactForm'; -import BackButton from '@src/components/BlueBackButton'; +import { BlueBackButton } from '@src/components/backButton'; export default async function Page({ params: { clubId }, @@ -17,7 +17,7 @@ export default async function Page({
- +
diff --git a/src/app/manage/page.tsx b/src/app/manage/page.tsx index d0e33298..a52474d1 100644 --- a/src/app/manage/page.tsx +++ b/src/app/manage/page.tsx @@ -1,4 +1,4 @@ -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import { getServerAuthSession } from '@src/server/auth'; import { api } from '@src/trpc/server'; import ClubCard from './ClubCard'; diff --git a/src/app/page.tsx b/src/app/page.tsx index db3754f6..058b8025 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,4 +1,4 @@ -import Header from '../components/BaseHeader'; +import Header from '../components/header/BaseHeader'; import Carousel from '../components/club/directory/Carousel'; import TagFilter from '../components/club/directory/TagFilter'; import OrgDirectoryGrid from '../components/club/directory/OrgDirectoryGrid'; diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index 17ea96ba..b7e1eade 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -2,7 +2,7 @@ import { getServerAuthSession } from '@src/server/auth'; import SettingsForm from '@src/components/settings/SettingsForm'; import { type Metadata } from 'next'; import { redirect } from 'next/navigation'; -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import { signInRoute } from '@src/utils/redirect'; export const metadata: Metadata = { title: 'Settings - Jupiter', diff --git a/src/components/BlueBackButton.tsx b/src/components/BlueBackButton.tsx deleted file mode 100644 index c44be100..00000000 --- a/src/components/BlueBackButton.tsx +++ /dev/null @@ -1,20 +0,0 @@ -'use client'; - -import { useRouter } from 'next/navigation'; -import { LeftArrowIcon } from '../icons/Icons'; - -const BackButton = () => { - const router = useRouter(); - return ( -
- -
- ); -}; -export default BackButton; diff --git a/src/components/NotFound.tsx b/src/components/NotFound.tsx index 61041e98..4e93365f 100644 --- a/src/components/NotFound.tsx +++ b/src/components/NotFound.tsx @@ -1,4 +1,4 @@ -import Header from '@src/components/BaseHeader'; +import Header from '@src/components/header/BaseHeader'; import React from 'react'; import { type FC } from 'react'; diff --git a/src/components/backButton.tsx b/src/components/backButton.tsx index ff2c044c..483ea7ac 100644 --- a/src/components/backButton.tsx +++ b/src/components/backButton.tsx @@ -1,6 +1,7 @@ 'use client'; import { useRouter } from 'next/navigation'; +import { LeftArrowIcon } from '../icons/Icons'; const BackButton = () => { const router = useRouter(); @@ -29,4 +30,19 @@ const BackButton = () => {
); }; +export const BlueBackButton = () => { + const router = useRouter(); + return ( +
+ +
+ ); +}; + export default BackButton; diff --git a/src/components/BaseHeader.tsx b/src/components/header/BaseHeader.tsx similarity index 88% rename from src/components/BaseHeader.tsx rename to src/components/header/BaseHeader.tsx index 1d8e0c48..1a72a5f9 100644 --- a/src/components/BaseHeader.tsx +++ b/src/components/header/BaseHeader.tsx @@ -1,10 +1,10 @@ import type { ReactNode } from 'react'; import { ProfileDropDown } from './ProfileDropDown'; import { getServerAuthSession } from '@src/server/auth'; -import { ClubSearchBar } from './searchBar/ClubSearchBar'; -import { EventSearchBar } from './searchBar/EventSearchBar'; +import { ClubSearchBar } from '../searchBar/ClubSearchBar'; +import { EventSearchBar } from '../searchBar/EventSearchBar'; import SignInButton from './signInButton'; -import MobileNav from './nav/MobileNav'; +import MobileNav from '../nav/MobileNav'; import { api } from '@src/trpc/server'; export const BaseHeader = async ({ children }: { children: ReactNode }) => { diff --git a/src/components/ProfileDropDown.tsx b/src/components/header/ProfileDropDown.tsx similarity index 100% rename from src/components/ProfileDropDown.tsx rename to src/components/header/ProfileDropDown.tsx diff --git a/src/components/signInButton.tsx b/src/components/header/signInButton.tsx similarity index 100% rename from src/components/signInButton.tsx rename to src/components/header/signInButton.tsx From cc338dbb745bd9e301c414793359a47e0d006f15 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:31:57 -0500 Subject: [PATCH 19/37] move ContactIcons to icons folder --- src/app/directory/create/CreateContactSelector.tsx | 2 +- src/app/manage/[clubId]/edit/EditContactSelector.tsx | 2 +- src/components/club/listing/ContactButtons.tsx | 2 +- src/{components => icons}/ContactIcons.tsx | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/{components => icons}/ContactIcons.tsx (100%) diff --git a/src/app/directory/create/CreateContactSelector.tsx b/src/app/directory/create/CreateContactSelector.tsx index 5d5f7071..2d0735c5 100644 --- a/src/app/directory/create/CreateContactSelector.tsx +++ b/src/app/directory/create/CreateContactSelector.tsx @@ -16,7 +16,7 @@ import { Website, Youtube, type logoProps, -} from '@src/components/ContactIcons'; +} from '@src/icons/ContactIcons'; import { type Control, type UseFormRegister, diff --git a/src/app/manage/[clubId]/edit/EditContactSelector.tsx b/src/app/manage/[clubId]/edit/EditContactSelector.tsx index 8bd2d1d4..3e03c38b 100644 --- a/src/app/manage/[clubId]/edit/EditContactSelector.tsx +++ b/src/app/manage/[clubId]/edit/EditContactSelector.tsx @@ -23,7 +23,7 @@ import { Website, Youtube, type logoProps, -} from '@src/components/ContactIcons'; +} from '@src/icons/ContactIcons'; import { type modifyDeletedAction } from '@src/app/manage/[clubId]/edit/EditContactForm'; import { type editClubContactSchema } from '@src/utils/formSchemas'; diff --git a/src/components/club/listing/ContactButtons.tsx b/src/components/club/listing/ContactButtons.tsx index b526a45c..ea255f59 100644 --- a/src/components/club/listing/ContactButtons.tsx +++ b/src/components/club/listing/ContactButtons.tsx @@ -1,5 +1,5 @@ import type { SelectContact as Contacts } from '@src/server/db/models'; -import { logo } from '../../ContactIcons'; +import { logo } from '@src/icons/ContactIcons'; import Link from 'next/link'; type contentButtonProps = { diff --git a/src/components/ContactIcons.tsx b/src/icons/ContactIcons.tsx similarity index 100% rename from src/components/ContactIcons.tsx rename to src/icons/ContactIcons.tsx From 1a8928e92eab7c027d0df589558c0b78b07104f3 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 11:49:01 -0500 Subject: [PATCH 20/37] fix broken imports --- src/app/directory/[id]/page.tsx | 6 +++--- src/components/club/listing/OrgHeader.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/directory/[id]/page.tsx b/src/app/directory/[id]/page.tsx index e42b484b..cb03e51e 100644 --- a/src/app/directory/[id]/page.tsx +++ b/src/app/directory/[id]/page.tsx @@ -1,7 +1,7 @@ import Header from '@src/components/header/BaseHeader'; -import OrgHeader from '@src/components/OrgHeader'; -import OrgInfoSegment from '@src/components/OrgInfoSegment'; -import OrgUpcomingEvents from '@src/components/OrgUpcomingEvents'; +import OrgHeader from '@src/components/club/listing/OrgHeader'; +import OrgInfoSegment from '@src/components/club/listing/OrgInfoSegment'; +import OrgUpcomingEvents from '@src/components/club/listing/OrgUpcomingEvents'; import { api } from '@src/trpc/server'; import { db } from '@src/server/db'; import { eq } from 'drizzle-orm'; diff --git a/src/components/club/listing/OrgHeader.tsx b/src/components/club/listing/OrgHeader.tsx index 4b17dcb0..5dc99217 100644 --- a/src/components/club/listing/OrgHeader.tsx +++ b/src/components/club/listing/OrgHeader.tsx @@ -4,7 +4,7 @@ import type { SelectClub, SelectContact as Contacts, } from '@src/server/db/models'; -import JoinButton from './JoinButton'; +import JoinButton from '../JoinButton'; import { getServerAuthSession } from '@src/server/auth'; import Link from 'next/link'; import { api } from '@src/trpc/server'; From 06564901b17fe119d94529b0b1f889853d52e240 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 19:28:55 -0500 Subject: [PATCH 21/37] rename orgs to clubs in all locations --- src/app/admin/carousel/add/page.tsx | 6 +-- src/app/admin/{orgs => clubs}/[id]/page.tsx | 8 ++-- src/app/admin/{orgs => clubs}/page.tsx | 6 +-- src/app/admin/page.tsx | 4 +- src/app/directory/[id]/page.tsx | 16 +++---- src/app/directory/create/OfficerSelector.tsx | 2 +- src/app/page.tsx | 4 +- .../admin/{AddOrg.tsx => AddClub.tsx} | 42 +++++++++---------- src/components/admin/ApprovedClub.tsx | 23 ++++++++++ src/components/admin/ApprovedOrg.tsx | 23 ---------- src/components/admin/CarouselCards.tsx | 2 +- ...angeOrgStatus.tsx => ChangeClubStatus.tsx} | 12 +++--- ...OrgDescription.tsx => ClubDescription.tsx} | 2 +- .../admin/{OrgSearch.tsx => ClubSearch.tsx} | 6 +-- .../admin/{OrgTable.tsx => ClubTable.tsx} | 4 +- ...OtherOrgStatus.tsx => OtherClubStatus.tsx} | 14 +++---- ...irectoryGrid.tsx => ClubDirectoryGrid.tsx} | 8 ++-- .../club/directory/InfiniteScrollGrid.tsx | 16 +++---- .../listing/{OrgHeader.tsx => ClubHeader.tsx} | 4 +- ...OrgInfoSegment.tsx => ClubInfoSegment.tsx} | 4 +- ...omingEvents.tsx => ClubUpcomingEvents.tsx} | 4 +- src/server/api/routers/admin.ts | 20 ++++----- 22 files changed, 113 insertions(+), 117 deletions(-) rename src/app/admin/{orgs => clubs}/[id]/page.tsx (72%) rename src/app/admin/{orgs => clubs}/page.tsx (51%) rename src/components/admin/{AddOrg.tsx => AddClub.tsx} (72%) create mode 100644 src/components/admin/ApprovedClub.tsx delete mode 100644 src/components/admin/ApprovedOrg.tsx rename src/components/admin/{ChangeOrgStatus.tsx => ChangeClubStatus.tsx} (78%) rename src/components/admin/{OrgDescription.tsx => ClubDescription.tsx} (96%) rename src/components/admin/{OrgSearch.tsx => ClubSearch.tsx} (79%) rename src/components/admin/{OrgTable.tsx => ClubTable.tsx} (98%) rename src/components/admin/{OtherOrgStatus.tsx => OtherClubStatus.tsx} (78%) rename src/components/club/directory/{OrgDirectoryGrid.tsx => ClubDirectoryGrid.tsx} (75%) rename src/components/club/listing/{OrgHeader.tsx => ClubHeader.tsx} (96%) rename src/components/club/listing/{OrgInfoSegment.tsx => ClubInfoSegment.tsx} (98%) rename src/components/club/listing/{OrgUpcomingEvents.tsx => ClubUpcomingEvents.tsx} (93%) diff --git a/src/app/admin/carousel/add/page.tsx b/src/app/admin/carousel/add/page.tsx index f609d74c..3da1d6ea 100644 --- a/src/app/admin/carousel/add/page.tsx +++ b/src/app/admin/carousel/add/page.tsx @@ -1,12 +1,12 @@ -import AddOrg from '@src/components/admin/AddOrg'; +import AddClub from '@src/components/admin/AddClub'; export default function Page() { return (

- Add Orgs to Carousel + Add Clubs to Carousel

- +
); } diff --git a/src/app/admin/orgs/[id]/page.tsx b/src/app/admin/clubs/[id]/page.tsx similarity index 72% rename from src/app/admin/orgs/[id]/page.tsx rename to src/app/admin/clubs/[id]/page.tsx index f6bba3fc..06626949 100644 --- a/src/app/admin/orgs/[id]/page.tsx +++ b/src/app/admin/clubs/[id]/page.tsx @@ -1,5 +1,5 @@ -import ApprovedOrg from '@src/components/admin/ApprovedOrg'; -import OtherOrgStatus from '@src/components/admin/OtherOrgStatus'; +import ApprovedClub from '@src/components/admin/ApprovedClub'; +import OtherClubStatus from '@src/components/admin/OtherClubStatus'; import { db } from '@src/server/db'; import { eq } from 'drizzle-orm'; import { notFound } from 'next/navigation'; @@ -16,9 +16,9 @@ export default async function Page({ params: { id } }: Props) {

{org.name}

{org.approved === 'approved' ? ( - + ) : ( - + )}
); diff --git a/src/app/admin/orgs/page.tsx b/src/app/admin/clubs/page.tsx similarity index 51% rename from src/app/admin/orgs/page.tsx rename to src/app/admin/clubs/page.tsx index d2fc79b8..c6558454 100644 --- a/src/app/admin/orgs/page.tsx +++ b/src/app/admin/clubs/page.tsx @@ -1,11 +1,11 @@ -import OrgTable from '@src/components/admin/OrgTable'; +import ClubTable from '@src/components/admin/ClubTable'; import { api } from '@src/trpc/server'; export default async function Page() { - const clubs = await api.admin.allOrgs(); + const clubs = await api.admin.allClubs(); return (
- +
); } diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index ba693fa0..372a0741 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -8,10 +8,10 @@ export default function Page() {
- Manage Orgs + Manage Clubs { +const ClubPage = async ({ params }: { params: { id: string } }) => { const club = await api.club.getDirectoryInfo({ id: params.id }); if (!club) return ; @@ -16,15 +16,15 @@ const OrganizationPage = async ({ params }: { params: { id: string } }) => {
- - - + + +
); }; -export default OrganizationPage; +export default ClubPage; export async function generateMetadata({ params, diff --git a/src/app/directory/create/OfficerSelector.tsx b/src/app/directory/create/OfficerSelector.tsx index 06b9ccf0..05c07ef5 100644 --- a/src/app/directory/create/OfficerSelector.tsx +++ b/src/app/directory/create/OfficerSelector.tsx @@ -7,7 +7,7 @@ import { type FieldErrors, } from 'react-hook-form'; import { type z } from 'zod'; -import { UserSearchBar } from '../../../components/searchBar/UserSearchBar'; +import { UserSearchBar } from '@src/components/searchBar/UserSearchBar'; type OfficerSelectorProps = { control: Control>; diff --git a/src/app/page.tsx b/src/app/page.tsx index 058b8025..97531516 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,7 @@ import Header from '../components/header/BaseHeader'; import Carousel from '../components/club/directory/Carousel'; import TagFilter from '../components/club/directory/TagFilter'; -import OrgDirectoryGrid from '../components/club/directory/OrgDirectoryGrid'; +import ClubDirectoryGrid from '../components/club/directory/ClubDirectoryGrid'; import type { Metadata } from 'next'; import { api } from '@src/trpc/server'; @@ -33,7 +33,7 @@ const Home = async (props: Params) => {
- +
); diff --git a/src/components/admin/AddOrg.tsx b/src/components/admin/AddClub.tsx similarity index 72% rename from src/components/admin/AddOrg.tsx rename to src/components/admin/AddClub.tsx index 80429406..c287c40e 100644 --- a/src/components/admin/AddOrg.tsx +++ b/src/components/admin/AddClub.tsx @@ -2,26 +2,26 @@ import { useState } from 'react'; import { DayPicker, type DateRange } from 'react-day-picker'; -import OrgSearch from './OrgSearch'; +import ClubSearch from './ClubSearch'; import 'react-day-picker/dist/style.css'; import { api } from '@src/trpc/react'; import { useRouter } from 'next/navigation'; -type AddOrg = { +type AddClub = { range: DateRange; orgId: string | null; name: string | null; }; -export default function AddOrg() { - const [addOrg, setAddOrg] = useState({ +export default function AddClub() { + const [addClub, setAddClub] = useState({ range: { from: undefined, to: undefined }, orgId: null, name: null, }); const router = useRouter(); const utils = api.useContext(); - const { mutate } = api.admin.addOrgCarousel.useMutation({ + const { mutate } = api.admin.addClubCarousel.useMutation({ onSuccess: async () => { await utils.admin.upcomingCarousels.invalidate(); await utils.club.getCarousel.invalidate(); @@ -32,21 +32,21 @@ export default function AddOrg() { }); function onClick() { - if (!addOrg.orgId || !addOrg.range.from || !addOrg.range.to) return; + if (!addClub.orgId || !addClub.range.from || !addClub.range.to) return; mutate({ - orgId: addOrg.orgId, - range: addOrg.range, + orgId: addClub.orgId, + range: addClub.range, }); } - function setOrg({ id, name }: { id: string; name: string }) { - setAddOrg({ ...addOrg, orgId: id, name }); + function setClub({ id, name }: { id: string; name: string }) { + setAddClub({ ...addClub, orgId: id, name }); } function setRange(range: DateRange | undefined) { - setAddOrg({ - ...addOrg, + setAddClub({ + ...addClub, range: { from: range?.from ? range.from : undefined, to: range?.to ? range.to : undefined, @@ -58,18 +58,18 @@ export default function AddOrg() {
- - {addOrg.name && ( + + {addClub.name && (
- Adding {addOrg.name} + Adding {addClub.name}
)} - {addOrg.range.from && addOrg.range.to && ( + {addClub.range.from && addClub.range.to && (
From: - {addOrg.range.from.toLocaleDateString(undefined, { + {addClub.range.from.toLocaleDateString(undefined, { dateStyle: 'long', })} @@ -77,7 +77,7 @@ export default function AddOrg() {
To: - {addOrg.range.to.toLocaleDateString(undefined, { + {addClub.range.to.toLocaleDateString(undefined, { dateStyle: 'long', })} @@ -87,7 +87,7 @@ export default function AddOrg() {
- Add Org + Add Club
); diff --git a/src/components/admin/ApprovedClub.tsx b/src/components/admin/ApprovedClub.tsx new file mode 100644 index 00000000..b9a99aca --- /dev/null +++ b/src/components/admin/ApprovedClub.tsx @@ -0,0 +1,23 @@ +import { type SelectClub } from '@src/server/db/models'; +import AddOfficer from './AddOfficer'; +import OfficerTable from './OfficerTable'; +import ClubDescription from './ClubDescription'; +import { api } from '@src/trpc/server'; +import ChangeClubStatus from './ChangeClubStatus'; + +type Props = { club: SelectClub }; +export default async function AcceptedClub({ club: club }: Props) { + const officers = await api.club.getOfficers({ id: club.id }); + + return ( + <> +

Officers

+
+ + +
+ + + + ); +} diff --git a/src/components/admin/ApprovedOrg.tsx b/src/components/admin/ApprovedOrg.tsx deleted file mode 100644 index e4592d52..00000000 --- a/src/components/admin/ApprovedOrg.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { type SelectClub } from '@src/server/db/models'; -import AddOfficer from './AddOfficer'; -import OfficerTable from './OfficerTable'; -import OrgDescription from './OrgDescription'; -import { api } from '@src/trpc/server'; -import ChangeOrgStatus from './ChangeOrgStatus'; - -type Props = { org: SelectClub }; -export default async function AcceptedOrg({ org }: Props) { - const officers = await api.club.getOfficers({ id: org.id }); - - return ( - <> -

Officers

-
- - -
- - - - ); -} diff --git a/src/components/admin/CarouselCards.tsx b/src/components/admin/CarouselCards.tsx index af851e05..061b34a3 100644 --- a/src/components/admin/CarouselCards.tsx +++ b/src/components/admin/CarouselCards.tsx @@ -11,7 +11,7 @@ type Props = { export default function CarouselCard({ item }: Props) { const router = useRouter(); - const { mutate } = api.admin.removeOrgCarousel.useMutation({ + const { mutate } = api.admin.removeClubCarousel.useMutation({ onSuccess: () => router.refresh(), }); return ( diff --git a/src/components/admin/ChangeOrgStatus.tsx b/src/components/admin/ChangeClubStatus.tsx similarity index 78% rename from src/components/admin/ChangeOrgStatus.tsx rename to src/components/admin/ChangeClubStatus.tsx index 878e6cda..f79ee174 100644 --- a/src/components/admin/ChangeOrgStatus.tsx +++ b/src/components/admin/ChangeClubStatus.tsx @@ -4,27 +4,27 @@ import { api } from '@src/trpc/react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; -type Props = { status: 'approved' | 'pending' | 'rejected'; orgId: string }; +type Props = { status: 'approved' | 'pending' | 'rejected'; clubId: string }; -export default function ChangeOrgStatus({ status: initial, orgId }: Props) { +export default function ChangeClubStatus({ status: initial, clubId }: Props) { const router = useRouter(); const [status, setStatus] = useState(initial); - const { mutate } = api.admin.changeOrgStatus.useMutation({ + const { mutate } = api.admin.changeClubStatus.useMutation({ onSuccess: () => router.refresh(), }); function onChange(e: React.ChangeEvent) { switch (e.target.value) { case 'approved': - mutate({ orgId, status: 'approved' }); + mutate({ clubId: clubId, status: 'approved' }); setStatus('approved'); break; case 'pending': - mutate({ orgId, status: 'pending' }); + mutate({ clubId: clubId, status: 'pending' }); setStatus('pending'); break; case 'rejected': - mutate({ orgId, status: 'rejected' }); + mutate({ clubId: clubId, status: 'rejected' }); setStatus('rejected'); break; } diff --git a/src/components/admin/OrgDescription.tsx b/src/components/admin/ClubDescription.tsx similarity index 96% rename from src/components/admin/OrgDescription.tsx rename to src/components/admin/ClubDescription.tsx index b9b7900b..aec25d82 100644 --- a/src/components/admin/OrgDescription.tsx +++ b/src/components/admin/ClubDescription.tsx @@ -6,7 +6,7 @@ import { type SelectClub } from '@src/server/db/models'; type Props = { club: SelectClub; }; -export default function OrgDescription({ club }: Props) { +export default function ClubDescription({ club }: Props) { return ( diff --git a/src/components/admin/OrgSearch.tsx b/src/components/admin/ClubSearch.tsx similarity index 79% rename from src/components/admin/OrgSearch.tsx rename to src/components/admin/ClubSearch.tsx index 9caf805d..0c14d02d 100644 --- a/src/components/admin/OrgSearch.tsx +++ b/src/components/admin/ClubSearch.tsx @@ -6,10 +6,10 @@ import { DebouncedSearchBar } from '../searchBar/DebouncedSearchBar'; import { type SelectClub } from '@src/server/db/models'; type Props = { - setOrg: ({ id, name }: { id: string; name: string }) => void; + setClub: ({ id, name }: { id: string; name: string }) => void; }; -export default function OrgSearch({ setOrg }: Props) { +export default function ClubSearch({ setClub }: Props) { const [search, setSearch] = useState(''); const { data } = api.club.byName.useQuery( { name: search }, @@ -17,7 +17,7 @@ export default function OrgSearch({ setOrg }: Props) { ); const onClickSearchResult = (club: SelectClub) => { - setOrg({ id: club.id, name: club.name }); + setClub({ id: club.id, name: club.name }); setSearch(''); }; return ( diff --git a/src/components/admin/OrgTable.tsx b/src/components/admin/ClubTable.tsx similarity index 98% rename from src/components/admin/OrgTable.tsx rename to src/components/admin/ClubTable.tsx index c94fd9e7..8123e162 100644 --- a/src/components/admin/OrgTable.tsx +++ b/src/components/admin/ClubTable.tsx @@ -18,11 +18,11 @@ import { useRouter } from 'next/navigation'; import { type Club, fuzzyFilter } from '@src/utils/table'; import StatusFilter from './StatusFilter'; -export default function OrgTable({ clubs }: { clubs: Club[] }) { +export default function ClubTable({ clubs }: { clubs: Club[] }) { const router = useRouter(); const parentRef = useRef(null); const [columnFilters, setColumnFilters] = useState([]); - const { mutate } = api.admin.deleteOrg.useMutation({ + const { mutate } = api.admin.deleteClub.useMutation({ onSuccess: () => router.refresh(), }); diff --git a/src/components/admin/OtherOrgStatus.tsx b/src/components/admin/OtherClubStatus.tsx similarity index 78% rename from src/components/admin/OtherOrgStatus.tsx rename to src/components/admin/OtherClubStatus.tsx index f62c8e5f..cc4ecd59 100644 --- a/src/components/admin/OtherOrgStatus.tsx +++ b/src/components/admin/OtherClubStatus.tsx @@ -1,14 +1,14 @@ import { db } from '@src/server/db'; import { type SelectClub } from '@src/server/db/models'; import { and, eq } from 'drizzle-orm'; -import ChangeOrgStatus from './ChangeOrgStatus'; +import ChangeClubStatus from './ChangeClubStatus'; -type Props = { org: SelectClub }; +type Props = { club: SelectClub }; -export default async function PendingOrg({ org }: Props) { +export default async function PendingClub({ club }: Props) { const president = await db.query.userMetadataToClubs.findFirst({ where: (umtc) => - and(eq(umtc.clubId, org.id), eq(umtc.memberType, 'President')), + and(eq(umtc.clubId, club.id), eq(umtc.memberType, 'President')), with: { userMetadata: true }, }); @@ -18,7 +18,7 @@ export default async function PendingOrg({ org }: Props) { return (
- {org.description.split('\n').map((line, i) => ( + {club.description.split('\n').map((line, i) => (

{line}

@@ -26,7 +26,7 @@ export default async function PendingOrg({ org }: Props) {
Tags: - {org.tags.map((tag) => ( + {club.tags.map((tag) => (
- +
); } diff --git a/src/components/club/directory/OrgDirectoryGrid.tsx b/src/components/club/directory/ClubDirectoryGrid.tsx similarity index 75% rename from src/components/club/directory/OrgDirectoryGrid.tsx rename to src/components/club/directory/ClubDirectoryGrid.tsx index 8a84de19..8c6a99ab 100644 --- a/src/components/club/directory/OrgDirectoryGrid.tsx +++ b/src/components/club/directory/ClubDirectoryGrid.tsx @@ -1,5 +1,5 @@ import { type FC } from 'react'; -import DirectoryOrgs from '../ClubCard'; +import ClubCard from '../ClubCard'; import { api } from '@src/trpc/server'; import { getServerAuthSession } from '@src/server/auth'; import InfiniteScrollGrid from './InfiniteScrollGrid'; @@ -9,14 +9,14 @@ interface Props { tag?: string; } -const OrgDirectoryGrid: FC = async ({ tag }) => { +const ClubDirectoryGrid: FC = async ({ tag }) => { const { clubs } = await api.club.all({ tag, limit: 9 }); const session = await getServerAuthSession(); return (
{clubs.map((club) => ( - + ))} {clubs.length === 9 && } @@ -24,4 +24,4 @@ const OrgDirectoryGrid: FC = async ({ tag }) => { ); }; -export default OrgDirectoryGrid; +export default ClubDirectoryGrid; diff --git a/src/components/club/directory/InfiniteScrollGrid.tsx b/src/components/club/directory/InfiniteScrollGrid.tsx index 1be06703..259ab9b8 100644 --- a/src/components/club/directory/InfiniteScrollGrid.tsx +++ b/src/components/club/directory/InfiniteScrollGrid.tsx @@ -2,7 +2,7 @@ import { api } from '@src/trpc/react'; import { type Session } from 'next-auth'; import { useEffect, useRef } from 'react'; -import DirectoryOrgs, { ClubCardSkeleton } from '../ClubCard'; +import ClubCard, { ClubCardSkeleton } from '../ClubCard'; type Props = { session: Session | null; @@ -21,7 +21,7 @@ export default function InfiniteScrollGrid({ session, tag }: Props) { ); const observer = useRef(); - const lastOrgElementRef = useRef(null); + const lastClubElementRef = useRef(null); useEffect(() => { if (isLoading || isFetchingNextPage) return; @@ -35,8 +35,8 @@ export default function InfiniteScrollGrid({ session, tag }: Props) { } }); - if (lastOrgElementRef.current) { - observer.current.observe(lastOrgElementRef.current); + if (lastClubElementRef.current) { + observer.current.observe(lastClubElementRef.current); } return () => { @@ -54,14 +54,10 @@ export default function InfiniteScrollGrid({ session, tag }: Props) { clubIndex === page.clubs.length - 1; return (
- +
); }), diff --git a/src/components/club/listing/OrgHeader.tsx b/src/components/club/listing/ClubHeader.tsx similarity index 96% rename from src/components/club/listing/OrgHeader.tsx rename to src/components/club/listing/ClubHeader.tsx index 5dc99217..fcbb26dc 100644 --- a/src/components/club/listing/OrgHeader.tsx +++ b/src/components/club/listing/ClubHeader.tsx @@ -13,7 +13,7 @@ type Club = SelectClub & { contacts?: Contacts[]; tags: string[]; }; -const OrgHeader = async ({ club }: { club: Club }) => { +const ClubHeader = async ({ club }: { club: Club }) => { const session = await getServerAuthSession(); const memberType = await api.club.memberType({ id: club.id }); return ( @@ -83,4 +83,4 @@ const OrgHeader = async ({ club }: { club: Club }) => { ); }; -export default OrgHeader; +export default ClubHeader; diff --git a/src/components/club/listing/OrgInfoSegment.tsx b/src/components/club/listing/ClubInfoSegment.tsx similarity index 98% rename from src/components/club/listing/OrgInfoSegment.tsx rename to src/components/club/listing/ClubInfoSegment.tsx index 2e2e3b9a..d1fe1fc7 100644 --- a/src/components/club/listing/OrgInfoSegment.tsx +++ b/src/components/club/listing/ClubInfoSegment.tsx @@ -3,7 +3,7 @@ import { type FC } from 'react'; import { type RouterOutputs } from '@src/trpc/shared'; import { api } from '@src/trpc/server'; -const OrgInfoSegment: FC<{ +const ClubInfoSegment: FC<{ club: NonNullable; }> = async ({ club }) => { const isActive = await api.club.isActive({ id: club.id }); @@ -87,4 +87,4 @@ const OrgInfoSegment: FC<{ ); }; -export default OrgInfoSegment; +export default ClubInfoSegment; diff --git a/src/components/club/listing/OrgUpcomingEvents.tsx b/src/components/club/listing/ClubUpcomingEvents.tsx similarity index 93% rename from src/components/club/listing/OrgUpcomingEvents.tsx rename to src/components/club/listing/ClubUpcomingEvents.tsx index 9232c1a3..7672f8a8 100644 --- a/src/components/club/listing/OrgUpcomingEvents.tsx +++ b/src/components/club/listing/ClubUpcomingEvents.tsx @@ -4,7 +4,7 @@ import { type FC } from 'react'; const MAX_DESCRIPTION_LENGTH = 150; -const OrgUpcomingEvents: FC<{ clubId: string }> = async ({ clubId }) => { +const ClubUpcomingEvents: FC<{ clubId: string }> = async ({ clubId }) => { const cur_time = new Date(); const data = await api.event.byClubId({ @@ -51,4 +51,4 @@ const OrgUpcomingEvents: FC<{ clubId: string }> = async ({ clubId }) => { ); }; -export default OrgUpcomingEvents; +export default ClubUpcomingEvents; diff --git a/src/server/api/routers/admin.ts b/src/server/api/routers/admin.ts index 2e398bad..86eac7b1 100644 --- a/src/server/api/routers/admin.ts +++ b/src/server/api/routers/admin.ts @@ -25,13 +25,13 @@ const carouselSchema = z.object({ range: z.custom((val) => isDateRange(val)), }); -const changeOrgStatusSchema = z.object({ - orgId: z.string(), +const changeClubStatusSchema = z.object({ + clubId: z.string(), status: z.enum(['approved', 'pending', 'rejected']), }); export const adminRouter = createTRPCRouter({ - allOrgs: adminProcedure.query(async ({ ctx }) => { + allClubs: adminProcedure.query(async ({ ctx }) => { const orgs = await ctx.db.query.club.findMany({ columns: { id: true, @@ -44,7 +44,7 @@ export const adminRouter = createTRPCRouter({ }); return orgs; }), - deleteOrg: adminProcedure + deleteClub: adminProcedure .input(deleteSchema) .mutation(async ({ ctx, input }) => { await ctx.db.delete(club).where(eq(club.id, input.id)); @@ -103,13 +103,13 @@ export const adminRouter = createTRPCRouter({ return carousels; }), - addOrgCarousel: adminProcedure + addClubCarousel: adminProcedure .input(carouselSchema) .mutation(async ({ ctx, input }) => { if (!input.range.from || !input.range.to) throw new Error('Invalid date range'); - // Check if there is already a carousel for this org + // Check if there is already a carousel for this club const exists = await ctx.db.query.carousel.findFirst({ where: (carousel) => eq(carousel.orgId, input.orgId), }); @@ -130,17 +130,17 @@ export const adminRouter = createTRPCRouter({ endTime: input.range.to, }); }), - removeOrgCarousel: adminProcedure + removeClubCarousel: adminProcedure .input(deleteSchema) .mutation(async ({ ctx, input }) => { await ctx.db.delete(carousel).where(eq(carousel.orgId, input.id)); }), - changeOrgStatus: adminProcedure - .input(changeOrgStatusSchema) + changeClubStatus: adminProcedure + .input(changeClubStatusSchema) .mutation(async ({ ctx, input }) => { await ctx.db .update(club) .set({ approved: input.status }) - .where(eq(club.id, input.orgId)); + .where(eq(club.id, input.clubId)); }), }); From a46cb7a862d8ec357e99d32b78a4987f94c2fbe1 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Mon, 30 Sep 2024 19:30:58 -0500 Subject: [PATCH 22/37] fix relative icon imports --- src/components/club/directory/Carousel.tsx | 2 +- src/components/events/EventCard.tsx | 2 +- src/components/events/EventLikeButton.tsx | 2 +- src/components/nav/SidebarItems.tsx | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/club/directory/Carousel.tsx b/src/components/club/directory/Carousel.tsx index 3edb1159..74a04aff 100644 --- a/src/components/club/directory/Carousel.tsx +++ b/src/components/club/directory/Carousel.tsx @@ -1,7 +1,7 @@ 'use client'; import Image from 'next/image'; import { useState, type TouchEventHandler } from 'react'; -import { LeftArrowIcon, RightArrowIcon } from '../../../icons/Icons'; +import { LeftArrowIcon, RightArrowIcon } from '@src/icons/Icons'; import Link from 'next/link'; import { type SelectClub } from '@src/server/db/models'; diff --git a/src/components/events/EventCard.tsx b/src/components/events/EventCard.tsx index 091256fa..1eb41bc5 100644 --- a/src/components/events/EventCard.tsx +++ b/src/components/events/EventCard.tsx @@ -2,7 +2,7 @@ import { format, isSameDay } from 'date-fns'; import Image from 'next/image'; import Link from 'next/link'; -import { MoreIcon } from '../../icons/Icons'; +import { MoreIcon } from '@src/icons/Icons'; import { type RouterOutputs } from '@src/trpc/shared'; import EventLikeButton from './EventLikeButton'; import { getServerAuthSession } from '@src/server/auth'; diff --git a/src/components/events/EventLikeButton.tsx b/src/components/events/EventLikeButton.tsx index a22b05a4..5257e59d 100644 --- a/src/components/events/EventLikeButton.tsx +++ b/src/components/events/EventLikeButton.tsx @@ -1,6 +1,6 @@ 'use client'; /* eslint-disable @typescript-eslint/no-misused-promises */ -import { CheckIcon, PlusIcon } from '../../icons/Icons'; +import { CheckIcon, PlusIcon } from '@src/icons/Icons'; import { api } from '@src/trpc/react'; import { useRouter } from 'next/navigation'; diff --git a/src/components/nav/SidebarItems.tsx b/src/components/nav/SidebarItems.tsx index fdf1cc89..d13c5cdb 100644 --- a/src/components/nav/SidebarItems.tsx +++ b/src/components/nav/SidebarItems.tsx @@ -2,7 +2,7 @@ import { type FC, useState } from 'react'; import { useRouter, usePathname } from 'next/navigation'; import { IconMap, type allCats, routeMap } from '@src/constants/categories'; -import { RightChevron } from '../../icons/Icons'; +import { RightChevron } from '@src/icons/Icons'; const SidebarItems: FC<{ cat: allCats[number] }> = ({ cat }) => { const Icon = IconMap[cat]; From 3a422c11163fe13b74ae2c6ef23a1bcd9801625f Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Tue, 1 Oct 2024 14:45:23 -0500 Subject: [PATCH 23/37] add submit functionality to search bar --- .../searchBar/DebouncedSearchBar.tsx | 6 +++ src/components/searchBar/index.tsx | 37 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/components/searchBar/DebouncedSearchBar.tsx b/src/components/searchBar/DebouncedSearchBar.tsx index 395f898c..1fe89774 100644 --- a/src/components/searchBar/DebouncedSearchBar.tsx +++ b/src/components/searchBar/DebouncedSearchBar.tsx @@ -18,6 +18,8 @@ export type DebouncedSearchBarProps = { setSearch: Dispatch>; searchResults?: Array; onClick?: (input: T) => void; + submitButton?: boolean; + submitLogic?: () => void; }; export const DebouncedSearchBar = ({ placeholder, @@ -25,6 +27,8 @@ export const DebouncedSearchBar = ({ setSearch, searchResults, onClick, + submitButton, + submitLogic, }: DebouncedSearchBarProps) => { const [input, setInput] = useState(value ?? ''); const [focused, setFocused] = useState(false); @@ -48,6 +52,8 @@ export const DebouncedSearchBar = ({ onChange={handleSearch} onFocus={() => setFocused(true)} onBlur={() => setTimeout(() => setFocused(false), 300)} + submitButton={submitButton} + submitLogic={submitLogic} /> {input && focused && searchResults && searchResults.length > 0 && (
diff --git a/src/components/searchBar/index.tsx b/src/components/searchBar/index.tsx index 2fbe4389..cd90c59f 100644 --- a/src/components/searchBar/index.tsx +++ b/src/components/searchBar/index.tsx @@ -1,9 +1,14 @@ -import { SearchIcon } from '@src/icons/Icons'; -import { ComponentProps } from 'react'; +import { RightArrowIcon, SearchIcon } from '@src/icons/Icons'; +import { type ComponentProps } from 'react'; -type SearchBarProps = Omit, 'type'>; +type SearchBarProps = Omit, 'type'> & { + submitButton?: boolean; + submitLogic?: () => void; +}; export const SearchBar = (props: SearchBarProps) => { + const submitButton = props.submitButton; + const submitLogic = props.submitLogic; return (
@@ -12,8 +17,32 @@ export const SearchBar = (props: SearchBarProps) => { { + console.log('howdy from submit'); + }} + onKeyDown={(e) => { + if (e.key === 'Enter' && submitLogic) { + submitLogic(); + } + }} /> + {submitButton && ( + + )}
); }; From ea1284e41366750ec8a365a09de38885ca8fe63b Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Tue, 1 Oct 2024 16:13:33 -0500 Subject: [PATCH 24/37] implement submits to current searchbars --- src/components/searchBar/ClubSearchBar.tsx | 6 +++++ .../searchBar/EventClubSearchBar.tsx | 27 ++++++++++--------- src/components/searchBar/EventSearchBar.tsx | 22 ++++++++------- src/components/searchBar/UserSearchBar.tsx | 27 +++++++++---------- 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/components/searchBar/ClubSearchBar.tsx b/src/components/searchBar/ClubSearchBar.tsx index 7523c719..6e2ffa8d 100644 --- a/src/components/searchBar/ClubSearchBar.tsx +++ b/src/components/searchBar/ClubSearchBar.tsx @@ -21,6 +21,12 @@ export const ClubSearchBar = () => { setSearch={setSearch} searchResults={data || []} onClick={onClickSearchResult} + submitButton + submitLogic={() => { + if (data && data[0]) { + onClickSearchResult(data[0]); + } + }} /> ); }; diff --git a/src/components/searchBar/EventClubSearchBar.tsx b/src/components/searchBar/EventClubSearchBar.tsx index afce98f5..0c65a28f 100644 --- a/src/components/searchBar/EventClubSearchBar.tsx +++ b/src/components/searchBar/EventClubSearchBar.tsx @@ -1,5 +1,5 @@ 'use client'; -import { useState, useEffect } from 'react'; +import { useState } from 'react'; import type { SelectClub as Club } from '@src/server/db/models'; import { api } from '@src/trpc/react'; import { DebouncedSearchBar } from './DebouncedSearchBar'; @@ -9,29 +9,30 @@ type EventClubSearchBarProps = { }; export const EventClubSearchBar = ({ addClub }: EventClubSearchBarProps) => { const [search, setSearch] = useState(''); - const [res, setRes] = useState([]); const utils = api.useUtils(); - const clubQuery = api.club.byName.useQuery( + const { data } = api.club.byName.useQuery( { name: search }, { enabled: !!search, }, ); - useEffect(() => { - if (clubQuery.data) { - setRes(clubQuery.data); - } - }, [clubQuery.data]); + const submit = (club: Club) => { + void utils.club.byId.prefetch({ id: club.id }); + addClub(club.id); + setSearch(''); + }; return ( { - void utils.club.byId.prefetch({ id: club.id }); - addClub(club.id); - setSearch(''); + searchResults={data || []} + onClick={submit} + submitButton + submitLogic={() => { + if (data && data[0]) { + submit(data[0]); + } }} /> ); diff --git a/src/components/searchBar/EventSearchBar.tsx b/src/components/searchBar/EventSearchBar.tsx index 04adb555..7e32cd98 100644 --- a/src/components/searchBar/EventSearchBar.tsx +++ b/src/components/searchBar/EventSearchBar.tsx @@ -1,5 +1,5 @@ 'use client'; -import { useState, useEffect } from 'react'; +import { useState } from 'react'; import { useRouter } from 'next/navigation'; import { api } from '@src/trpc/react'; import type { SelectEvent as Event } from '@src/server/db/models'; @@ -8,26 +8,28 @@ import { DebouncedSearchBar } from './DebouncedSearchBar'; export const EventSearchBar = () => { const router = useRouter(); const [search, setSearch] = useState(''); - const [res, setRes] = useState([]); - const eventQuery = api.event.byName.useQuery( + const { data } = api.event.byName.useQuery( { name: search, sortByDate: true, }, { enabled: !!search }, ); - useEffect(() => { - if (eventQuery.data) setRes(eventQuery.data); - }, [eventQuery.data]); - + const onClickSearchResult = (event: Event) => { + router.push(`/event/${event.id}`); + }; return ( { - router.push(`/event/${event.id}`); + searchResults={data || []} + onClick={onClickSearchResult} + submitButton + submitLogic={() => { + if (data && data[0]) { + onClickSearchResult(data[0]); + } }} /> ); diff --git a/src/components/searchBar/UserSearchBar.tsx b/src/components/searchBar/UserSearchBar.tsx index 487d4f40..94fad809 100644 --- a/src/components/searchBar/UserSearchBar.tsx +++ b/src/components/searchBar/UserSearchBar.tsx @@ -1,42 +1,41 @@ 'use client'; -import { type SelectUserMetadata } from '@src/server/db/models'; import { api } from '@src/trpc/react'; -import { useState, useEffect } from 'react'; +import { useState } from 'react'; import { DebouncedSearchBar } from './DebouncedSearchBar'; type UserSearchBarProps = { passUser: (user: { id: string; name: string }) => void; }; -type User = { - name: string; -} & SelectUserMetadata; export const UserSearchBar = ({ passUser }: UserSearchBarProps) => { const [search, setSearch] = useState(''); - const [res, setRes] = useState([]); const userQuery = api.userMetadata.searchByName.useQuery( { name: search }, { enabled: !!search, }, ); - useEffect(() => { - if (userQuery.data) { - const newData = userQuery.data.map((val) => { + const formattedData = userQuery.isSuccess + ? userQuery.data.map((val) => { return { name: val.firstName + ' ' + val.lastName, ...val }; - }); - setRes(newData); - } - }, [userQuery.data]); + }) + : []; return ( { passUser({ id: user.id, name: user.name }); setSearch(''); }} + submitLogic={() => { + if (formattedData && formattedData[0]) { + const user = formattedData[0]; + passUser({ id: user.id, name: user.name }); + setSearch(''); + } + }} /> ); }; From 14cef9abebd78db60968c5a1d6367d1f6b2fb209 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Thu, 3 Oct 2024 13:30:55 -0500 Subject: [PATCH 25/37] remove debug statement and reword logic --- src/components/searchBar/index.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/components/searchBar/index.tsx b/src/components/searchBar/index.tsx index cd90c59f..228aeb96 100644 --- a/src/components/searchBar/index.tsx +++ b/src/components/searchBar/index.tsx @@ -18,11 +18,8 @@ export const SearchBar = (props: SearchBarProps) => { {...props} type="text" className={`h-10 w-full rounded-full border pl-10 ${submitButton ? 'pr-[38px]' : 'pr-3'} focus:outline-none ${props.className}`} - onSubmit={() => { - console.log('howdy from submit'); - }} onKeyDown={(e) => { - if (e.key === 'Enter' && submitLogic) { + if (e.key === 'Enter' && typeof submitLogic !== 'undefined') { submitLogic(); } }} From 674959dbadba850707d1f527ad7f05e435f8be33 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Thu, 3 Oct 2024 13:40:44 -0500 Subject: [PATCH 26/37] move prettier config to modules and add typing --- .prettierrc.js | 9 --------- .prettierrc.mjs | 16 ++++++++++++++++ 2 files changed, 16 insertions(+), 9 deletions(-) delete mode 100644 .prettierrc.js create mode 100644 .prettierrc.mjs diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 08a34d3b..00000000 --- a/.prettierrc.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - printWidth: 80, - semi: true, - singleQuote: true, - tabWidth: 2, - trailingComma: 'all', - useTabs: false, - plugins: ['prettier-plugin-tailwindcss'], -}; diff --git a/.prettierrc.mjs b/.prettierrc.mjs new file mode 100644 index 00000000..b7128a21 --- /dev/null +++ b/.prettierrc.mjs @@ -0,0 +1,16 @@ +/** + * @see https://prettier.io/docs/en/configuration.html + * @type {import("prettier").Config} + */ +const config = { + printWidth: 80, + semi: true, + singleQuote: true, + tabWidth: 2, + trailingComma: 'all', + useTabs: false, + bracketSameLine: false, + plugins: ['prettier-plugin-tailwindcss'], +}; + +export default config; From c3a1532e7cb98f3a2e2685aec085aa177239ef3e Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Thu, 3 Oct 2024 14:41:23 -0500 Subject: [PATCH 27/37] fix formatting check --- .github/workflows/prettierCheck.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/prettierCheck.yml b/.github/workflows/prettierCheck.yml index e642ea75..09538a2f 100644 --- a/.github/workflows/prettierCheck.yml +++ b/.github/workflows/prettierCheck.yml @@ -16,9 +16,11 @@ jobs: npm i --no-save prettier prettier-plugin-tailwindcss mv package.json.bak package.json - name: Run prettier + id: prettier + continue-on-error: true run: | - files=`npx prettier . -l` || st=$? && st=$? - echo status=`echo $st`>>"$GITHUB_ENV" - echo files=`echo $files`>> "$GITHUB_ENV" + echo "files=${npx prettier . -l}">> "$GITHUB_ENV" - name: generate errors/summary run: .github/workflows/generateCheck.sh + env: + status: ${{ success() && 0 || 1 }} From 2b3468a1c91c3fd8443df9ab275bc25ad693d40d Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Thu, 3 Oct 2024 14:46:50 -0500 Subject: [PATCH 28/37] fix status check --- .github/workflows/prettierCheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prettierCheck.yml b/.github/workflows/prettierCheck.yml index 09538a2f..d875a5e8 100644 --- a/.github/workflows/prettierCheck.yml +++ b/.github/workflows/prettierCheck.yml @@ -23,4 +23,4 @@ jobs: - name: generate errors/summary run: .github/workflows/generateCheck.sh env: - status: ${{ success() && 0 || 1 }} + status: ${{ steps.prettier.outcome == 'success' && 0 || 1 }} From 37b81f7e0835535d1db297d61cbd73dd20516585 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Thu, 3 Oct 2024 14:50:17 -0500 Subject: [PATCH 29/37] fix substitution --- .github/workflows/prettierCheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/prettierCheck.yml b/.github/workflows/prettierCheck.yml index d875a5e8..11982147 100644 --- a/.github/workflows/prettierCheck.yml +++ b/.github/workflows/prettierCheck.yml @@ -19,7 +19,7 @@ jobs: id: prettier continue-on-error: true run: | - echo "files=${npx prettier . -l}">> "$GITHUB_ENV" + echo files=`npx prettier . -l` >> "$GITHUB_ENV" - name: generate errors/summary run: .github/workflows/generateCheck.sh env: From 4b1b9837b620b3cb55997b2bc37e63a840b78f09 Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Thu, 3 Oct 2024 15:08:44 -0500 Subject: [PATCH 30/37] simplify install --- .github/workflows/prettierCheck.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/prettierCheck.yml b/.github/workflows/prettierCheck.yml index 11982147..ea76a9ad 100644 --- a/.github/workflows/prettierCheck.yml +++ b/.github/workflows/prettierCheck.yml @@ -11,15 +11,11 @@ jobs: node-version: 18 cache: 'npm' - name: Run npm install - run: | - mv package.json package.json.bak - npm i --no-save prettier prettier-plugin-tailwindcss - mv package.json.bak package.json + run: npm ci - name: Run prettier id: prettier continue-on-error: true - run: | - echo files=`npx prettier . -l` >> "$GITHUB_ENV" + run: echo files=`npx prettier . -l` >> "$GITHUB_ENV" - name: generate errors/summary run: .github/workflows/generateCheck.sh env: From 8fdeb9d79a2f5ac9b1f33edf6d844f4aa5965a1b Mon Sep 17 00:00:00 2001 From: Ethan Bickel Date: Thu, 3 Oct 2024 15:14:02 -0500 Subject: [PATCH 31/37] formatting fixes --- .../[clubId]/create/CreateEventForm.tsx | 331 ++++++++++-------- .../[clubId]/create/EventCardPreview.tsx | 110 +++--- src/app/manage/[clubId]/create/TimeSelect.tsx | 177 ++++++---- src/app/manage/[clubId]/create/page.tsx | 1 - src/server/api/routers/event.ts | 7 +- src/utils/formSchemas.ts | 2 +- 6 files changed, 366 insertions(+), 262 deletions(-) diff --git a/src/app/manage/[clubId]/create/CreateEventForm.tsx b/src/app/manage/[clubId]/create/CreateEventForm.tsx index fb3fbf0e..bd09638c 100644 --- a/src/app/manage/[clubId]/create/CreateEventForm.tsx +++ b/src/app/manage/[clubId]/create/CreateEventForm.tsx @@ -1,142 +1,199 @@ -'use client' +'use client'; -import { useEffect, useState } from "react"; -import { type SelectClub } from "@src/server/db/models"; -import { createEventSchema } from "@src/utils/formSchemas"; -import { useForm } from "react-hook-form"; -import { api } from "@src/trpc/react"; -import { type z } from "zod"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useRouter } from "next/navigation"; -import { UploadIcon } from "@src/icons/Icons"; -import EventCardPreview from "./EventCardPreview"; -import TimeSelect from "./TimeSelect"; -import { type RouterOutputs } from "@src/trpc/shared"; +import { useEffect, useState } from 'react'; +import { type SelectClub } from '@src/server/db/models'; +import { createEventSchema } from '@src/utils/formSchemas'; +import { useForm } from 'react-hook-form'; +import { api } from '@src/trpc/react'; +import { type z } from 'zod'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useRouter } from 'next/navigation'; +import { UploadIcon } from '@src/icons/Icons'; +import EventCardPreview from './EventCardPreview'; +import TimeSelect from './TimeSelect'; +import { type RouterOutputs } from '@src/trpc/shared'; -const CreateEventForm = ({ clubId, officerClubs }: { clubId: string, officerClubs: SelectClub[]}) => { - const { - register, - handleSubmit, - watch, - setValue, - getValues, - control, - } = useForm>({ - resolver: zodResolver(createEventSchema), - defaultValues: { - clubId: clubId, - }, - mode: "onSubmit", - }); - const router = useRouter(); - const [watchDescription, watchStartTime] = watch(['description', 'startTime']); - const [loading, setLoading] = useState(false); - const [eventPreview, setEventPreview] = useState({ - name: "", - clubId, - description: "", - location: "", - liked: false, - id: "", - startTime: new Date(Date.now()), - endTime: new Date(Date.now()), - club: officerClubs.filter((v) => v.id == clubId)[0]!, - }); - useEffect(() => { - const subscription = watch((data, info) => { - const { name, clubId, description, location, startTime, endTime } = data; - const club = officerClubs.find((val) => val.id == data.clubId); - if (club) { - setEventPreview({ - name: name || "", - clubId: clubId || "", - description: description || "", - location: location || "", - liked: false, - id: "", - startTime: startTime?.toString() === "" || startTime === undefined ? new Date(Date.now()) : new Date(startTime), - endTime: endTime?.toString() === "" || endTime?.toString() === "Invalid Date" || !endTime ? new Date(Date.now()) : new Date(endTime), - club, - }); - } - if (info.name == "clubId") { - router.replace(`/manage/${data.clubId}/create`); - } - }); - return () => subscription.unsubscribe(); - }, [router, watch, officerClubs]); +const CreateEventForm = ({ + clubId, + officerClubs, +}: { + clubId: string; + officerClubs: SelectClub[]; +}) => { + const { register, handleSubmit, watch, setValue, getValues, control } = + useForm>({ + resolver: zodResolver(createEventSchema), + defaultValues: { + clubId: clubId, + }, + mode: 'onSubmit', + }); + const router = useRouter(); + const [watchDescription, watchStartTime] = watch([ + 'description', + 'startTime', + ]); + const [loading, setLoading] = useState(false); + const [eventPreview, setEventPreview] = useState< + RouterOutputs['event']['findByFilters']['events'][number] + >({ + name: '', + clubId, + description: '', + location: '', + liked: false, + id: '', + startTime: new Date(Date.now()), + endTime: new Date(Date.now()), + club: officerClubs.filter((v) => v.id == clubId)[0]!, + }); + useEffect(() => { + const subscription = watch((data, info) => { + const { name, clubId, description, location, startTime, endTime } = data; + const club = officerClubs.find((val) => val.id == data.clubId); + if (club) { + setEventPreview({ + name: name || '', + clubId: clubId || '', + description: description || '', + location: location || '', + liked: false, + id: '', + startTime: + startTime?.toString() === '' || startTime === undefined + ? new Date(Date.now()) + : new Date(startTime), + endTime: + endTime?.toString() === '' || + endTime?.toString() === 'Invalid Date' || + !endTime + ? new Date(Date.now()) + : new Date(endTime), + club, + }); + } + if (info.name == 'clubId') { + router.replace(`/manage/${data.clubId}/create`); + } + }); + return () => subscription.unsubscribe(); + }, [router, watch, officerClubs]); - const createMutation = api.event.create.useMutation({ - onSuccess: (data) => { if (data) { - router.push(`/event/${data}`); - } }, - onError: () => { - setLoading(false); - } - }) + const createMutation = api.event.create.useMutation({ + onSuccess: (data) => { + if (data) { + router.push(`/event/${data}`); + } + }, + onError: () => { + setLoading(false); + }, + }); - const onSubmit = handleSubmit((data: z.infer) => { - if (!createMutation.isPending && !loading) { - setLoading(true); - createMutation.mutate(data); - } - }); + const onSubmit = handleSubmit((data: z.infer) => { + if (!createMutation.isPending && !loading) { + setLoading(true); + createMutation.mutate(data); + } + }); - return (
void onSubmit(e)} className="w-full flex flex-row flex-wrap justify-start gap-10 overflow-x-clip text-[#4D5E80] pb-4"> -
-
- Create Club Event for -
- -
-
-
-

Event Picture

-

Drag or choose file to upload

-
- -

JPEG, PNG, or SVG

-
-
-
-

Event Details

-
- - -
-
- - -
-
-
- -

{watchDescription && watchDescription.length} of 1000 Characters used

-
-