diff --git a/package-lock.json b/package-lock.json
index 8c70b39..70873c5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -38,17 +38,6 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "@commitlint/cli": "^18.6.1",
- "@commitlint/config-conventional": "^16.2.4",
- "@tailwindcss/typography": "^0.5.15",
- "@types/eslint": "^8.56.12",
- "@types/jest": "^29.5.12",
- "@types/node": "^18.19.50",
- "@types/react": "^18.3.5",
- "@types/react-dom": "^18.3.0",
- "@typescript-eslint/eslint-plugin": "^6.21.0",
- "@typescript-eslint/parser": "^6.21.0",
- "autoprefixer": "^10.4.20",
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^16.2.1",
"@tailwindcss/typography": "^0.5.9",
@@ -64,12 +53,6 @@
"cz-conventional-changelog": "^3.3.0",
"dotenv-cli": "^7.4.2",
"drizzle-kit": "^0.19.13",
- "eslint": "^8.57.1",
- "eslint-config-next": "^13.5.6",
- "eslint-config-prettier": "^8.10.0",
- "eslint-plugin-jsx-a11y": "^6.10.0",
- "eslint-plugin-react": "^7.35.2",
- "eslint-plugin-react-hooks": "^4.6.2",
"eslint": "^8.47.0",
"eslint-config-next": "^14.2.1",
"eslint-config-prettier": "^8.5.0",
@@ -1437,10 +1420,12 @@
}
},
"node_modules/@humanwhocodes/object-schema": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
- "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
- "dev": true
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
@@ -3574,6 +3559,13 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
+ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/acorn": {
"version": "8.10.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
@@ -8378,6 +8370,49 @@
"@pkgjs/parseargs": "^0.11.0"
}
},
+ "node_modules/jake": {
+ "version": "10.9.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz",
+ "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.3",
+ "chalk": "^4.0.2",
+ "filelist": "^1.0.4",
+ "minimatch": "^3.1.2"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jake/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/jake/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
@@ -11579,11 +11614,6 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"devOptional": true
},
- "node_modules/save-dev": {
- "version": "0.0.1-security",
- "resolved": "https://registry.npmjs.org/save-dev/-/save-dev-0.0.1-security.tgz",
- "integrity": "sha512-k6knZTDNK8PKKbIqnvxiOveJinuw2LcQjqDoaorZWP9M5AR2EPsnpDeSbeoZZ0pHr5ze1uoaKdK8NBGQrJ34Uw=="
- },
"node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -11612,6 +11642,24 @@
"optional": true,
"peer": true
},
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/set-function-name": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
diff --git a/src/app/page.tsx b/src/app/page.tsx
index ddab1f9..9753151 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -33,7 +33,7 @@ const Home = async (props: Params) => {
-
+
);
diff --git a/src/components/InfiniteScrollGrid.tsx b/src/components/InfiniteScrollGrid.tsx
new file mode 100644
index 0000000..6883567
--- /dev/null
+++ b/src/components/InfiniteScrollGrid.tsx
@@ -0,0 +1,78 @@
+'use client';
+import { api } from '@src/trpc/react';
+import { type Session } from 'next-auth';
+import { useEffect, useRef } from 'react';
+import { type SelectClub } from '@src/server/db/models';
+import ClubCard, { ClubCardSkeleton } from './club/ClubCard';
+
+type Props = {
+ session: Session | null;
+ tag?: string;
+};
+
+export default function InfiniteScrollGrid({ session, tag }: Props) {
+ const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage } =
+ api.club.all.useInfiniteQuery(
+ { tag, limit: 9 },
+ {
+ getNextPageParam: (lastPage) =>
+ lastPage.clubs.length < 9 ? undefined : lastPage.cursor,
+ initialCursor: 9,
+ },
+ );
+
+ const observer = useRef();
+ const lastOrgElementRef = useRef(null);
+
+ useEffect(() => {
+ if (isLoading || isFetchingNextPage) return;
+ if (observer.current) observer.current.disconnect();
+
+ observer.current = new IntersectionObserver((entries) => {
+ if (!entries[0]) return;
+ if (entries[0].isIntersecting) {
+ void fetchNextPage();
+ }
+ });
+
+ if (lastOrgElementRef.current) {
+ observer.current.observe(lastOrgElementRef.current);
+ }
+
+ return () => {
+ if (observer.current) observer.current.disconnect();
+ };
+ }, [isLoading, isFetchingNextPage, hasNextPage, fetchNextPage]);
+
+ return (
+ <>
+ {data && !isLoading
+ ? data.pages.map((page: { clubs: SelectClub[] }, index: number) =>
+ page.clubs.map((club, clubIndex) => {
+ const isLastElement =
+ index === data.pages.length - 1 &&
+ clubIndex === page.clubs.length - 1;
+ return (
+
+
+
+ );
+ }),
+ )
+ : Array.from({ length: 4 }, (_, index) => (
+
+ ))}
+ {isFetchingNextPage &&
+ Array.from({ length: 4 }, (_, index) => (
+
+ ))}
+ >
+ );
+}
diff --git a/src/components/OrgDirectoryCarousel.tsx b/src/components/OrgDirectoryCarousel.tsx
index 434750d..20eae73 100644
--- a/src/components/OrgDirectoryCarousel.tsx
+++ b/src/components/OrgDirectoryCarousel.tsx
@@ -2,10 +2,10 @@
import { useRef, type FC } from 'react';
import React, { useState } from 'react';
-import DirectoryOrgs from './DirectoryOrgs';
import { type Session } from 'next-auth';
import { type SelectClub } from '@src/server/db/models';
import { LeftArrowIcon, RightArrowIcon } from '@src/icons/Icons';
+import ClubCard from './club/ClubCard';
type Props = {
clubs: SelectClub[],
@@ -54,7 +54,7 @@ const OrgDirectoryCarousel: FC = ({ clubs, session }) => {
>
{clubs.map((club) => (
-
+
))}