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/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/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..2d0735c5 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/icons/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 230828fa..05c07ef5 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'; +import { UserSearchBar } from '@src/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'; 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/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..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'; @@ -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 } }; 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/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/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/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..3e03c38b 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/icons/ContactIcons'; import { type modifyDeletedAction } from '@src/app/manage/[clubId]/edit/EditContactForm'; import { type editClubContactSchema } from '@src/utils/formSchemas'; 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/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 34978715..97531516 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 Header from '../components/header/BaseHeader'; +import Carousel from '../components/club/directory/Carousel'; +import TagFilter from '../components/club/directory/TagFilter'; +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/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/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/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/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/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 67% rename from src/components/admin/OrgSearch.tsx rename to src/components/admin/ClubSearch.tsx index 505a710f..0c14d02d 100644 --- a/src/components/admin/OrgSearch.tsx +++ b/src/components/admin/ClubSearch.tsx @@ -2,14 +2,14 @@ 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 = { - 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,11 +17,11 @@ 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 ( - (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/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/DirectoryOrgs.tsx b/src/components/club/ClubCard.tsx similarity index 93% rename from src/components/DirectoryOrgs.tsx rename to src/components/club/ClubCard.tsx index 882b0410..3fa4755f 100644 --- a/src/components/DirectoryOrgs.tsx +++ b/src/components/club/ClubCard.tsx @@ -7,7 +7,7 @@ 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/JoinButton.tsx b/src/components/club/JoinButton.tsx similarity index 100% rename from src/components/JoinButton.tsx rename to src/components/club/JoinButton.tsx 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..74a04aff 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 '@src/icons/Icons'; import Link from 'next/link'; import { type SelectClub } from '@src/server/db/models'; diff --git a/src/components/OrgDirectoryGrid.tsx b/src/components/club/directory/ClubDirectoryGrid.tsx similarity index 75% rename from src/components/OrgDirectoryGrid.tsx rename to src/components/club/directory/ClubDirectoryGrid.tsx index c3be3c13..8c6a99ab 100644 --- a/src/components/OrgDirectoryGrid.tsx +++ b/src/components/club/directory/ClubDirectoryGrid.tsx @@ -1,5 +1,5 @@ import { type FC } from 'react'; -import DirectoryOrgs from './DirectoryOrgs'; +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/InfiniteScrollGrid.tsx b/src/components/club/directory/InfiniteScrollGrid.tsx similarity index 75% rename from src/components/InfiniteScrollGrid.tsx rename to src/components/club/directory/InfiniteScrollGrid.tsx index 2a3e6189..259ab9b8 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 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,24 +54,20 @@ export default function InfiniteScrollGrid({ session, tag }: Props) { clubIndex === page.clubs.length - 1; return (
- +
); }), ) : Array.from({ length: 4 }, (_, index) => ( - + ))} {isFetchingNextPage && Array.from({ length: 4 }, (_, index) => ( - + ))} ); 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 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/OrgHeader.tsx b/src/components/club/listing/ClubHeader.tsx similarity index 95% rename from src/components/OrgHeader.tsx rename to src/components/club/listing/ClubHeader.tsx index 4b17dcb0..fcbb26dc 100644 --- a/src/components/OrgHeader.tsx +++ b/src/components/club/listing/ClubHeader.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'; @@ -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/OrgInfoSegment.tsx b/src/components/club/listing/ClubInfoSegment.tsx similarity index 98% rename from src/components/OrgInfoSegment.tsx rename to src/components/club/listing/ClubInfoSegment.tsx index 2e2e3b9a..d1fe1fc7 100644 --- a/src/components/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/OrgUpcomingEvents.tsx b/src/components/club/listing/ClubUpcomingEvents.tsx similarity index 93% rename from src/components/OrgUpcomingEvents.tsx rename to src/components/club/listing/ClubUpcomingEvents.tsx index 9232c1a3..7672f8a8 100644 --- a/src/components/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/components/ContactButtons.tsx b/src/components/club/listing/ContactButtons.tsx similarity index 93% rename from src/components/ContactButtons.tsx rename to src/components/club/listing/ContactButtons.tsx index b961ca01..ea255f59 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 '@src/icons/ContactIcons'; import Link from 'next/link'; type contentButtonProps = { diff --git a/src/components/events/EventCard.tsx b/src/components/events/EventCard.tsx index 75008289..1eb41bc5 100644 --- a/src/components/events/EventCard.tsx +++ b/src/components/events/EventCard.tsx @@ -2,9 +2,9 @@ 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 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..5257e59d 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 '@src/icons/Icons'; import { api } from '@src/trpc/react'; import { useRouter } from 'next/navigation'; 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 93d0a874..1a72a5f9 100644 --- a/src/components/BaseHeader.tsx +++ b/src/components/header/BaseHeader.tsx @@ -1,9 +1,10 @@ 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 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 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..d13c5cdb 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 '@src/icons/Icons'; const SidebarItems: FC<{ cat: allCats[number] }> = ({ cat }) => { const Icon = IconMap[cat]; diff --git a/src/components/searchBar/ClubSearchBar.tsx b/src/components/searchBar/ClubSearchBar.tsx new file mode 100644 index 00000000..7523c719 --- /dev/null +++ b/src/components/searchBar/ClubSearchBar.tsx @@ -0,0 +1,26 @@ +'use client'; +import { useState } from 'react'; +import { useRouter } from 'next/navigation'; +import type { SelectClub as Club } from '@src/server/db/models'; +import { api } from '@src/trpc/react'; +import { DebouncedSearchBar } from './DebouncedSearchBar'; + +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 ( + + ); +}; 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; 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'; 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 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)); }), });