Skip to content

Commit

Permalink
feat(voting): ✨ Introducing voting
Browse files Browse the repository at this point in the history
  • Loading branch information
julianYaman committed Jul 3, 2022
1 parent a4de5d5 commit d690048
Show file tree
Hide file tree
Showing 13 changed files with 771 additions and 335 deletions.
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"tools",
"partnerPage",
"footer",
"auth"
"auth",
"voting"
]
}
27 changes: 26 additions & 1 deletion components/CategoryMain.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
import { useUser } from "@supabase/auth-helpers-react";
import { Table } from "flowbite-react";
import toast, { Toaster } from "react-hot-toast";
import { supabase } from "../util/supabase";
import EmbeddedSearchbar from "./EmbeddedSearchbar";
import ToolTableRow from "./ToolTableRow";

export default function CategoryMain(props: any) {

const { user, error } = useUser();
const supabaseCallUser = supabase.auth.user()

const userInfo = user || supabaseCallUser || null


const notifications = {
"noLoginVote": () => toast.error('You need to login first before voting!', {icon: "🙈", position: "bottom-center", duration: 3000}),
"voteAdded": (promise:Promise<{}>) => toast.promise(promise, {
loading: 'Adding vote...',
success: <b>Voted!</b>,
error: <b>Sorry, an error happened. Please try again later.</b>
}, {position: "bottom-center", duration: 2000}).then((r) => r).catch((error) => console.error(error)),
"voteRemoved": (promise:Promise<{}>) => toast.promise(promise, {
loading: 'Remove vote...',
success: <b>Vote removed!</b>,
error: <b>Sorry, an error happened. Please try again later.</b>
}, {position: "bottom-center", duration: 2000}).then((r) => r).catch((error) => console.error(error)),
"voteError": () => toast.error('An error occurred while trying to vote / unvote!', {position: "bottom-center", duration: 3000}),
}

// Show the tool page depending on the id of the tool
return (
<section className="text-white-900 body-font">
<Toaster />
<div className="container flex flex-wrap flex-col max-w-6xl mx-auto pt-40 pb-6 p-5">
<EmbeddedSearchbar />
</div>
Expand Down Expand Up @@ -38,7 +63,7 @@ export default function CategoryMain(props: any) {
{
props.categoryResults.map((tool: any, index: number) => {
return (
<ToolTableRow key={tool.tools.id} row={tool.tools} showSubmittedBy={true} />
<ToolTableRow key={tool.tools.id} notifications={notifications} userInfo={userInfo} row={tool.tools} showSubmittedBy={true} />
)
})
}
Expand Down
25 changes: 24 additions & 1 deletion components/EmbeddedSearchbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ import Link from 'next/link'
import axios from 'axios'
import { useState } from 'react';
import ToolTableRow from './ToolTableRow';
import toast from 'react-hot-toast';
import { supabase } from '../util/supabase';
import { useUser } from '@supabase/auth-helpers-react';


export default function EmbeddedSearchbar(props: any) {

const [results, setResults] = useState([])
const [tableVisible, setTableVisibility] = useState(false)

const { user, error } = useUser();
const supabaseCallUser = supabase.auth.user()

const userInfo = user || supabaseCallUser || null

const showSearchResults = async (searchTerm: string) => {

if (searchTerm.length > 3){
Expand All @@ -31,6 +39,21 @@ export default function EmbeddedSearchbar(props: any) {

}

const notifications = {
"noLoginVote": () => toast.error('You need to login first before voting!', {icon: "🙈", position: "bottom-center", duration: 3000}),
"voteAdded": (promise:Promise<{}>) => toast.promise(promise, {
loading: 'Adding vote...',
success: <b>Voted!</b>,
error: <b>Sorry, an error happened. Please try again later.</b>
}, {position: "bottom-center", duration: 2000}).then((r) => r).catch((error) => console.error(error)),
"voteRemoved": (promise:Promise<{}>) => toast.promise(promise, {
loading: 'Remove vote...',
success: <b>Vote removed!</b>,
error: <b>Sorry, an error happened. Please try again later.</b>
}, {position: "bottom-center", duration: 2000}).then((r) => r).catch((error) => console.error(error)),
"voteError": () => toast.error('An error occurred while trying to vote / unvote!', {position: "bottom-center", duration: 3000}),
}

return (
<div className='relative w-full'>
<TextInput
Expand Down Expand Up @@ -65,7 +88,7 @@ export default function EmbeddedSearchbar(props: any) {
results.length > 0 ? (
results.map((row: any, index: number) => {
return (
<ToolTableRow key={row.id} row={row} showSubmittedBy={false} showCategories={true} />
<ToolTableRow key={row.id} row={row} notifications={notifications} userInfo={userInfo} showSubmittedBy={false} showCategories={true} />
)
})
) : (
Expand Down
61 changes: 58 additions & 3 deletions components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
import {useState} from "react";
import Image from "next/image"
import Link from "next/link";
import Logo from "../assets/default-monochrome-white.svg"
import { SiDiscord, SiTwitter } from "react-icons/si";
import { Button } from "flowbite-react";
import { Avatar, Button, Dropdown, Spinner } from "flowbite-react";
import LoginModal from "./LoginModal";
import { useUser } from '@supabase/auth-helpers-react';
import { supabase } from "../util/supabase";
import { Suspense, useEffect, useState } from 'react';

export default function Header() {
export default function Header(props:any) {

const [navbarOpen, setNavbarOpen] = useState(false);
const [showLoginModal, setShowLoginModal] = useState(false);
const [isLoading, setIsLoading] = useState(true);

const { user, error } = useUser();
const [ userData, setUserData] : any = useState({username: "loading..."});

const supabaseCallUser = supabase.auth.user()

useEffect(() => {
setIsLoading(false);
async function loadData(user:any) {
const { data } : any = await supabase.from('profiles').select('*').eq("user_id", user?.id);
setUserData(data[0]);
}
if (user) {
loadData(user);
}
if(supabaseCallUser){
loadData(supabaseCallUser)
}
}, [user]);

return (
<header className="fixed top-0 w-full clearNav z-50">
Expand Down Expand Up @@ -103,12 +126,44 @@ export default function Header() {
>
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/julianyaman/tooldb?style=social" />
</a>
{ isLoading ? (<Spinner aria-label="Loading" size='xl' color="yellow" />) : (
<Suspense fallback={<div className="text-center"><Spinner aria-label="Loading" size='xl' color="red" /></div>}>
{ supabaseCallUser ? (
<Dropdown size="sm" color="blue" outline={!!supabaseCallUser} label={supabaseCallUser.user_metadata.full_name ?
(<Avatar
img={supabaseCallUser.user_metadata.avatar_url}
rounded={true}
size="xs"
>
</Avatar>) : <span>{supabaseCallUser.user_metadata.full_name || userData.username || supabaseCallUser.email}</span> }>
<Dropdown.Header>
<span className="block text-sm">
{supabaseCallUser.user_metadata.full_name || userData.username || supabaseCallUser.email }
</span>
<span className="block truncate text-xs font-medium">
{supabaseCallUser.email}
</span>
</Dropdown.Header>
<Dropdown.Item>
<Link href="/profile/settings">
<a className="block text-sm">Settings</a>
</Link>
</Dropdown.Item>
<Dropdown.Item onClick={() => {supabase.auth.signOut(); window.location.href = "/";}}>
Sign out
</Dropdown.Item>
</Dropdown>

) : (
<Button
size="md"
onClick={() => {setShowLoginModal(true)}}
>
Sign In
</Button>
)}
</Suspense>
)}
</div>
</div>
</header>
Expand Down
Loading

0 comments on commit d690048

Please sign in to comment.