feat: search components

This commit is contained in:
Damien Ostler 2024-06-01 01:57:45 -04:00
parent 22df3ab0fd
commit e86a8fa481
6 changed files with 60 additions and 39 deletions

View File

@ -54,8 +54,8 @@ export async function GET(
.select('*') .select('*')
.eq('user_id', userId) .eq('user_id', userId)
.single(); .single();
console.log(subscription) //console.log(subscription)
console.log(gallery.tier) //console.log(gallery.tier)
switch(gallery.tier){ switch(gallery.tier){
case "Tier 3": case "Tier 3":
if(subscription?.tier!="Tier 3"){ if(subscription?.tier!="Tier 3"){

View File

@ -20,10 +20,6 @@ export default async function AuthButton() {
return redirect("/login"); return redirect("/login");
}; };
// ...
const heads = headers() const heads = headers()
const currentPage = heads.get('x-path') const currentPage = heads.get('x-path')

View File

@ -6,7 +6,9 @@ import SearchInput from '@/components/neroshitron/search_input';
interface SearchProps { } interface SearchProps { }
const Search = ({ }:SearchProps) => { const Search = ({ }:SearchProps) => {
const [tags, setTags] = useState<any[]>([]); const [tags, setTags] = useState<string[]>([]);
const [search, setSearch] = useState<string>('');
const [nsfw, setNsfw] = useState<boolean>(false);
const [selectingTags, setSelectingTags] = useState<boolean>(false); const [selectingTags, setSelectingTags] = useState<boolean>(false);
const getData = async () => { const getData = async () => {
@ -20,7 +22,7 @@ const Search = ({ }:SearchProps) => {
<> <>
<section className="fixed flex items-center w-full p-8 pt-20 opacity-90 animate-in animate-once animate-duration-500"> <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"> <div className="container mx-auto py-8">
<SearchInput /> <SearchInput searchChanged={(search)=>{setSearch(search)}} nsfwChanged={(nsfw)=>{setNsfw(nsfw)}} tagsChanged={(tags)=>{setTags(tags);}} />
</div> </div>
</section> </section>
</> </>

View File

@ -4,23 +4,27 @@ import { on } from 'events';
import TagSelector from '../neroshitron/tag_selector'; import TagSelector from '../neroshitron/tag_selector';
interface SearchInputProps { interface SearchInputProps {
tagsChanged: (tags: string[]) => void;
searchChanged: (search: string) => void;
nsfwChanged: (nsfw: boolean) => void;
} }
const SearchInput = ({ }: SearchInputProps) => { const SearchInput = ({ tagsChanged, searchChanged, nsfwChanged}: SearchInputProps) => {
const [search, setSearch] = useState<string>(''); const [search, setSearch] = useState<string>('');
const [nsfw, setNsfw] = useState<boolean>(false); const [nsfw, setNsfw] = useState<boolean>(false);
const [selectedTags, setSelectedTags] = useState<string[]>([]); const [selectedTags, setSelectedTags] = useState<string[]>([]);
const [selectingTags, setSelectingTags] = useState<boolean>(false); const [selectingTags, setSelectingTags] = useState<boolean>(false);
const tagSelectorRef = React.useRef(null); const tagSelectorRef = React.useRef(null);
const updateTags = (newTags: string[]) => {
setSelectedTags(newTags)
tagsChanged(newTags);
}
const onTagsClosed = (tags:string[]) => { const onTagsClosed = (tags:string[]) => {
if(tagSelectorRef.current !== null){
setSelectedTags((tagSelectorRef.current as any).getSelectedTags());
}
setSelectingTags(false); setSelectingTags(false);
setSelectedTags(tags);
} }
const openTags = () => { const openTags = () => {
@ -30,6 +34,14 @@ const SearchInput = ({ }: SearchInputProps) => {
} }
} }
const getData = async () => {
setSelectedTags(selectedTags)
}
useEffect(() => {
getData();
}, [selectedTags]);
return ( return (
<> <>
<div className="relative md:w-full lg:w-1/2 mx-auto flex flex-col items-center justify-center"> <div className="relative md:w-full lg:w-1/2 mx-auto flex flex-col items-center justify-center">
@ -48,7 +60,7 @@ const SearchInput = ({ }: SearchInputProps) => {
</div> </div>
</div> </div>
</div> </div>
{(selectingTags) && <TagSelector ref={tagSelectorRef} />} {(selectingTags) && <TagSelector tagsChanged={(newTags:string[])=>{ updateTags(newTags) }} selectedTagsInput={selectedTags} ref={tagSelectorRef} />}
</> </>
); );
}; };

View File

@ -6,14 +6,14 @@ interface TagProps { onTagClicked: (tag: string ) => void, selected:boolean, tag
const Tag = ({ onTagClicked, selected, tag, }:TagProps) => { const Tag = ({ onTagClicked, selected, tag, }:TagProps) => {
return ( return (
<a <button
key={"select-tags"} key={tag+"-button"}
type="button"
className={`w-full m-4 rounded-md no-underline text-white py-1 font-medium text-center ${selected ? 'hover:bg-pink-800 bg-pink-900' : 'hover:bg-neroshi-blue-700 bg-neroshi-blue-800'}`} className={`w-full m-4 rounded-md no-underline text-white py-1 font-medium text-center ${selected ? 'hover:bg-pink-800 bg-pink-900' : 'hover:bg-neroshi-blue-700 bg-neroshi-blue-800'}`}
href="#"
onClick={() => onTagClicked(tag)} onClick={() => onTagClicked(tag)}
> >
{tag} {tag}
</a> </button>
); );
}; };

View File

@ -5,44 +5,55 @@ import Tag from './tag_pill';
import Masonry from 'react-masonry-css'; import Masonry from 'react-masonry-css';
interface TagSelectorProps { interface TagSelectorProps {
selectedTagsInput: string[],
tagsChanged: (tags: string[]) => void
} }
const TagSelector = forwardRef<TagSelectorProps, {}>((props, ref) => { const TagSelector = forwardRef<TagSelectorProps, { selectedTagsInput: string[], tagsChanged: (tags: string[]) => void }>((props, ref) => {
const [tags, setTags] = useState<any[]>([]); const [tags, setTags] = useState<any[]>([]);
const [selectedTags, setSelectedTags] = useState<string[]>([]); const [selectedTags, setSelectedTags] = useState<string[]>(props.selectedTagsInput);
const supabase = createClient();
useImperativeHandle(ref, () => ({
getSelectedTags: () => {
return tags.map(tag => tag.name);
},
}));
const getData = async () => {
const tagsResponse = await fetch(`/api/galleries/tags`);
const tagsData = await tagsResponse.json();
setTags(tagsData);
}
const handleTag = (tag: string) => { const handleTag = (tag: string) => {
if (selectedTags.includes(tag)) { if (selectedTags.includes(tag)) {
setSelectedTags(selectedTags.filter(t => t !== tag)); setSelectedTags(selectedTags.filter(t => t !== tag));
} else { } else {
setSelectedTags([...selectedTags, tag]); setSelectedTags([...selectedTags, tag]);
} }
setTags(selectedTags);
}; };
const getData = async () => {
const tagsResponse = await fetch(`/api/galleries/tags`);
const tagsData = await tagsResponse.json();
setTags(tagsData);
}
const generateRandomString = (length: number): string => {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
result += characters.charAt(randomIndex);
}
return result;
};
useEffect(() => {
props.tagsChanged(selectedTags);
getData();
}, [selectedTags]);
useEffect(() => { useEffect(() => {
getData(); getData();
}, []); }, []);
console.log(selectedTags)
return ( return (
<div className="flex md:w-full lg:w-1/2 animate-in mx-auto pt-4"> <div className="flex md:w-full lg:w-1/2 animate-in mx-auto pt-4">
<div className="grid grid-cols-6 gap-4 w-full animate-in mx-auto pt-4 bg-neroshi-blue-900 pr-8 pb-4 rounded-md"> <div className="grid grid-cols-6 gap-4 w-full mx-auto pt-4 bg-neroshi-blue-900 pr-8 pb-4 rounded-md opacity-75 backdrop-filter backdrop-blur-md">
{tags.map((tag: any) => ( {tags.map((tag: any) => (
<Tag key={tag.id} tag={tag.name} selected={selectedTags.includes(tag.name)} onTagClicked={(tag) => handleTag(tag)} /> <Tag key={tag.name} tag={tag.name} selected={selectedTags.includes(tag.name)} onTagClicked={(tag) => handleTag(tag)} />
))} ))}
</div> </div>
</div> </div>