202 lines
7.5 KiB
TypeScript
Raw Normal View History

2024-05-26 02:14:59 -04:00
"use client";
import { createClient } from "@/utils/supabase/client";
import { redirect } from "next/navigation";
import GalleryThumbnail from "@/components/ui/gallery_thumbnail";
import React, { useState, useEffect } from 'react';
import { User } from "@supabase/supabase-js";
import Gallery from "@/components/ui/gallery";
function PageComponent() {
const supabase = createClient();
2024-05-27 20:40:23 -04:00
const [showNSFW, setShowNSFW] = useState<boolean>(true);
2024-05-26 03:46:00 -04:00
const [randomIds, setRandomIds] = useState<string[]>([]); // replace any with your gallery type
2024-05-26 02:14:59 -04:00
const [isOpen, setIsOpen] = useState<boolean>(false);
const [galleries, setGalleries] = useState<any[]>([]); // replace any with your gallery type
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState<boolean>(true);
2024-05-26 13:08:59 -04:00
const [selectedGallery, setSelectedGallery] = useState<string | null>(null);
2024-05-26 19:49:20 -04:00
const [tags, setTags] = useState<any[]>([]);
const [search, setSearch] = useState<string>('');
2024-05-26 16:58:48 -04:00
const [galleryColumns, setColumns] = useState<number>(0);
2024-05-26 19:49:20 -04:00
const [selectedTags, setSelectedTags] = useState<number[]>([]);
2024-05-27 20:53:24 -04:00
const generateRandomString = function (length: number) {
let result = '';
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
2024-05-26 03:46:00 -04:00
let charactersLength = characters.length;
2024-05-27 20:53:24 -04:00
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
2024-05-26 03:46:00 -04:00
}
return result;
2024-05-27 20:53:24 -04:00
}
2024-05-26 02:14:59 -04:00
2024-05-27 20:53:24 -04:00
const selectGallery = (gallery: string, columns: number) => {
2024-05-26 03:46:00 -04:00
setRandomIds([generateRandomString(3), generateRandomString(3), generateRandomString(3), generateRandomString(3)]);
2024-05-26 02:14:59 -04:00
setSelectedGallery(gallery);
2024-05-26 16:58:48 -04:00
setColumns(columns);
2024-05-26 02:14:59 -04:00
setIsOpen(true);
};
2024-05-26 14:36:20 -04:00
const closeGallery = () => {
setSelectedGallery(null);
2024-05-26 16:58:48 -04:00
setColumns(0);
2024-05-26 14:36:20 -04:00
setIsOpen(false);
}
2024-05-26 02:14:59 -04:00
const getData = async () => {
let { data: { user } } = await supabase.auth.getUser();
2024-05-27 20:53:24 -04:00
const galleriesResponse = await fetch(`/api/galleries?search=` + search + '&nsfw=' + showNSFW, {
2024-05-26 19:49:20 -04:00
method: 'POST',
headers: {
2024-05-27 20:53:24 -04:00
'Content-Type': 'application/json'
2024-05-26 19:49:20 -04:00
},
2024-05-27 20:53:24 -04:00
body: JSON.stringify({ tags: selectedTags })
2024-05-26 19:49:20 -04:00
});
//console.log(galleriesResponse)
2024-05-26 19:49:20 -04:00
const galleriesData = await galleriesResponse.json();
const tagsResponse = await fetch(`/api/galleries/tags`);
const tagsData = await tagsResponse.json();
2024-05-26 02:14:59 -04:00
setGalleries(galleriesData);
2024-05-26 19:49:20 -04:00
setTags(tagsData);
2024-05-26 02:14:59 -04:00
setUser(user);
setLoading(false);
}
useEffect(() => {
getData();
2024-05-27 20:53:24 -04:00
}, [selectedTags, search, showNSFW]);
2024-05-26 19:49:20 -04:00
const handleTagClick = (tag: number) => {
if (selectedTags.includes(tag)) {
setSelectedTags(selectedTags.filter((selectedTag) => selectedTag !== tag));
} else {
setSelectedTags([...selectedTags, tag]);
}
//console.log(selectedTags)
2024-05-26 19:49:20 -04:00
};
return (
2024-05-27 16:38:34 -04:00
<div>
2024-05-27 17:09:49 -04:00
<div className="fixed w-full h-full overflow-hidden z-0 animate-fade-left animate-fade-left animate-once animate-duration-[2000ms] animate-normal animate-fill-forwards">
2024-05-27 16:38:34 -04:00
<img
src="gallery_girl.png"
className="float-right object-cover h-screen w-6/6 md:w-5/6 lg:w-3/6 opacity-50 overflow-hidden"
alt="Background"
/>
2024-05-27 17:09:49 -04:00
</div>
2024-05-27 20:53:24 -04:00
{/*
THIS IS THE SEARCH BAR AND TAGS SECTION
THIS IS THE SEARCH BAR AND TAGS SECTION
THIS IS THE SEARCH BAR AND TAGS SECTION
THIS IS THE SEARCH BAR AND TAGS SECTION
THIS IS THE SEARCH BAR AND TAGS SECTION
THIS IS THE SEARCH BAR AND TAGS SECTION
*/}
2024-05-27 20:19:20 -04:00
<section className="flex items-center w-full p-8 pt-20 opacity-90 animate-jump-in animate-once animate-duration-500">
2024-05-27 20:53:24 -04:00
{(tags.length > 0) ? (
<div className="container mx-auto py-8">
<div className="relative w-full mx-auto">
<input
className="w-full text-neroshi-blue-950 h-16 px-3 rounded mb-8 focus:outline-none focus:shadow-outline text-xl px-8 shadow-lg"
type="search"
placeholder="Search by title..."
onChange={(e) => setSearch(e.target.value)}
style={{
animation: 'expandFromLeft 2s ease-out forwards',
paddingRight: '2rem', // make room for the checkbox
}}
/>
<label htmlFor="toggleNSFW" className="absolute right-0 top-0 h-full mr-2 flex items-center text-neroshi-blue-950 animate-fade animate-once animate-duration-500 animate-delay-[2000ms] animate-ease-out">
Censor NSFW
<input
id="toggleNSFW"
type="checkbox"
checked={showNSFW}
onChange={() => setShowNSFW(!showNSFW)}
className="form-checkbox h-5 w-5 text-neroshi-blue-950 ml-2 "
/>
</label>
</div>
2024-05-27 20:53:24 -04:00
{(tags.length > 0) ? (
2024-05-27 23:19:30 -04:00
<nav className="grid grid-cols-3 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-4 justify-items-center">
2024-05-27 20:53:24 -04:00
{tags.map((tag, index) => (
<a
key={index}
className={`w-full rounded-lg no-underline text-white py-3 px-4 font-medium text-center animate-jump-in animate-once animate-duration-500 animate-ease-out ${selectedTags.includes(tag.name) ? 'bg-neroshi-blue-950 hover:bg-neroshi-blue-900' : 'bg-neroshi-blue-800 hover:bg-neroshi-blue-700'
}`}
href="#"
onClick={() => handleTagClick(tag.name)}
>
{tag.name}
</a>
))}
</nav>
) : (
<div className="flex justify-center">
<p className="text-white">Loading Tags...</p>
</div>
)}
</div>
) : (
<div className="animate-pulse bg-neroshi-blue-950 rounded-3xl w-full p-8 mt-10 h-48" ></div>
)}
2024-05-27 16:38:34 -04:00
</section>
2024-05-27 20:53:24 -04:00
{/*
These are the thumbnails for the gallery below the search bar
*/}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-y-60 gap-x-5 h-full mb-96 animate-in">
2024-05-27 16:38:34 -04:00
{galleries && galleries.map((gallery, index) => (
<div className="mx-auto">
2024-05-27 20:53:24 -04:00
<GalleryThumbnail
key={gallery.name + " " + showNSFW}
id={gallery.name}
title={gallery.name}
tags={gallery.tags}
columns={gallery.columns}
showNsfw={showNSFW}
subscription={gallery.tier as string}
onSelect={selectGallery}
nsfw={gallery.nsfw}
></GalleryThumbnail>
</div>
))}
2024-05-27 16:38:34 -04:00
</div>
{isOpen ? (
<>
2024-05-27 20:53:24 -04:00
{/*
This is the modal for holding the gallery
*/}
<div
2024-05-27 20:53:24 -04:00
className={`fixed inset-0 transition-opacity z-30 ${isOpen ? 'animate-in' : 'fade-out'
}`}
2024-05-27 16:38:34 -04:00
aria-hidden="true"
>
<div
className="absolute inset-0 bg-neroshi-blue-900 opacity-70 z-30"
onClick={() => setIsOpen(false)}
></div>
<div className="absolute inset-0 overflow-y-auto overflow-x-hidden no-scrollbar pt-2 w-full p-20 z-30">
<Gallery
id={selectedGallery as string}
columns={galleryColumns}
closeMenu={() => closeGallery()}
></Gallery>
</div>
</div>
2024-05-27 16:38:34 -04:00
</>
) : null}
</div>
2024-05-26 19:49:20 -04:00
);
2024-05-26 02:14:59 -04:00
}
export default PageComponent;