252 lines
12 KiB
TypeScript
Raw Normal View History

2024-06-02 03:48:21 -04:00
"use client";
import { createClient } from "@/utils/supabase/client";
import React, { useState, useEffect } from 'react';
import Search from "@/components/neroshitron/search";
import Gallery from "@/components/neroshitron/gallery";
import Masonry from "react-masonry-css";
import SearchInput from "@/components/neroshitron/search_input";
2024-06-02 04:42:34 -04:00
import GalleryThumbnail from "@/components/neroshitron/gallery_thumbnail";
2024-06-02 03:48:21 -04:00
function PageComponent() {
const [filePreviews, setFilePreviews] = useState<string[]>([]);
const supabase = createClient();
const user = supabase.auth.getUser();
const [gallery , setGallery] = useState<any>(null);
2024-06-03 02:00:05 -04:00
const [originalName, setOriginalGalleryName] = useState<string>('');
const [galleryName, setGalleryName] = useState<string>('');
const [nsfw, setNsfw] = useState<boolean>(false);
const [tags, setTags] = useState<string[]>([]);
const [tier, setTier] = useState<string>('Free');
2024-06-03 02:00:05 -04:00
const [thumbnail, setThumbnail] = useState<string>();
const [fileNames, setFileNames] = useState<string[]>([]);
const [selectedTags, setSelectedTags] = useState<string[]>([]);
2024-06-03 02:25:25 -04:00
const [open, setOpen] = useState<boolean>(false);
2024-06-03 02:10:39 -04:00
const [images, setImages] = useState<string[]>([]);
const getData = async () => {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const galleryResponse = await fetch(`/api/galleries/admin/${id}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const galleryData = await galleryResponse.json();
setGallery(galleryData.gallery);
2024-06-03 02:00:05 -04:00
const filesResponse = await fetch(`/api/galleries/${id}/images/names`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const filesData = await filesResponse.json();
setFileNames(filesData);
setNsfw(galleryData.gallery.nsfw);
setTags(galleryData.gallery.tags);
setTier(galleryData.gallery.tier);
setGalleryName(galleryData.gallery.name);
2024-06-03 02:00:05 -04:00
if(originalName === ''){
setOriginalGalleryName(galleryData.gallery.name);
}
2024-06-03 02:10:39 -04:00
const imagesResponse = await fetch('/api/galleries/' + galleryData.gallery.name+ '/images');
const imagesUrls = await imagesResponse.json() as string[];
setImages(imagesUrls);
}
useEffect(() => {
getData();
}, []);
2024-06-03 02:00:05 -04:00
useEffect(() => {
}, [gallery]);
useEffect(() => {
2024-06-02 23:37:41 -04:00
}, [gallery, ]);
useEffect(() => {
}, [ nsfw ]);
useEffect(() => {
}, [tags ]);
useEffect(() => {
}, [galleryName]);
useEffect(() => {
}, [ tier]);
const updateGallery = async () => {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
const formData = new FormData();
2024-06-03 02:38:20 -04:00
formData.append('id', gallery.name);
2024-06-02 23:37:41 -04:00
formData.append('name', galleryName);
2024-06-03 02:00:05 -04:00
formData.append('thumbnail', thumbnail ?? '');
formData.append('originalName', originalName);
formData.append('tags', JSON.stringify(selectedTags));
2024-06-02 23:37:41 -04:00
formData.append('nsfw', nsfw.toString());
formData.append('tier', tier);
2024-06-03 02:00:05 -04:00
const response = await fetch(`/api/galleries/admin/${originalName}`, {
2024-06-02 23:37:41 -04:00
method: 'PUT',
2024-06-03 02:00:05 -04:00
body: formData
2024-06-02 23:37:41 -04:00
});
if (response.ok) {
2024-06-03 02:00:05 -04:00
console.log(response)
2024-06-02 23:37:41 -04:00
const data = await response.json();
} else {
console.log(response)
}
2024-06-03 02:00:05 -04:00
if(originalName != galleryName){
window.location.href=`/gallery/admin/view?id=${galleryName}`
}
else{
window.location.reload();
}
}
const deleteGallery = async () => {
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get('id');
2024-06-03 02:39:11 -04:00
const response = await fetch(`/api/gallery/admin/${gallery.name}`, {
2024-06-03 02:00:05 -04:00
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
});
if (response.ok) {
const data = await response.json();
window.location.href = "/gallery/admin";
} else {
console.log(response)
}
2024-06-02 23:37:41 -04:00
}
2024-06-02 03:48:21 -04:00
return (
2024-06-03 22:21:19 -04:00
<div className="w-full p-8 h-screen text-white flex justify-center items-center animate-in">
<div className="w-full lg:w-1/2 rounded-md p-12 mt-14 ">
2024-06-03 22:21:19 -04:00
<div className="w-full lg:pt-0 pt-32 flex pb-60 justify-center"> {/* Center the gallery thumbnail */}
{gallery != null && (
<GalleryThumbnail
2024-06-02 23:37:41 -04:00
key={"galleryThumbnail"+galleryName+"-"+tags.join("")}
2024-06-03 02:00:05 -04:00
id={originalName}
columns={3}
2024-06-03 02:25:25 -04:00
onSelect={function (id: string, columns: number): void { setOpen(true) }}
title={galleryName}
subscription={tier}
tags={tags}
2024-06-02 23:37:41 -04:00
showNsfw={false}
nsfw={nsfw}
></GalleryThumbnail>
)}
2024-06-02 04:42:34 -04:00
</div>
<div className="w-full flex opacity-90 backdrop-blur-lg bg-primary shadow-lg p-8 pb-0 rounded">
2024-06-02 03:48:21 -04:00
<input
type="text"
className="mb-8 mr-2 rounded-md bg-secondary p-2 w-1/2 text-white"
placeholder="Gallery Name"
value={galleryName}
onChange={(e) => setGalleryName(e.target.value)}
2024-06-03 22:21:19 -04:00
/><div className="w-1/6">
<button
onClick={() => deleteGallery()}
className="text-center w-full bg-error hover:bg-error-light text-white rounded-md p-2 flex items-center justify-center"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5}
stroke="currentColor" className="md:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" />
</svg>
<span className="md:block hidden">Delete</span>
</button>
</div>
<div className="w-1/6">
<button
onClick={() => (window.location.href = "/gallery/admin")}
className="w-full bg-error-dark hover:bg-error text-white rounded-md p-2 ml-2 flex items-center justify-center"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5}
stroke="currentColor" className="md:hidden size-6">
<path strokeLinecap="round" strokeLinejoin="round" d="M9 15 3 9m0 0 6-6M3 9h12a6 6 0 0 1 0 12h-3" />
</svg>
<span className="md:block hidden">Back</span>
</button>
</div>
2024-06-02 04:25:36 -04:00
<div className="w-1/4">
2024-06-02 23:37:41 -04:00
<button onClick={()=>{updateGallery()}} className="w-full bg-success hover:bg-success-light text-white rounded-md p-2 ml-4">
2024-06-03 22:21:19 -04:00
<span>Save</span>
2024-06-02 04:25:36 -04:00
</button>
2024-06-02 03:48:21 -04:00
</div>
2024-06-02 04:25:36 -04:00
</div>
2024-06-03 22:21:19 -04:00
<div className="w-full lg:flex opacity-90 backdrop-blur-lg bg-primary shadow-lg p-8 pt-0 rounded">
<div className="w-full lg:w-1/2 mr-8">
2024-06-03 02:00:05 -04:00
{gallery &&(
2024-06-02 03:48:21 -04:00
<SearchInput
2024-06-03 02:00:05 -04:00
placeholderTags={[
{ value: "tags", label: "❗️ click here to add tags" },
]}
startingTags={gallery.tags}
nsfwButtonEnabled={true}
2024-06-02 03:48:21 -04:00
searchChanged={(search) => {}}
nsfwChanged={(nsfw) => {}}
2024-06-03 02:00:05 -04:00
tagsChanged={(tags) => { setSelectedTags(tags) }}
2024-06-02 03:48:21 -04:00
/>
2024-06-03 02:00:05 -04:00
)}
2024-06-02 03:48:21 -04:00
</div>
2024-06-03 22:21:19 -04:00
<div className="w-full lg:w-1/2 pt-4">
{gallery != null && (<>
<select value={nsfw ? "NSFW" : "SFW"} className="mb-2 shadow-lg rounded-md bg-secondary p-2 w-full text-white" onChange={e=>{
2024-06-03 02:00:05 -04:00
setNsfw(e.target.value == "NSFW");
}}>
2024-06-03 02:00:05 -04:00
<option value="" disabled >Set NSFW</option>
<option value="NSFW" selected={nsfw}>NSFW</option>
2024-06-03 02:00:05 -04:00
<option value="SFW" selected={!nsfw}>SFW</option>
2024-06-02 04:37:59 -04:00
</select>
2024-06-03 02:00:05 -04:00
<select onChange={e=>{
setTier(e.target.value);
}} className="mb-2 shadow-lg mr-2 rounded-md bg-secondary p-2 w-full text-white">
<option value="" disabled >Select New Tier</option>
<option value="Free" selected={tier === "Free"}>Free</option>
<option value="Tier 1" selected={tier === "Tier 1"}>Tier 1</option>
<option value="Tier 2" selected={tier === "Tier 2"}>Tier 2</option>
<option value="Tier 3" selected={tier === "Tier 3"}>Tier 3</option>
2024-06-02 04:37:59 -04:00
</select>
2024-06-03 02:00:05 -04:00
<select onChange={e=>{setThumbnail(e.target.value)}} className="mb-2 shadow-lg mr-2 rounded-md bg-secondary p-2 w-full text-white">
2024-06-02 04:37:59 -04:00
<option value="" disabled selected>Select New Thumbnail</option>
2024-06-03 02:00:05 -04:00
{fileNames.map((name, index) => (
<option selected={name==gallery.thumbnail_file} key={index} value={name}>{name}</option>
))}
2024-06-02 04:35:15 -04:00
</select>
</>
)}
2024-06-02 03:48:21 -04:00
</div>
</div>
2024-06-03 02:25:25 -04:00
{(open) && (
<>
{/*
This is the modal for holding the gallery
*/}
<div
className={`fixed inset-0 transition-opacity z-30 animate-in`}
aria-hidden="true"
>
<div
2024-06-03 02:29:09 -04:00
className="absolute w-full h-full inset-0 bg-secondary-dark opacity-70 z-30"
2024-06-03 02:25:25 -04:00
onClick={() => setOpen(true)}
></div>
2024-06-03 02:29:09 -04:00
<div className="absolute inset-0 overflow-y-auto overflow-x-hidden no-scrollbar pt-2 w-full p-20 h-full z-30">
2024-06-03 02:25:25 -04:00
<Gallery
id={gallery.name}
columns={3}
closeMenu={() => setOpen(false)}
></Gallery>
</div>
2024-06-03 02:10:39 -04:00
</div>
2024-06-03 02:25:25 -04:00
</>
)}
2024-06-02 03:48:21 -04:00
</div>
</div>
);
}
export default PageComponent;