-
+
{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));
}),
});