Spaces:
Runtime error
Runtime error
no-ssr component
Browse files- app/api/collections/[id]/route.ts +16 -0
- app/api/collections/route.ts +4 -2
- app/page.tsx +4 -1
- components/main/collections/collection.tsx +1 -0
- components/main/hooks/useCollections.ts +15 -13
- components/main/index.tsx +7 -4
- components/no-ssr.tsx +31 -0
app/api/collections/[id]/route.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { PrismaClient } from '@prisma/client'
|
| 2 |
+
|
| 3 |
+
// const prisma = new PrismaClient()
|
| 4 |
+
|
| 5 |
+
export async function DELETE(request: Request) {
|
| 6 |
+
const { id } = await request.json()
|
| 7 |
+
|
| 8 |
+
console.log(id)
|
| 9 |
+
|
| 10 |
+
return Response.json(
|
| 11 |
+
{
|
| 12 |
+
status: 200,
|
| 13 |
+
ok: true
|
| 14 |
+
}
|
| 15 |
+
)
|
| 16 |
+
}
|
app/api/collections/route.ts
CHANGED
|
@@ -2,8 +2,10 @@ import { PrismaClient } from '@prisma/client'
|
|
| 2 |
|
| 3 |
const prisma = new PrismaClient()
|
| 4 |
|
| 5 |
-
export async function
|
| 6 |
-
const {
|
|
|
|
|
|
|
| 7 |
|
| 8 |
const collections = await prisma.collection.findMany({
|
| 9 |
orderBy: {
|
|
|
|
| 2 |
|
| 3 |
const prisma = new PrismaClient()
|
| 4 |
|
| 5 |
+
export async function GET(request: Request) {
|
| 6 |
+
const { searchParams } = new URL(request.url)
|
| 7 |
+
const userId = searchParams.get('id') ?? undefined
|
| 8 |
+
const page = searchParams.get('page') ? parseInt(searchParams.get('page') as string) : 0
|
| 9 |
|
| 10 |
const collections = await prisma.collection.findMany({
|
| 11 |
orderBy: {
|
app/page.tsx
CHANGED
|
@@ -1,12 +1,15 @@
|
|
| 1 |
import { Header } from "@/components/header";
|
| 2 |
import { Footer } from "@/components/footer";
|
| 3 |
import { Main } from "@/components/main";
|
|
|
|
| 4 |
|
| 5 |
export default function Home() {
|
| 6 |
return (
|
| 7 |
<div className="pb-32">
|
| 8 |
<Header />
|
| 9 |
-
<
|
|
|
|
|
|
|
| 10 |
<Footer />
|
| 11 |
</div>
|
| 12 |
);
|
|
|
|
| 1 |
import { Header } from "@/components/header";
|
| 2 |
import { Footer } from "@/components/footer";
|
| 3 |
import { Main } from "@/components/main";
|
| 4 |
+
import NoSSR from "@/components/no-ssr";
|
| 5 |
|
| 6 |
export default function Home() {
|
| 7 |
return (
|
| 8 |
<div className="pb-32">
|
| 9 |
<Header />
|
| 10 |
+
<NoSSR>
|
| 11 |
+
<Main />
|
| 12 |
+
</NoSSR>
|
| 13 |
<Footer />
|
| 14 |
</div>
|
| 15 |
);
|
components/main/collections/collection.tsx
CHANGED
|
@@ -30,6 +30,7 @@ export const Collection: React.FC<Props> = ({
|
|
| 30 |
<motion.div
|
| 31 |
initial={{ y: 100, opacity: 0 }}
|
| 32 |
animate={{ y: 0, opacity: 1 }}
|
|
|
|
| 33 |
transition={{
|
| 34 |
duration: 0.35,
|
| 35 |
delay: (index % 15) * 0.1,
|
|
|
|
| 30 |
<motion.div
|
| 31 |
initial={{ y: 100, opacity: 0 }}
|
| 32 |
animate={{ y: 0, opacity: 1 }}
|
| 33 |
+
data-id={collection.id}
|
| 34 |
transition={{
|
| 35 |
duration: 0.35,
|
| 36 |
delay: (index % 15) * 0.1,
|
components/main/hooks/useCollections.ts
CHANGED
|
@@ -19,13 +19,14 @@ export const useCollections = (category: string) => {
|
|
| 19 |
} = useQuery(
|
| 20 |
["collections"],
|
| 21 |
async () => {
|
| 22 |
-
const
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
})
|
|
|
|
| 29 |
const data = await response.json()
|
| 30 |
|
| 31 |
if (!response.ok) {
|
|
@@ -45,13 +46,14 @@ export const useCollections = (category: string) => {
|
|
| 45 |
|
| 46 |
const infiniteRefetch = async () => {
|
| 47 |
setLoading(true);
|
| 48 |
-
const
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
| 55 |
const d = await response.json()
|
| 56 |
if (d.ok) {
|
| 57 |
const images = _.concat(data?.images, d?.collections);
|
|
|
|
| 19 |
} = useQuery(
|
| 20 |
["collections"],
|
| 21 |
async () => {
|
| 22 |
+
const queryParams = new URLSearchParams();
|
| 23 |
+
queryParams.append('userId', category === 'my-own' ? user?.sub : undefined);
|
| 24 |
+
queryParams.append('page', '0');
|
| 25 |
+
|
| 26 |
+
const response = await fetch(`/api/collections?${queryParams.toString()}`, {
|
| 27 |
+
method: "GET",
|
| 28 |
})
|
| 29 |
+
|
| 30 |
const data = await response.json()
|
| 31 |
|
| 32 |
if (!response.ok) {
|
|
|
|
| 46 |
|
| 47 |
const infiniteRefetch = async () => {
|
| 48 |
setLoading(true);
|
| 49 |
+
const queryParams = new URLSearchParams();
|
| 50 |
+
queryParams.append('userId', category === 'my-own' ? user?.sub : undefined);
|
| 51 |
+
queryParams.append('page', data?.pagination?.page,);
|
| 52 |
+
|
| 53 |
+
const response = await fetch(`/api/collections?${queryParams.toString()}`, {
|
| 54 |
+
method: "GET",
|
| 55 |
+
})
|
| 56 |
+
|
| 57 |
const d = await response.json()
|
| 58 |
if (d.ok) {
|
| 59 |
const images = _.concat(data?.images, d?.collections);
|
components/main/index.tsx
CHANGED
|
@@ -29,7 +29,7 @@ const categories = [
|
|
| 29 |
},
|
| 30 |
];
|
| 31 |
|
| 32 |
-
const useBreakpoint = createBreakpoint({ L: 1024, XS: 640 });
|
| 33 |
|
| 34 |
export const Main = () => {
|
| 35 |
const { openWindowLogin, user } = useUser();
|
|
@@ -46,12 +46,15 @@ export const Main = () => {
|
|
| 46 |
<div className="items-center justify-center flex-col lg:flex-row lg:justify-end gap-5 w-full mt-6 lg:mt-0 flex">
|
| 47 |
{categories.map(({ key, label, icon, isLogged }) =>
|
| 48 |
isLogged && !user ? (
|
| 49 |
-
<
|
| 50 |
key={key}
|
| 51 |
src={`https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-${
|
| 52 |
-
|
| 53 |
}.svg`}
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
| 55 |
onClick={openWindowLogin}
|
| 56 |
/>
|
| 57 |
) : (
|
|
|
|
| 29 |
},
|
| 30 |
];
|
| 31 |
|
| 32 |
+
const useBreakpoint = createBreakpoint({ XL: 1280, L: 1024, S: 768, XS: 640 });
|
| 33 |
|
| 34 |
export const Main = () => {
|
| 35 |
const { openWindowLogin, user } = useUser();
|
|
|
|
| 46 |
<div className="items-center justify-center flex-col lg:flex-row lg:justify-end gap-5 w-full mt-6 lg:mt-0 flex">
|
| 47 |
{categories.map(({ key, label, icon, isLogged }) =>
|
| 48 |
isLogged && !user ? (
|
| 49 |
+
<Image
|
| 50 |
key={key}
|
| 51 |
src={`https://huggingface.co/datasets/huggingface/badges/resolve/main/sign-in-with-huggingface-${
|
| 52 |
+
["XS", "S"].includes(breakpoint) ? "lg" : "xl"
|
| 53 |
}.svg`}
|
| 54 |
+
width="100"
|
| 55 |
+
height="32"
|
| 56 |
+
alt="Sign in with Hugging Face"
|
| 57 |
+
className="cursor-pointer hover:-translate-y-1 transition-all duration-200 w-auto object-contain"
|
| 58 |
onClick={openWindowLogin}
|
| 59 |
/>
|
| 60 |
) : (
|
components/no-ssr.tsx
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
import { useEffect, useLayoutEffect, useState } from "react";
|
| 3 |
+
import PropTypes from "prop-types";
|
| 4 |
+
|
| 5 |
+
const useEnhancedEffect =
|
| 6 |
+
typeof window !== "undefined" && process.env.NODE_ENV !== "test"
|
| 7 |
+
? useLayoutEffect
|
| 8 |
+
: useEffect;
|
| 9 |
+
|
| 10 |
+
const NoSSR = ({
|
| 11 |
+
children,
|
| 12 |
+
defer = false,
|
| 13 |
+
fallback = null,
|
| 14 |
+
}: {
|
| 15 |
+
children: React.ReactNode;
|
| 16 |
+
defer?: boolean;
|
| 17 |
+
fallback?: React.ReactNode;
|
| 18 |
+
}) => {
|
| 19 |
+
const [isMounted, setMountedState] = useState(false);
|
| 20 |
+
|
| 21 |
+
useEnhancedEffect(() => {
|
| 22 |
+
if (!defer) setMountedState(true);
|
| 23 |
+
}, [defer]);
|
| 24 |
+
|
| 25 |
+
useEffect(() => {
|
| 26 |
+
if (defer) setMountedState(true);
|
| 27 |
+
}, [defer]);
|
| 28 |
+
|
| 29 |
+
return isMounted ? children : fallback;
|
| 30 |
+
};
|
| 31 |
+
export default NoSSR;
|