From 72e4916c1fd833654d08202d5706801a14c9f445 Mon Sep 17 00:00:00 2001 From: Faye Date: Fri, 24 Nov 2023 16:14:04 +0100 Subject: [PATCH] changes --- next.config.js | 4 + src/app/account/frontpage/page.client.jsx | 22 +- src/app/account/gallery/page.client.jsx | 5 +- src/app/api/gallery/getTotalGallery/route.js | 14 +- .../api/user/avatarChange/[uniqueId]/route.js | 146 +++++--- src/app/api/user/getUser/[uniqueId]/route.js | 43 --- src/app/gallery/[uniqueId]/page.client.jsx | 339 ++++++++---------- src/app/gallery/page.client.jsx | 69 ++-- src/app/layouts/account-layout.jsx | 14 +- .../user/[uniqueId]/gallery/page.client.jsx | 86 +++-- src/app/user/[uniqueId]/page.client.jsx | 69 ++-- 11 files changed, 395 insertions(+), 416 deletions(-) delete mode 100644 src/app/api/user/getUser/[uniqueId]/route.js diff --git a/next.config.js b/next.config.js index cb897256..cb04b927 100644 --- a/next.config.js +++ b/next.config.js @@ -8,6 +8,10 @@ const nextConfig = { { protocol: "https", hostname: "*.headpat.de", + }, + { + protocol: "https", + hostname: "placekitten.com", } ] }, diff --git a/src/app/account/frontpage/page.client.jsx b/src/app/account/frontpage/page.client.jsx index 8f13bb72..2ed5d9a3 100644 --- a/src/app/account/frontpage/page.client.jsx +++ b/src/app/account/frontpage/page.client.jsx @@ -17,6 +17,10 @@ export default function AccountPage() { avatar: "", }); + const getAvatarImageUrl = (galleryId) => { + return `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655842922bac16a94a25/files/${galleryId}/preview?project=6557c1a8b6c2739b3ecf&width=400`; + }; + useEffect(() => { const fetchData = async () => { setIsLoading(true); @@ -35,7 +39,7 @@ export default function AccountPage() { pronouns: userDataResponseData.documents[0].pronouns || "", location: userDataResponseData.documents[0].location || "", avatar: - userDataResponseData.documents[0].avatar?.data?.attributes?.url || + getAvatarImageUrl(userDataResponseData.documents[0].avatarId) || "/logos/logo.webp", // Set the avatar value or a placeholder image }); setIsLoading(false); @@ -76,6 +80,7 @@ export default function AccountPage() { const formData = new FormData(); formData.append("file", selectedFile); + formData.append("fileId", "unique()"); try { const userResponse = await fetch("/api/user/getUserSelf", { @@ -226,9 +231,18 @@ export default function AccountPage() { type="file" onChange={handleAvatarChange} /> -

- JPG, GIF or PNG. 2MB max. -

+
+

+ JPG, GIF or PNG. 2MB max. +

+ +

1024x1024 max. resolution

diff --git a/src/app/account/gallery/page.client.jsx b/src/app/account/gallery/page.client.jsx index 3c37ff98..8cff58ea 100644 --- a/src/app/account/gallery/page.client.jsx +++ b/src/app/account/gallery/page.client.jsx @@ -52,8 +52,9 @@ export default function FetchGallery() { ? `queries[]=equal("userId","${userId}")&queries[]=equal("nsfw",false)` : `queries[]=equal("userId","${userId}")`; - const pageSize = 25; - const apiUrl = `/api/gallery/getUserGallery?${filters}&pagination[pageSize]=${pageSize}&pagination[page]=${currentPage}`; + const pageSize = 500; // Number of items per page + const offset = (currentPage - 1) * pageSize; // Calculate offset based on current page + const apiUrl = `/api/gallery/getUserGallery?${filters}&queries[]=limit(${pageSize})&queries[]=offset(${offset})`; setIsLoading(true); diff --git a/src/app/api/gallery/getTotalGallery/route.js b/src/app/api/gallery/getTotalGallery/route.js index 6efa600c..58146a00 100644 --- a/src/app/api/gallery/getTotalGallery/route.js +++ b/src/app/api/gallery/getTotalGallery/route.js @@ -1,22 +1,28 @@ import { NextResponse } from "next/server"; +import { headers } from "next/headers"; export const runtime = "edge"; export async function GET(request) { try { + const headersList = headers(); + const cookieHeader = headersList.get("cookie"); + // Extract query parameters from the incoming request const queryParams = new URLSearchParams( request.url.split("?")[1] ).toString(); // Construct the URL for the external fetch - const fetchURL = `${process.env.NEXT_PUBLIC_DOMAIN_API}/api/galleries?${queryParams}`; + const fetchURL = `${process.env.NEXT_PUBLIC_API_URL}/v1/databases/65527f2aafa5338cdb57/collections/655cb829dbf6102f2436/documents?${queryParams}`; const response = await fetch(fetchURL, { method: "GET", headers: { - Authorization: `Bearer ${process.env.DOMAIN_API_KEY}`, "Content-Type": "application/json", + "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, + "X-Appwrite-Response-Format": "1.4.0", + Cookie: cookieHeader, }, }); @@ -25,8 +31,8 @@ export async function GET(request) { } const data = await response.json(); - return NextResponse.json(data); + return NextResponse.json(data, { status: 200 }); } catch (error) { - return NextResponse.error(500, error.message); + return NextResponse.error(error.message, { status: 500 }); } } diff --git a/src/app/api/user/avatarChange/[uniqueId]/route.js b/src/app/api/user/avatarChange/[uniqueId]/route.js index 8aae2704..e2e532cb 100644 --- a/src/app/api/user/avatarChange/[uniqueId]/route.js +++ b/src/app/api/user/avatarChange/[uniqueId]/route.js @@ -8,6 +8,8 @@ export async function POST(request) { const headersList = headers(); const cookieHeader = headersList.get("cookie"); + const uniqueId = new URL(request.url).pathname.split("/").pop(); + // Read the entire stream and buffer it const requestData = await request.arrayBuffer(); @@ -16,59 +18,123 @@ export async function POST(request) { requestData.slice(0, 100).toString() );*/ - // Construct the URL for the external fetch - const fetchURL = `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655842922bac16a94a25/files`; - //console.log("Forwarding request to:", fetchURL); - - const uploadImage = await fetch(fetchURL, { - method: "POST", - headers: { - "Content-Type": - request.headers.get("Content-Type") || "multipart/form-data", - "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, - "X-Appwrite-Response-Format": "1.4.0", - Cookie: cookieHeader, - }, - body: requestData, - }); + // See if user has an avatar already + const avatarResponse = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/v1/databases/65527f2aafa5338cdb57/collections/655f6354b7c3fff1d687/documents?queries[]=equal("userId","${uniqueId}")`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, + "X-Appwrite-Response-Format": "1.4.0", + Cookie: cookieHeader, + }, + } + ); + + const avatarData = await avatarResponse.json(); + const avatarDocumentId = avatarData?.documents[0]?.$id; + const avatarGalleryId = avatarData?.documents[0]?.gallery_id; + // If user has an avatar, delete it + + if (avatarData.documents.length !== 0) { + const deleteURL = `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655842922bac16a94a25/files/${avatarGalleryId}`; + + const deleteResponse = await fetch(deleteURL, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, + "X-Appwrite-Response-Format": "1.4.0", + Cookie: cookieHeader, + }, + }); + + //const deleteData = await deleteResponse.json(); + + const deleteDocURL = `${process.env.NEXT_PUBLIC_API_URL}/v1/databases/65527f2aafa5338cdb57/collections/655f6354b7c3fff1d687/documents/${avatarDocumentId}`; + + const deleteDocResponse = await fetch(deleteDocURL, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, + "X-Appwrite-Response-Format": "1.4.0", + Cookie: cookieHeader, + }, + }); + } + + const uploadImage = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655842922bac16a94a25/files`, + { + method: "POST", + headers: { + "Content-Type": + request.headers.get("Content-Type") || "multipart/form-data", + "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, + "X-Appwrite-Response-Format": "1.4.0", + Cookie: cookieHeader, + }, + body: requestData, + } + ); const imageData = await uploadImage.json(); - const postURL = `${process.env.NEXT_PUBLIC_API_URL}/v1/databases/65527f2aafa5338cdb57/collections/655cb829dbf6102f2436/documents`; - - const response = await fetch(postURL, { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, - "X-Appwrite-Response-Format": "1.4.0", - Cookie: cookieHeader, - }, - body: JSON.stringify({ - documentId: "unique()", - data: { - gallery_id: imageData.$id, - siteOriginal: imageData.sizeOriginal, + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/v1/databases/65527f2aafa5338cdb57/collections/655f6354b7c3fff1d687/documents`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, + "X-Appwrite-Response-Format": "1.4.0", + Cookie: cookieHeader, }, - }), - }); + body: JSON.stringify({ + documentId: "unique()", + data: { + gallery_id: imageData.$id, + sizeOriginal: imageData.sizeOriginal, + userId: uniqueId, + }, + }), + } + ); - //console.log("External API Response Status:", response.status); - /*console.log( - "External API Response Headers:", - JSON.stringify([...response.headers]) - );*/ + // PATCH the userdata with the new avatar id + const patchResponse = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/v1/databases/65527f2aafa5338cdb57/collections/65564fa28d1942747a72/documents/${uniqueId}`, + { + method: "PATCH", + headers: { + "Content-Type": "application/json", + "X-Appwrite-Project": `${process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID}`, + "X-Appwrite-Response-Format": "1.4.0", + Cookie: cookieHeader, + }, + body: JSON.stringify({ + data: { + avatarId: imageData.$id, + }, + }), + } + ); if (!response.ok) { const errorData = await response.text(); - throw new Error(`Failed to forward data: ${errorData}`); + throw new Error(`Failed to POST data: ${errorData}`); + } + + if (!patchResponse.ok) { + const errorData = await patchResponse.text(); + throw new Error(`Failed to PATCH data: ${errorData}`); } const data = await response.json(); - //console.log("External API Response Body:", data); return NextResponse.json(data, { status: 201 }); } catch (error) { - //console.log("Error:", error.message); return NextResponse.json(error.message, { status: 500 }); } } diff --git a/src/app/api/user/getUser/[uniqueId]/route.js b/src/app/api/user/getUser/[uniqueId]/route.js deleted file mode 100644 index c94fdf8c..00000000 --- a/src/app/api/user/getUser/[uniqueId]/route.js +++ /dev/null @@ -1,43 +0,0 @@ -import { NextResponse } from "next/server"; - -export const runtime = "edge"; - -export async function GET() { - try { - // Assume the last segment of the URL is the user ID - const userId = request.url.split("/").pop(); - - // Extract query parameters from the incoming request - const queryParams = new URLSearchParams( - request.url.split("?")[1] - ).toString(); - - // Construct the URL for the external fetch - const fetchURL = `${process.env.NEXT_PUBLIC_DOMAIN_API}/api/users/${userId}?${queryParams}`; - - const response = await fetch(fetchURL, { - method: "GET", - headers: { - Authorization: `Bearer ${process.env.DOMAIN_API_KEY}`, - "Content-Type": "application/json", - }, - }); - - if (response.status === 401) { - return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); - } - - if (response.status === 403) { - return NextResponse.json({ message: "Forbidden" }, { status: 403 }); - } - - if (!response.ok) { - throw new Error("Failed to fetch data"); - } - - const data = await response.json(); - return NextResponse.json(data); - } catch (error) { - return NextResponse.error(500, error.message); - } -} diff --git a/src/app/gallery/[uniqueId]/page.client.jsx b/src/app/gallery/[uniqueId]/page.client.jsx index 3ac98a19..fcd5788d 100644 --- a/src/app/gallery/[uniqueId]/page.client.jsx +++ b/src/app/gallery/[uniqueId]/page.client.jsx @@ -8,14 +8,11 @@ export default function FetchGallery() { const [gallery, setGallery] = useState({}); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); - const [displayname, setDisplayname] = useState(null); + const [userData, setUserData] = useState({}); const [nsfwProfile, setNsfwProfile] = useState(null); - const getToken = () => { - return document.cookie.replace( - /(?:(?:^|.*;\s*)jwt\s*\=\s*([^;]*).*$)|^.*$/, - "$1" - ); + const getGalleryImageUrl = (galleryId) => { + return `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655ca6663497d9472539/files/${galleryId}/view?project=6557c1a8b6c2739b3ecf`; }; function getWidthHeightClass(width) { @@ -28,11 +25,6 @@ export default function FetchGallery() { useEffect(() => { const fetchInitialData = async () => { - const token = getToken(); - if (!token) { - return; - } - setIsLoading(true); try { const response = await fetch("/api/user/getUserSelf", { @@ -42,15 +34,7 @@ export default function FetchGallery() { throw new Error("Error fetching user self"); } const data = await response.json(); - const userId = data.id; - const userDataResponse = await fetch( - `/api/user/getUserData/${userId}`, - { - method: "GET", - } - ); - const userData = await userDataResponse.json(); - const enableNsfw = userData.data.attributes.enablensfw; + const enableNsfw = data[0].enablensfw; setNsfwProfile(enableNsfw); if (!enableNsfw) { setError("You don't have NSFW enabled!"); @@ -74,23 +58,22 @@ export default function FetchGallery() { try { const response = await fetch( - `/api/gallery/getUserGallery/${uniqueId}?populate=*`, + `/api/gallery/getUserGallery?queries[]=equal("$id","${uniqueId}")`, { method: "GET", } ); const data = await response.json(); - setGallery(data); + const userId = data.documents[0].userId; + setGallery(data.documents[0]); const userDataResponse = await fetch( - `/api/user/getUserData/${data.data.attributes.users_permissions_user.data.id}`, + `/api/user/getUserProfileFilter?queries[]=equal("$id","${userId}")`, { - headers: { - Authorization: `Bearer ${getToken()}`, - }, + method: "GET", } ); const userData = await userDataResponse.json(); - setDisplayname(userData.data?.attributes?.displayname); + setUserData(userData.documents[0]); } catch (error) { setError(error.message || "An error occurred."); } finally { @@ -101,6 +84,13 @@ export default function FetchGallery() { fetchGalleryData(); }, [nsfwProfile]); + const url = getGalleryImageUrl(gallery?.gallery_id); + const name = gallery?.name; + const longtext = gallery?.longtext; + const nsfw = gallery?.nsfw; + + const isNsfwImage = nsfw && !nsfwProfile; + // The rest of the component remains unchanged with conditional rendering based on the data's availability. return (
@@ -110,176 +100,137 @@ export default function FetchGallery() {
{(() => { - try { - const imgAttributes = - gallery?.data?.attributes?.img?.data?.attributes; - const url = imgAttributes?.url; - const name = gallery?.data?.attributes?.name; - const createdAt = gallery?.data?.attributes?.createdAt; - const modifiedAt = gallery?.data?.attributes?.updatedAt; - const longtext = gallery?.data?.attributes?.longtext; - const nsfw = gallery?.data?.attributes?.nsfw; - const width = - gallery?.data?.attributes?.img?.data?.attributes?.width; - const height = - gallery?.data?.attributes?.img?.data?.attributes?.height; - const username = - gallery?.data?.attributes?.users_permissions_user?.data - ?.attributes?.username; - - if (!url || !name) { - throw new Error("W-where am I? This is not a gallery!"); - } - - const isNsfwImage = nsfw && !nsfwProfile; - - return ( -
- {error || - (isNsfwImage ? ( - <> - ) : ( -
- - ← Go back - -
- ))} - {isNsfwImage ? ( -
- {/* Semi-transparent overlay */} -
{ - // Handle overlay click if needed (e.g., close the error message) - }} - >
-
- Du hast NSFW deaktiviert oder du bist nicht - eingeloggt, daher kannst du dieses Bild nicht sehen. -
-
- - Zurück zur Galerie - -
-
+ return ( +
+ {error || + (isNsfwImage ? ( + <> ) : ( - <> - {name -
-
-
-
-
-

- Image description -

-
-
-
-
-
- Title -
-
- {name || "No title provided."} -
-
-
-
- Uploaded by: -
-
- - {displayname || username} - -
-
-
-
- Creation Date -
-
- {new Date(createdAt).toLocaleDateString( - "de-DE", - { - day: "numeric", - month: "numeric", - year: "numeric", - timeZone: "Europe/Berlin", - } - )} -
-
-
-
- Last Modified -
-
- {new Date( - modifiedAt - ).toLocaleDateString("de-DE", { - day: "numeric", - month: "numeric", - year: "numeric", - timeZone: "Europe/Berlin", - })} -
-
-
-
- NSFW -
-
- {nsfw ? "Yes" : "No"} -
-
-
-
- Width/Height -
-
- {width}x{height} -
-
-
-
- About -
-
- {longtext || "No description provided."} -
-
-
-
+
+ + ← Go back + +
+ ))} + {isNsfwImage ? ( +
+ {/* Semi-transparent overlay */} +
{ + // Handle overlay click if needed (e.g., close the error message) + }} + >
+
+ Du hast NSFW deaktiviert oder du bist nicht eingeloggt, + daher kannst du dieses Bild nicht sehen. +
+
+ + Zurück zur Galerie + +
+
+ ) : ( + <> + {name +
+
+
+
+
+

+ Bild Informationen +

-
-
+
+
+
+
+ Titel +
+
+ {name || "No title provided."} +
+
+
+
+ Benutzer: +
+
+ + {userData.displayname} + +
+
+
+
+ Erstellt am +
+
+ {new Date( + userData.$createdAt + ).toLocaleString("en-GB", { + day: "2-digit", + month: "2-digit", + year: "numeric", + hour: "2-digit", + minute: "2-digit", + })} +
+
+
+
+ Letzte Änderung +
+
+ {new Date( + userData.$updatedAt + ).toLocaleString("en-GB", { + day: "2-digit", + month: "2-digit", + year: "numeric", + hour: "2-digit", + minute: "2-digit", + })} +
+
+
+
+ NSFW +
+
+ {nsfw ? "Yes" : "No"} +
+
+
+
+ Beschreibung +
+
+ {longtext || "No description provided."} +
+
+
+
+
+
- - )} -
- ); - } catch (e) { - return ( -
- -
- ); - } +
+ + )} +
+ ); })()}
diff --git a/src/app/gallery/page.client.jsx b/src/app/gallery/page.client.jsx index 4e3b7cd9..0f82253a 100644 --- a/src/app/gallery/page.client.jsx +++ b/src/app/gallery/page.client.jsx @@ -13,42 +13,27 @@ export default function FetchGallery({ data }) { const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); - - const getToken = () => { - return document.cookie.replace( - /(?:(?:^|.*;\s*)jwt\s*\=\s*([^;]*).*$)|^.*$/, - "$1" - ); - }; - - const handleApiResponse = (response) => { - if (response.status === 403 || !response.ok) { - //deleteCookie("jwt"); - window.location.reload(); - } - return response.json(); + const getGalleryImageUrl = (galleryId) => { + return `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655ca6663497d9472539/files/${galleryId}/preview?project=6557c1a8b6c2739b3ecf&quality=100&height=500&operation=fit`; }; useEffect(() => { const fetchInitialData = async () => { - const token = getToken(); - if (!token) return; - try { const response = await fetch("/api/user/getUserSelf", { method: "GET", }); - const data = await handleApiResponse(response); - setUserId(data.id); + const data = await response.json(); + setUserId(data.documents[0].$id); const userDataResponse = await fetch( - `/api/user/getUserDataSelf/${data.id}`, + `/api/user/getUserDataSelf/${data.documents[0].$id}`, { method: "GET", } ); - const userData = await handleApiResponse(userDataResponse); - setEnableNsfw(userData.data.attributes.enablensfw); + const userData = await userDataResponse.json(); + setEnableNsfw(userData[0].enablensfw); } catch (err) { setError(err); } @@ -60,9 +45,10 @@ export default function FetchGallery({ data }) { useEffect(() => { const fetchGalleryData = async () => { setIsLoading(true); - const filters = !enableNsfw ? `&filters[nsfw][$eq]=false` : ``; - const pageSize = 500; - const apiUrl = `/api/gallery/getTotalGallery?populate=img${filters}&pagination[pageSize]=${pageSize}&pagination[page]=${currentPage}`; + const filters = !enableNsfw ? `&queries[]=equal("nsfw",false)` : ``; + const pageSize = 500; // Number of items per page + const offset = (currentPage - 1) * pageSize; // Calculate offset based on current page + const apiUrl = `/api/gallery/getTotalGallery?${filters}&queries[]=limit(${pageSize})&queries[]=offset(${offset})`; setIsLoading(true); @@ -70,13 +56,14 @@ export default function FetchGallery({ data }) { const response = await fetch(apiUrl, { method: "GET", }); - const data = await handleApiResponse(response); + + const data = await response.json(); // Shuffle once when fetched - const shuffledData = data.data + const shuffledData = data.documents .sort(() => Math.random() - 0.5) .reverse(); setGallery(shuffledData); - setTotalPages(data.meta.pagination.pageCount); + setTotalPages(data.total); setIsLoading(false); } catch (err) { setError(err); @@ -120,37 +107,29 @@ export default function FetchGallery({ data }) { ) : ( diff --git a/src/app/layouts/account-layout.jsx b/src/app/layouts/account-layout.jsx index c6c4d75f..8de23cc0 100644 --- a/src/app/layouts/account-layout.jsx +++ b/src/app/layouts/account-layout.jsx @@ -53,6 +53,10 @@ export default function AccountLayout({ children }) { const [userData, setUserData] = useState(null); const [userMeData, setUserMeData] = useState(null); + const getAvatarImageUrl = (galleryId) => { + return `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655842922bac16a94a25/files/${galleryId}/preview?project=6557c1a8b6c2739b3ecf&width=100&output=webp&quality=75`; + }; + useEffect(() => { const fetchUserData = async () => { try { @@ -72,7 +76,7 @@ export default function AccountLayout({ children }) { const userDataResponse = await fetch(`/api/user/getUserDataSelf`, { method: "GET", }); - + const userDataResponseData = await userDataResponse.json(); // Set the userData state to the attributes object of the API response setUserData(userDataResponseData.documents[0]); @@ -234,10 +238,10 @@ export default function AccountLayout({ children }) { href={`/user/${userData.profileurl}`} className="flex items-center gap-x-4 px-6 py-3 text-sm font-semibold leading-6 text-white hover:bg-gray-800" > - - { + return `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655ca6663497d9472539/files/${galleryId}/preview?project=6557c1a8b6c2739b3ecf&width=400`; + }; + useEffect(() => { fetch( - `/api/user/getUserProfileUrlFilter?filters[username][$eq]=${username}`, + `/api/user/getUserProfileFilter?queries[]=equal("profileurl","${username}")`, { - headers: { - Authorization: `Bearer ${process.env.NEXT_PUBLIC_DOMAIN_API_KEY}`, - }, + method: "GET", } ) .then((response) => response.json()) .then((data) => { - setUserMe(data); // Access the first (and only) object in the array - setUserId(data[0].id); - const userId = data[0].id; // Access the id field of the first (and only) object in the array - fetch(`/api/user/getUserData/${userId}?populate=*`, { - method: "GET", - }) - .then((response) => response.json()) - .then((data) => { - setUserData(data); - }) - .catch((error) => { - console.error("API error:", error); - setHasError(true); // Set the error state to true - }); + setUserData(data.documents[0]); // Access the first (and only) object in the array + setUserId(data.documents[0].$id); }) .catch((error) => { console.error("API error:", error); @@ -63,22 +55,16 @@ export default function FetchGallery() { if (!userId) return; // Wait for userId to be available const fetchUserData = async () => { - const token = document.cookie.replace( - /(?:(?:^|.*;\s*)jwt\s*\=\s*([^;]*).*$)|^.*$/, - "$1" - ); - if (!token || typeof token === "undefined") return; // Return if "jwt" token does not exist - try { const response = await fetch( - `/api/user/getUserData/${userId}?populate=*`, + `/api/user/getUserDataSelf`, { method: "GET", } ); const data = await response.json(); - setEnableNsfw(data.data.attributes.enablensfw); + setEnableNsfw(data[0].enablensfw); } catch (error) { setError(error); } @@ -90,27 +76,39 @@ export default function FetchGallery() { useEffect(() => { if (!userId) return; // Wait for userId to be available - setIsLoading(true); - const filters = !enableNsfw - ? `filters[users_permissions_user][id][$eq]=${userId}&filters[nsfw][$eq]=false` - : `filters[users_permissions_user][id][$eq]=${userId}`; + ? `queries[]=equal("userId","${userId}")&queries[]=equal("nsfw",false)` + : `queries[]=equal("userId","${userId}")`; + + const pageSize = 500; // Number of items per page + const offset = (currentPage - 1) * pageSize; // Calculate offset based on current page + const apiUrl = `/api/gallery/getUserGallery?${filters}&queries[]=limit(${pageSize})&queries[]=offset(${offset})`; - const apiUrl = `/api/gallery/getTotalGallery?populate=*&${filters}`; + setIsLoading(true); fetch(apiUrl, { method: "GET", }) .then((response) => response.json()) .then((data) => { - setGallery(data.data.reverse()); - setIsLoading(false); + //setGallery(data.data.reverse()); + setGallery(data.documents); + setTotalPages(data.meta.pagination.pageCount); }) - .catch((error) => { - setError(error); + .catch((err) => { + setError(err.message || "An error occurred."); + }) + .finally(() => { setIsLoading(false); }); - }, [userId, enableNsfw]); + + setIsLoading(false); + }, [userId, enableNsfw, currentPage]); + + const handlePageChange = (page) => { + setCurrentPage(page); + window.history.pushState({ page }, `Page ${page}`, `?page=${page}`); + }; return ( <> @@ -405,13 +403,13 @@ export default function FetchGallery() { item.attributes.nsfw && !enableNsfw ? "https://placekitten.com/200/300" // Replace with placeholder image URL : item.attributes.img.data.attributes.ext === - ".gif" - ? item.attributes.img.data.attributes.url - : item.attributes.img.data.attributes.formats - .small - ? item.attributes.img.data.attributes.formats - .small.url - : item.attributes.img.data.attributes.url + ".gif" + ? item.attributes.img.data.attributes.url + : item.attributes.img.data.attributes + .formats.small + ? item.attributes.img.data.attributes + .formats.small.url + : item.attributes.img.data.attributes.url } alt={item.attributes.imgalt} className={`object-cover h-full w-full max-h-[600px] max-w-[600px]`} diff --git a/src/app/user/[uniqueId]/page.client.jsx b/src/app/user/[uniqueId]/page.client.jsx index 8a127bec..8a167de7 100644 --- a/src/app/user/[uniqueId]/page.client.jsx +++ b/src/app/user/[uniqueId]/page.client.jsx @@ -98,7 +98,11 @@ export default function UserProfile() { const params = useParams(); const username = params.uniqueId; - const rawBirthday = userData?.data?.attributes?.birthday; // ISO date string + const getAvatarImageUrl = (galleryId) => { + return `${process.env.NEXT_PUBLIC_API_URL}/v1/storage/buckets/655842922bac16a94a25/files/${galleryId}/preview?project=6557c1a8b6c2739b3ecf&width=100&output=webp&quality=75`; + }; + + const rawBirthday = userData?.birthday; // ISO date string // Parse the ISO date string to a Date object const dateObject = new Date(rawBirthday); @@ -134,7 +138,7 @@ export default function UserProfile() { ) .then((response) => response.json()) .then((data) => { - setUserData(data); + setUserData(data.documents[0]); console.log(data); }) .catch((error) => { @@ -166,13 +170,11 @@ export default function UserProfile() {
- {userData && - userData.data.attributes.avatar && - userData.data.attributes.avatar.data && - userData.data.attributes.avatar.data.attributes ? ( + {userData ? (

- {userData?.data?.attributes?.displayname || username} + {userData?.displayname || username}

It's their birthday today! @@ -239,14 +241,11 @@ export default function UserProfile() {

- {userData && - userData.data.attributes.avatar && - userData.data.attributes.avatar.data && - userData.data.attributes.avatar.data.attributes ? ( + {userData ? (

- {userData && userData[0]?.displayname} + {userData[0]?.displayname}

- {userData?.data?.attributes?.telegramname && ( + {userData?.telegramname && ( @@ -283,9 +282,9 @@ export default function UserProfile() { /> )} - {userData?.data?.attributes?.discordname && ( + {userData?.discordname && ( @@ -295,9 +294,9 @@ export default function UserProfile() { /> )} - {userData?.data?.attributes?.X_name && ( + {userData?.X_name && ( @@ -307,9 +306,9 @@ export default function UserProfile() { /> )} - {userData?.data?.attributes?.twitchname && ( + {userData?.twitchname && ( @@ -319,9 +318,9 @@ export default function UserProfile() { /> )} - {userData?.data?.attributes?.furaffinityname && ( + {userData?.furaffinityname && ( @@ -404,7 +403,7 @@ export default function UserProfile() { )} Gallery @@ -491,7 +490,7 @@ export default function UserProfile() { />
- {userData?.data?.attributes?.displayname} + {userData?.displayname}
- {userData?.data?.attributes?.status} + {userData?.status}
- {userData?.data?.attributes?.pronouns !== "" && ( + {userData?.pronouns !== "" && (
- {userData?.data?.attributes?.pronouns} + {userData?.pronouns}
)} {formattedBirthday !== "31.01.1900" && (
)} - {userData?.data?.attributes?.location !== null && - userData?.data?.attributes?.location !== "" && ( + {userData?.location !== null && + userData?.location !== "" && (
@@ -561,7 +560,7 @@ export default function UserProfile() { />
- {userData?.data?.attributes?.location} + {userData?.location}
)} @@ -580,7 +579,7 @@ export default function UserProfile() { className="font-medium dark:text-gray-300 text-gray-800" style={{ whiteSpace: "pre-line" }} > - {userData?.data?.attributes?.bio} + {userData?.bio}