mirror of
https://github.com/D4M13N-D3V/neroshitron.git
synced 2025-03-14 10:05:04 +00:00
chore: formatting
This commit is contained in:
parent
97f2a31951
commit
9b5c3d44c5
@ -1,126 +0,0 @@
|
||||
// "use client";
|
||||
// import { createClient } from "@/utils/supabase/client";
|
||||
// import React, { useState, useEffect } from 'react';
|
||||
// import { User } from "@supabase/supabase-js";
|
||||
// import Search from "@/components/ui/search";
|
||||
|
||||
// function PageComponent() {
|
||||
|
||||
// const supabase = createClient();
|
||||
|
||||
// const [showNSFW, setShowNSFW] = useState<boolean>(true);
|
||||
// const [randomIds, setRandomIds] = useState<string[]>([]); // replace any with your gallery type
|
||||
// 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);
|
||||
// const [selectedGallery, setSelectedGallery] = useState<string | null>(null);
|
||||
// const [search, setSearch] = useState<string>('');
|
||||
// const [galleryColumns, setColumns] = useState<number>(0);
|
||||
// const [selectedTags, setSelectedTags] = useState<string[]>([]);
|
||||
// const generateRandomString = function (length: number) {
|
||||
// let result = '';
|
||||
// let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
// let charactersLength = characters.length;
|
||||
// for (let i = 0; i < length; i++) {
|
||||
// result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
// }
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// const selectGallery = (gallery: string, columns: number) => {
|
||||
// setRandomIds([generateRandomString(3), generateRandomString(3), generateRandomString(3), generateRandomString(3)]);
|
||||
// setSelectedGallery(gallery);
|
||||
// setColumns(columns);
|
||||
// setIsOpen(true);
|
||||
// };
|
||||
|
||||
// const closeGallery = () => {
|
||||
// setSelectedGallery(null);
|
||||
// setColumns(0);
|
||||
// setIsOpen(false);
|
||||
// }
|
||||
|
||||
// const getData = async () => {
|
||||
// let { data: { user } } = await supabase.auth.getUser();
|
||||
// const galleriesResponse = await fetch(`/api/galleries?search=` + search + '&nsfw=' + showNSFW, {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json'
|
||||
// },
|
||||
// body: JSON.stringify({ tags: selectedTags })
|
||||
// });
|
||||
// const galleriesData = await galleriesResponse.json();
|
||||
// setGalleries(galleriesData);
|
||||
// setUser(user);
|
||||
// setLoading(false);
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// getData();
|
||||
// }, [selectedTags, search, showNSFW]);
|
||||
|
||||
|
||||
// return (
|
||||
// <div>
|
||||
// <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">
|
||||
// <img
|
||||
// src="gallery_girl.png"
|
||||
// className="float-right object-cover h-screen w-full lg:w-5/6 xl:w-3/6 opacity-50 overflow-hidden"
|
||||
// alt="Background"
|
||||
// />
|
||||
// </div>
|
||||
|
||||
// <Search
|
||||
// />
|
||||
|
||||
|
||||
// {/*
|
||||
// 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">
|
||||
// {galleries && galleries.map((gallery, index) => (
|
||||
// <div className="mx-auto">
|
||||
// <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>
|
||||
// ))}
|
||||
// </div>
|
||||
// {isOpen ? (
|
||||
// <>
|
||||
// {/*
|
||||
// This is the modal for holding the gallery
|
||||
// */}
|
||||
// <div
|
||||
// className={`fixed inset-0 transition-opacity z-30 ${isOpen ? 'animate-in' : 'fade-out'
|
||||
// }`}
|
||||
// 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>
|
||||
// </>
|
||||
// ) : null}
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
// export default PageComponent;
|
@ -2,14 +2,14 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import GalleryThumbnail from './gallery_thumbnail';
|
||||
|
||||
interface TagProps {
|
||||
interface TagProps {
|
||||
nsfw: boolean;
|
||||
tags: string[];
|
||||
search: string;
|
||||
gallerySelected: (gallery: string) => void;
|
||||
}
|
||||
|
||||
const Galleries = ({ nsfw, tags, search, gallerySelected }:TagProps) => {
|
||||
const Galleries = ({ nsfw, tags, search, gallerySelected }: TagProps) => {
|
||||
|
||||
const [galleries, setGalleries] = useState([]);
|
||||
const [nsfwState, setNsfwState] = useState<boolean>(nsfw);
|
||||
@ -20,7 +20,7 @@ const Galleries = ({ nsfw, tags, search, gallerySelected }:TagProps) => {
|
||||
|
||||
const selectGallery = (gallery: string) => {
|
||||
setSelectedGallery(gallery);
|
||||
gallerySelected(gallery);
|
||||
gallerySelected(gallery);
|
||||
};
|
||||
|
||||
console.log(tags)
|
||||
@ -32,19 +32,19 @@ const Galleries = ({ nsfw, tags, search, gallerySelected }:TagProps) => {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ tags: tagsState })
|
||||
});
|
||||
});
|
||||
const galleriesData = await galleriesResponse.json();
|
||||
setGalleries(galleriesData);
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getData();
|
||||
getData();
|
||||
}, [tagsState]);
|
||||
|
||||
return (
|
||||
<div className="absolute inset-0 mx-auto ml-16 md:ml-0 pt-48 p-4 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-y-60 gap-x-4 animate-in overflow-y-scroll no-scrollbar z-0">
|
||||
|
||||
{galleries && galleries.map((gallery:any, index) => (
|
||||
{galleries && galleries.map((gallery: any, index) => (
|
||||
<GalleryThumbnail
|
||||
key={gallery.name + " " + nsfw}
|
||||
id={gallery.name}
|
||||
|
@ -11,7 +11,7 @@ interface GalleryThumbnailProps {
|
||||
nsfw: boolean;
|
||||
}
|
||||
|
||||
const GalleryThumbnail = ({ id, columns, onSelect, title,showNsfw, nsfw, subscription, tags }: GalleryThumbnailProps) => {
|
||||
const GalleryThumbnail = ({ id, columns, onSelect, title, showNsfw, nsfw, subscription, tags }: GalleryThumbnailProps) => {
|
||||
const [galleryId, setGalleryId] = useState<string>(id);
|
||||
const [thumbnailUrl, setThumbnailUrl] = useState<string>('');
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
|
@ -24,30 +24,29 @@ export default async function AuthButton() {
|
||||
const currentPage = heads.get('x-path')
|
||||
|
||||
const getGravatarUrl = () => {
|
||||
if(user==null)
|
||||
{
|
||||
if (user == null) {
|
||||
return;
|
||||
}
|
||||
let email = user.email;
|
||||
if(email != null){
|
||||
if (email != null) {
|
||||
const emailHash = crypto.createHash('md5').update(email.trim().toLowerCase()).digest('hex');
|
||||
return `https://www.gravatar.com/avatar/${emailHash}`;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
const url = getGravatarUrl();
|
||||
return(
|
||||
return (
|
||||
<div className="flex justify-center items-center pt-2 ">
|
||||
<nav className="w-auto bg-neroshi-blue-300 bg-opacity-10 flex justify-center z-10 h-16 animate-in rounded-md" style={{ backdropFilter: 'blur(10px)' }}>
|
||||
<div className="w-full max-w-2xl flex justify-between items-center p-3 text-sm">
|
||||
<nav className="w-auto bg-neroshi-blue-300 bg-opacity-10 flex justify-center z-10 h-16 animate-in rounded-md" style={{ backdropFilter: 'blur(10px)' }}>
|
||||
<div className="w-full max-w-2xl flex justify-between items-center p-3 text-sm">
|
||||
<div className="flex items-center gap-2 z-10">
|
||||
<Link
|
||||
href="/gallery"
|
||||
className={`py-2 px-3 flex rounded-md no-underline ${currentPage === '/gallery' ? 'bg-neroshi-blue-800 hover:bg-neroshi-blue-700' : 'bg-neroshi-blue-900 hover:bg-neroshi-blue-800'}`}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
|
||||
</svg>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
|
||||
</svg>
|
||||
|
||||
<span className="hidden lg:block">Gallery</span>
|
||||
</Link>
|
||||
@ -80,28 +79,28 @@ export default async function AuthButton() {
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{(user!=null) ? (
|
||||
{(user != null) ? (
|
||||
<>
|
||||
<form action={signOut}>
|
||||
<button className="py-2 px-4 ml-2 rounded-md no-underline bg-pink-950 hover:bg-pink-900">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 md:hidden ">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 10.5V6.75a4.5 4.5 0 1 1 9 0v3.75M3.75 21.75h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H3.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z" />
|
||||
</svg>
|
||||
<span className="hidden lg:block">Logout</span>
|
||||
</button>
|
||||
</form>
|
||||
<img src={url} alt="Profile" className="w-10 h-10 object-cover rounded-full cursor-pointer" />
|
||||
</>
|
||||
<form action={signOut}>
|
||||
<button className="py-2 px-4 ml-2 rounded-md no-underline bg-pink-950 hover:bg-pink-900">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 md:hidden ">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 10.5V6.75a4.5 4.5 0 1 1 9 0v3.75M3.75 21.75h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H3.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z" />
|
||||
</svg>
|
||||
<span className="hidden lg:block">Logout</span>
|
||||
</button>
|
||||
</form>
|
||||
<img src={url} alt="Profile" className="w-10 h-10 object-cover rounded-full cursor-pointer" />
|
||||
</>
|
||||
) : (
|
||||
<Link
|
||||
href="/subscriptions"
|
||||
className={`ml-2 py-2 px-3 flex rounded-md no-underline ${currentPage === '/gallery' ? 'bg-neroshi-blue-800 hover:bg-neroshi-blue-700' : 'bg-neroshi-blue-900 hover:bg-neroshi-blue-800'}`}
|
||||
>
|
||||
href="/subscriptions"
|
||||
className={`ml-2 py-2 px-3 flex rounded-md no-underline ${currentPage === '/gallery' ? 'bg-neroshi-blue-800 hover:bg-neroshi-blue-700' : 'bg-neroshi-blue-900 hover:bg-neroshi-blue-800'}`}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6 lg:hidden block">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
|
||||
</svg>
|
||||
<span className="hidden lg:block">Login</span>
|
||||
</Link>
|
||||
<span className="hidden lg:block">Login</span>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,11 +3,11 @@ import React, { useState, useEffect } from 'react';
|
||||
import SearchInput from '@/components/neroshitron/search_input';
|
||||
import Galleries from './galleries';
|
||||
|
||||
interface SearchProps {
|
||||
interface SearchProps {
|
||||
gallerySelected: (gallery: string) => void;
|
||||
}
|
||||
|
||||
const Search = ({gallerySelected }:SearchProps) => {
|
||||
const Search = ({ gallerySelected }: SearchProps) => {
|
||||
const [tags, setTags] = useState<string[]>([]);
|
||||
const [search, setSearch] = useState<string>('');
|
||||
const [nsfw, setNsfw] = useState<boolean>(false);
|
||||
@ -27,10 +27,10 @@ const Search = ({gallerySelected }:SearchProps) => {
|
||||
}, [tags]);
|
||||
useEffect(() => {
|
||||
getData();
|
||||
if(gallery!=null)
|
||||
if (gallery != null)
|
||||
gallerySelected(gallery);
|
||||
}, [gallery]);
|
||||
//TRY TESTING WITH THIS REMOVED!
|
||||
//TRY TESTING WITH THIS REMOVED!
|
||||
|
||||
|
||||
|
||||
@ -38,17 +38,17 @@ const Search = ({gallerySelected }:SearchProps) => {
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Galleries gallerySelected={(gallery:string)=>{setGallery(gallery)}} key={search+"-"+tags.length+"-"+nsfw} search={search} nsfw={nsfw} tags={tags} />
|
||||
|
||||
return (
|
||||
<>
|
||||
<Galleries gallerySelected={(gallery: string) => { setGallery(gallery) }} key={search + "-" + tags.length + "-" + nsfw} search={search} nsfw={nsfw} tags={tags} />
|
||||
<section className="fixed flex items-center w-full p-8 pt-20 opacity-90 animate-in animate-once animate-duration-500">
|
||||
<div className="container mx-auto py-8">
|
||||
<SearchInput searchChanged={(search)=>{setSearch(search)}} nsfwChanged={(nsfw)=>{setNsfw(nsfw)}} tagsChanged={(tags)=>{setTags(tags);}} />
|
||||
</div>
|
||||
<div className="container mx-auto py-8">
|
||||
<SearchInput searchChanged={(search) => { setSearch(search) }} nsfwChanged={(nsfw) => { setNsfw(nsfw) }} tagsChanged={(tags) => { setTags(tags); }} />
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Search;
|
@ -1,5 +1,5 @@
|
||||
"use client;"
|
||||
import React, { useState, useEffect, useRef,forwardRef } from 'react';
|
||||
import React, { useState, useEffect, useRef, forwardRef } from 'react';
|
||||
import TagSelector from '../neroshitron/tag_selector';
|
||||
import Select from "react-tailwindcss-select";
|
||||
import { SelectValue } from 'react-tailwindcss-select/dist/components/type';
|
||||
@ -11,7 +11,7 @@ interface SearchInputProps {
|
||||
nsfwChanged: (nsfw: boolean) => void;
|
||||
}
|
||||
|
||||
const SearchInput = ({ tagsChanged, searchChanged, nsfwChanged}: SearchInputProps) => {
|
||||
const SearchInput = ({ tagsChanged, searchChanged, nsfwChanged }: SearchInputProps) => {
|
||||
|
||||
const [tagSearch, setTagSearch] = useState<string>('');
|
||||
const [nsfw, setNsfw] = useState<boolean>(false);
|
||||
@ -34,13 +34,13 @@ const SearchInput = ({ tagsChanged, searchChanged, nsfwChanged}: SearchInputProp
|
||||
setSelectedTags(newTags)
|
||||
}
|
||||
|
||||
const onTagsClosed = (tags:string[]) => {
|
||||
const onTagsClosed = (tags: string[]) => {
|
||||
setSelectingTags(false);
|
||||
}
|
||||
|
||||
const openTags = () => {
|
||||
setSelectingTags(true);
|
||||
if(selectingTags){
|
||||
if (selectingTags) {
|
||||
onTagsClosed(selectedTags);
|
||||
}
|
||||
}
|
||||
@ -62,69 +62,54 @@ const SearchInput = ({ tagsChanged, searchChanged, nsfwChanged}: SearchInputProp
|
||||
<div className="relative md:w-full lg:w-1/2 mx-auto flex flex-col items-center justify-center z-10">
|
||||
<div className="search-box mx-auto my-auto w-full sm:w-full md:w-full lg:w-3/4 xl:w-3/4">
|
||||
<div className="flex flex-row">
|
||||
|
||||
|
||||
{(selectingTags) ? (
|
||||
<>
|
||||
<input autoFocus value={tagSearch} onChange={(e) => setTagSearch(e.target.value)} className="rounded-l-md h-16 bg-gray-100 text-grey-darker py-2 font-normal text-grey-darkest border border-gray-100 font-bold w-full py-1 px-2 outline-none text-lg text-gray-600" type="text" placeholder="Looking for specific tag?" />
|
||||
|
||||
<span className="flex items-center bg-gray-100 rounded rounded-l-none border-0 px-3 font-bold text-grey-100">
|
||||
<button key="back" onClick={()=>{openTags()}} type="button" className={`animate-in bg-pink-900 hover:bg-pink-800 text-lg text-white font-bold py-3 px-6 rounded`}>
|
||||
Back
|
||||
</button>
|
||||
|
||||
</span>
|
||||
<input autoFocus value={tagSearch} onChange={(e) => setTagSearch(e.target.value)} className="rounded-l-md h-16 bg-gray-100 text-grey-darker py-2 font-normal text-grey-darkest border border-gray-100 font-bold w-full py-1 px-2 outline-none text-lg text-gray-600" type="text" placeholder="Looking for specific tag?" />
|
||||
|
||||
<span className="flex items-center bg-gray-100 rounded rounded-l-none border-0 px-3 font-bold text-grey-100">
|
||||
<button key="back" onClick={() => { openTags() }} type="button" className={`animate-in bg-pink-900 hover:bg-pink-800 text-lg text-white font-bold py-3 px-6 rounded`}>
|
||||
Back
|
||||
</button>
|
||||
|
||||
</span>
|
||||
</>
|
||||
)
|
||||
:(
|
||||
<>
|
||||
<Select isMultiple isSearchable isClearable searchInputPlaceholder='Start typing to search tags...' options={tagOptions} placeholder="Start typing to search tags..."
|
||||
|
||||
onChange={(value: Option | Option[] | null) => {
|
||||
if (value === null) {
|
||||
setSelectedTags([]);
|
||||
setSelectedTagsInput([]);
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
setSelectedTags(value.map((option) => option.value));
|
||||
setSelectedTagsInput(value as Option[])
|
||||
} else if (value) {
|
||||
setSelectedTags([value.value]);
|
||||
setSelectedTagsInput([value])
|
||||
}
|
||||
} }
|
||||
|
||||
value={selectedTagsInput} primaryColor={'neroshi-blue'}/>
|
||||
<span className="flex items-center rounded rounded-l-none border-0 px-3 font-bold text-grey-100">
|
||||
{/* <div className="relative">
|
||||
<button key="tags" data-tip={selectedTags.join(',')} onClick={()=>{openTags()}} type="button" className={`bg-neroshi-blue-900 hover:bg-neroshi-blue-800 text-lg text-white font-bold py-3 px-6 rounded ${selectedTags.length == 0 ? 'animate-pulse animate-infinite animate-ease-out' : 'animate-in'}`}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor" className="size-6">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M6 6h.008v.008H6V6Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<span className="absolute top-8 left-14 inline-block w-6 h-6 </svg>text-xs bg-pink-800 text-white rounded-full flex items-center justify-center">
|
||||
{selectedTags.length}
|
||||
</span>
|
||||
</div> */}
|
||||
|
||||
|
||||
<button
|
||||
onClick={()=>{ setNsfw(!nsfw) }}
|
||||
type="button"
|
||||
className={`animate-in text-sm text-white font-bold py-1 w-16 px-2 rounded ml-2 ${nsfw ? "bg-pink-900 hover:bg-pink-800":"bg-green-900 hover:bg-green-800"}`}
|
||||
|
||||
>
|
||||
{nsfw ? "NSFW" : "SFW"}
|
||||
</button>
|
||||
</span>
|
||||
</>
|
||||
: (
|
||||
<>
|
||||
<Select isMultiple isSearchable isClearable searchInputPlaceholder='Start typing to search tags...'
|
||||
options={tagOptions}
|
||||
onChange={(value: Option | Option[] | null) => {
|
||||
if (value === null) {
|
||||
setSelectedTags([]);
|
||||
setSelectedTagsInput([]);
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
setSelectedTags(value.map((option) => option.value));
|
||||
setSelectedTagsInput(value as Option[])
|
||||
} else if (value) {
|
||||
setSelectedTags([value.value]);
|
||||
setSelectedTagsInput([value])
|
||||
}
|
||||
}}
|
||||
value={selectedTagsInput} primaryColor={'neroshi-blue'} />
|
||||
<span className="flex items-center rounded rounded-l-none border-0 px-3 font-bold text-grey-100">
|
||||
<button
|
||||
onClick={() => { setNsfw(!nsfw) }}
|
||||
type="button"
|
||||
className={`animate-in text-sm text-white font-bold py-1 w-16 px-2 rounded ml-2 ${nsfw ? "bg-pink-900 hover:bg-pink-800" : "bg-green-900 hover:bg-green-800"}`}
|
||||
|
||||
)}
|
||||
>
|
||||
{nsfw ? "NSFW" : "SFW"}
|
||||
</button>
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{(selectingTags) &&
|
||||
<TagSelector key={tagSearch} tagSearch={tagSearch} tagsChanged={(newTags:string[])=>{ updateTags(newTags) }} selectedTagsInput={selectedTags} ref={tagSelectorRef} />}
|
||||
{(selectingTags) &&
|
||||
<TagSelector key={tagSearch} tagSearch={tagSearch} tagsChanged={(newTags: string[]) => { updateTags(newTags) }} selectedTagsInput={selectedTags} ref={tagSelectorRef} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,20 +1,20 @@
|
||||
"use client;"
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
interface TagProps { onTagClicked: (tag: string ) => void, selected:boolean, tag:string }
|
||||
interface TagProps { onTagClicked: (tag: string) => void, selected: boolean, tag: string }
|
||||
|
||||
const Tag = ({ onTagClicked, selected, tag, }:TagProps) => {
|
||||
const Tag = ({ onTagClicked, selected, tag, }: TagProps) => {
|
||||
|
||||
return (
|
||||
<button
|
||||
key={tag}
|
||||
type="button"
|
||||
className={`animate-in w-full h-8 rounded-md no-underline text-sm text-white py-1 font-medium text-center ${selected ? 'hover:bg-pink-800 bg-pink-900' : 'hover:bg-pink-600 bg-neroshi-blue-800 border-neroshi-blue-900 border-2'}`}
|
||||
onClick={() => onTagClicked(tag)}
|
||||
>
|
||||
{tag}
|
||||
</button>
|
||||
);
|
||||
return (
|
||||
<button
|
||||
key={tag}
|
||||
type="button"
|
||||
className={`animate-in w-full h-8 rounded-md no-underline text-sm text-white py-1 font-medium text-center ${selected ? 'hover:bg-pink-800 bg-pink-900' : 'hover:bg-pink-600 bg-neroshi-blue-800 border-neroshi-blue-900 border-2'}`}
|
||||
onClick={() => onTagClicked(tag)}
|
||||
>
|
||||
{tag}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tag;
|
@ -2,13 +2,13 @@
|
||||
import React, { forwardRef, useState, useEffect } from 'react';
|
||||
import Tag from './tag_pill';
|
||||
|
||||
interface TagSelectorProps {
|
||||
interface TagSelectorProps {
|
||||
tagSearch: string,
|
||||
selectedTagsInput: string[],
|
||||
tagsChanged: (tags: string[]) => void
|
||||
}
|
||||
}
|
||||
|
||||
const TagSelector = forwardRef<TagSelectorProps, {tagSearch: string, selectedTagsInput: string[], tagsChanged: (tags: string[]) => void }>((props, ref) => {
|
||||
const TagSelector = forwardRef<TagSelectorProps, { tagSearch: string, selectedTagsInput: string[], tagsChanged: (tags: string[]) => void }>((props, ref) => {
|
||||
|
||||
const [tags, setTags] = useState<any[]>([]);
|
||||
const [tagSearch, setTagSearch] = useState<string>(props.tagSearch);
|
||||
@ -29,44 +29,35 @@ const TagSelector = forwardRef<TagSelectorProps, {tagSearch: string, selectedTag
|
||||
const tagsResponse = await fetch(`/api/galleries/tags`);
|
||||
const tagsData = await tagsResponse.json();
|
||||
setTags(tagsData);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
props.tagsChanged(selectedTags);
|
||||
getData();
|
||||
}, [selectedTags,tagSearch]);
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
props.tagsChanged(selectedTags);
|
||||
getData();
|
||||
}, [selectedTags,tagSearch]);
|
||||
}, [selectedTags, tagSearch]);
|
||||
|
||||
useEffect(() => {
|
||||
props.tagsChanged(selectedTags);
|
||||
getData();
|
||||
}, [selectedTags, tagSearch]);
|
||||
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
const generateRandomString = () => {
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
for (let i = 0; i < 10; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
console.log(tags.length)
|
||||
return (
|
||||
|
||||
<div className="flex md:w-full pt-4 justify-center items-center">
|
||||
return (
|
||||
|
||||
<div className="flex md:w-full pt-4 justify-center items-center">
|
||||
{(tags.length > 0) && (
|
||||
<div className="z-10 grid p-4 grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-1 w-full max-h-96 overflow-y-scroll no-scrollbar pt-4 bg-neroshi-blue-900 rounded-md opacity-90 backdrop-filter backdrop-blur-md mx-auto">
|
||||
<div className="z-10 grid p-4 grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-1 w-full max-h-96 overflow-y-scroll no-scrollbar pt-4 bg-neroshi-blue-900 rounded-md opacity-90 backdrop-filter backdrop-blur-md mx-auto">
|
||||
{tags.map((tag: any) => (
|
||||
(tagSearch === '' || tag.name.toLowerCase().includes(tagSearch.toLowerCase())) && // Updated condition
|
||||
<Tag tag={tag.name} selected={selectedTags.includes(tag.name)} onTagClicked={(tag) => handleTag(tag)} />
|
||||
))}
|
||||
</div>
|
||||
(tagSearch === '' || tag.name.toLowerCase().includes(tagSearch.toLowerCase())) && // Updated condition
|
||||
<Tag tag={tag.name} selected={selectedTags.includes(tag.name)} onTagClicked={(tag) => handleTag(tag)} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default TagSelector;
|
@ -1,96 +0,0 @@
|
||||
"use client;"
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import TagSelector from './tag_selector';
|
||||
|
||||
interface SearchProps { }
|
||||
|
||||
const Search = ({ }:SearchProps) => {
|
||||
const [nsfw, setNsfw] = useState<boolean>(false);
|
||||
const [tags, setTags] = useState<any[]>([]);
|
||||
const [search, setSearch] = useState<string>('');
|
||||
const [selectedTags, setSelectedTagsState] = useState<string[]>([]);
|
||||
const [selectingTags, setSelectingTags] = useState<boolean>(false);
|
||||
|
||||
const getNsfw = () => {
|
||||
return nsfw;
|
||||
};
|
||||
|
||||
const getTags = () => {
|
||||
return tags;
|
||||
};
|
||||
|
||||
const getSearch = () => {
|
||||
return search;
|
||||
};
|
||||
|
||||
const getSelectedTags = () => {
|
||||
return selectedTags;
|
||||
};
|
||||
|
||||
const getData = async () => {
|
||||
const tagsResponse = await fetch(`/api/galleries/tags`);
|
||||
const tagsData = await tagsResponse.json();
|
||||
setTags(tagsData);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, [selectingTags]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="flex items-center w-full p-8 pt-20 opacity-90 animate-jump-in animate-once animate-duration-500">
|
||||
{(tags.length > 0) ? (
|
||||
<div className="container mx-auto py-8">
|
||||
<div className="relative w-full mx-auto">
|
||||
<input
|
||||
className="animate-in animate-delay-[2000ms] 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)}
|
||||
/>
|
||||
<div className="absolute right-0 top-0 h-full mr-2 flex items-center">
|
||||
<label htmlFor="toggleNSFW" className="text-neroshi-blue-950 animate-in animate-delay-[2000ms] animate-ease-out">
|
||||
Censor NSFW
|
||||
<input
|
||||
id="toggleNSFW"
|
||||
type="checkbox"
|
||||
onChange={(e) => setNsfw(e.target.checked)}
|
||||
className="form-checkbox h-5 w-5 text-neroshi-blue-950 ml-2"
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<nav className="pt-6 grid grid-cols-3 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-10 gap-4 justify-items-center">
|
||||
{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="#"
|
||||
>
|
||||
{tag.name}
|
||||
</a>
|
||||
))}
|
||||
<a
|
||||
key={"select-tags"}
|
||||
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 bg-pink-800 hover:bg-pink-700`}
|
||||
href="#"
|
||||
onClick={() => setSelectingTags(true)}
|
||||
>
|
||||
Select Tags : {selectingTags}
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
) : (
|
||||
<div className="animate-pulse bg-neroshi-blue-950 rounded-3xl w-full p-8 mt-10 h-48"></div>
|
||||
)}
|
||||
{(selectingTags) ??(
|
||||
<TagSelector/>
|
||||
)}
|
||||
</section>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Search;
|
@ -1,27 +0,0 @@
|
||||
"use client;"
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
interface SearchProps { }
|
||||
|
||||
const TagSelector = ({ }:SearchProps) => {
|
||||
|
||||
|
||||
const getData = async () => {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={`fixed inset-0 transition-opacity z-30 animate-in`} aria-hidden="true" >
|
||||
<div className="absolute inset-0 bg-neroshi-blue-900 opacity-70 z-30">
|
||||
</div>
|
||||
<div className="absolute inset-0 overflow-y-auto overflow-x-hidden no-scrollbar pt-2 w-full p-20 z-30">
|
||||
Test
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TagSelector;
|
Loading…
x
Reference in New Issue
Block a user