Skip to content

Commit

Permalink
Update to the vendor application feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Ibidapo-Ayo committed Nov 13, 2024
1 parent db5e2b9 commit fcc86f1
Show file tree
Hide file tree
Showing 21 changed files with 203 additions and 332 deletions.
18 changes: 18 additions & 0 deletions app/dashboard/components/AuthorizationError.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Button } from '@/components/ui/button'
import Link from 'next/link'
import React from 'react'

const AuthorizationError = () => {
return (
<div className='w-full h-screen flex flex-col justify-center items-center space-y-4'>
<div className='text-center'>
<h1 className='tracking-tight font-semibold'>You are not authorized to access this page yet!</h1>
<p className='text-sm text-secondary-200'>Please login as an admin or check if your vendor application is accepted</p>
</div>

<Link href={"/dashboard"}><Button variant={"ghost"} className='bg-secondary-green-60 hover:bg-secondary-green-50 rounded-full text-white hover:text-white'>Go to Home</Button></Link>
</div>
)
}

export default AuthorizationError
41 changes: 28 additions & 13 deletions app/dashboard/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import {
Home,
LogOut,
Plus,
Settings,
ShoppingBasket,
ShoppingBag,
User
User,
Blocks
} from "lucide-react"
import Image from "next/image"
import { Button } from "@/components/ui/button"
import { useRouter } from "next/navigation"
import { useEffect, useState } from "react"
import Cookies from 'js-cookie';
import { decryptKey } from "@/lib/utils"

const navLinks = [
{
Expand All @@ -32,7 +35,7 @@ const navLinks = [
},
{
name: "Manage Orders",
href: "/dashboard/orders",
href: "/dashboard/manage/orders",
Icon: ShoppingBasket
},
{
Expand All @@ -55,15 +58,24 @@ export default function Sidebar() {
}


export const SideBarLinks = () => {
export const SideBarLinks = () => {
const router = useRouter()

const [isAdmin, setIsAdmin] = useState<boolean>(false)

useEffect(() => {
const passKey = Cookies.get('adminPasskey');
setIsAdmin(decryptKey(passKey!) === process.env.NEXT_PUBLIC_ADMIN_PIN);
}, []);

const handleLogoutAdmin = async () => {
router.push("/logout")
router.push("/logout")
}
return (
<div className="flex flex-col justify-between h-full">
<Image src="/images/logo.png" alt="alt" width={1000} height={1000} className='w-24 md:w-28 mb-5' />
<div className="w-full flex justify-center">
<Image src="/images/logo.png" alt="alt" width={1000} height={1000} className='w-14 md:w-14 ' />
</div>
<nav className="flex flex-col gap-7 px-2 sm:py-5 space-y-3">
{navLinks.map((link, index) => {
return (
Expand All @@ -80,13 +92,16 @@ export const SideBarLinks = () => {
})}
</nav>
<nav className="mt-auto flex flex-col gap-4 py-5 px-5 justify-end">
<Link
href="/settings"
className="flex rounded-lg text-muted-foreground transition-colors hover:text-foreground space-x-4"
>
<Settings className="h-5 w-5" />
<span className="">Settings</span>
</Link>

{isAdmin && (
<Link
href="/manage/vendors"
className="flex rounded-lg text-muted-foreground transition-colors hover:text-foreground space-x-4"
>
<Blocks className="h-5 w-5" />
<span className="">Manage Vendors</span>
</Link>
)}

<Button variant={"ghost"} className="bg-red-500 hover:bg-red-600 space-x-2 text-left" onClick={handleLogoutAdmin}>
<LogOut className="text-white" />
Expand Down
9 changes: 9 additions & 0 deletions app/dashboard/manage/orders/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react'

const OrdersPage = () => {
return (
<div>OrdersPage</div>
)
}

export default OrdersPage
16 changes: 16 additions & 0 deletions app/dashboard/manage/vendors/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react'

const ManageVendors = () => {
return (
<div className='space-y-10'>
<div>
<h1 className='text-xl tracking-tighter font-semibold'>Manage your products</h1>
<p className='text-sm text-secondary'>You can edit or delete your products</p>
</div>


</div>
)
}

export default ManageVendors
21 changes: 10 additions & 11 deletions app/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import { getVendor } from '@/appwrite/vendor.actions'
import { cn } from '@/lib/utils'

const DashboardPage = async () => {
const user = await getUserInfo()
const transaction = await getUserTransactions()
const vendor = await getVendor()
const [user, transaction, vendor] = await Promise.allSettled([getUserInfo(), getUserTransactions(), getVendor()])

if (!user) {
throw new Error("No internet connection!")
Expand All @@ -20,7 +18,8 @@ const DashboardPage = async () => {
return (
<div className='space-y-10'>
<div>
{user && <h1 className='text-xl tracking-tighter font-semibold'>Welcome back, {user.name!.split(" ")[0]}</h1>}
{user.status
=== "fulfilled" && <h1 className='text-xl tracking-tighter font-semibold'>Welcome back, {user.value.name.split(" ")[0]}</h1>}
</div>


Expand All @@ -33,22 +32,22 @@ const DashboardPage = async () => {
/>
<Status
title='Orders'
count={`${transaction?.length}`}
count={`${transaction?.value.length}`}
Icon={ShoppingBasket}
/>

{vendor!.length > 0 && (
{vendor!.value.length > 0 && (
<Status
title='Application Status'
Icon={Hourglass}

// @ts-expect-error
type={`${vendor![0].status}`}>
type={`${vendor!.value[0].status}`}>

<div className={cn("w-auto px-2 py-1 rounded-full bg-green-100 text-green-500", {
"bg-amber-100 text-amber-500": vendor![0].status === "processing",
"bg-red-100 text-red-400": vendor![0].status === "declined"
})}>{vendor![0].status}</div>
"bg-amber-100 text-amber-500": vendor!.value[0].status === "processing",
"bg-red-100 text-red-400": vendor!.value[0].status === "declined"
})}>{vendor!.value[0].status}</div>
</Status>
)}

Expand Down
11 changes: 10 additions & 1 deletion app/dashboard/products/create/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import AddProductForm from '@/components/forms/AddProductForm'
import { userIsAuthorized } from '@/lib/helper'
import React from 'react'
import AuthorizationError from '../../components/AuthorizationError'

const CreateProduct = async () => {
const isAuthorized = await userIsAuthorized()


if (!isAuthorized) {
return <AuthorizationError />
}

const CreateProduct = () => {
return (
<div className='space-y-10'>
<div>
Expand Down
11 changes: 10 additions & 1 deletion app/dashboard/products/manage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import React from 'react'
import ProductsTable from '../../components/ProductsTable'
import AuthorizationError from '../../components/AuthorizationError'
import { userIsAuthorized } from '@/lib/helper'

const DashboardPage = async () => {
const isAuthorized = await userIsAuthorized()


if (!isAuthorized) {
return <AuthorizationError />
}

const DashboardPage = () => {
return (
<div className='space-y-10'>
<div>
Expand Down
47 changes: 41 additions & 6 deletions appwrite/vendor.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import { becomeVendorFormProps } from "@/types"
import { cookies } from "next/headers"
import { createSessionClient } from "./config"
import { createAdminClient, createSessionClient } from "./config"
import { ID, Query } from "node-appwrite"
import { decryptKey } from "@/lib/utils"

const { DATABASE_ID, VENDOR_ID } = process.env

Expand Down Expand Up @@ -36,7 +37,28 @@ export const createVendorAccount = async (data: becomeVendorFormProps) => {
}
}

export const getVendor = async (email?: string) => {
export const getAllVendor = async () => {
const cookieStore = await cookies()

try {
const { databases } = await createAdminClient();

const userId = cookieStore.get("userId")?.value;

const result = await databases.listDocuments(
DATABASE_ID!,
VENDOR_ID!,
)
return result.documents

} catch (error) {
if (error instanceof Error) {
throw new Error(error.message)
}
}
}

export const getVendor = async (email?: string, password?: string) => {
const cookieStore = await cookies()

try {
Expand All @@ -47,14 +69,27 @@ export const getVendor = async (email?: string) => {
const result = await databases.listDocuments(
DATABASE_ID!,
VENDOR_ID!,
email ? [Query.equal("email", email!)] : [Query.equal("user", userId!)]
[Query.equal("user", userId!)]
)

console.log(result)
if (email && password) {
if (result) {
if (decryptKey(result.documents[0].password) !== password! || result.documents[0].email !== email) {
throw new Error("Incorrect email/password")
} else {
if (result.documents[0].status === "accepted") {
cookieStore.set("vendorId", result.documents[0].$id)
}
return result.documents
}
}
}

return result.documents
} catch (error) {
console.log(error);

} catch (error) {
if (error instanceof Error) {
throw new Error(error.message)
}
}
}
32 changes: 18 additions & 14 deletions components/forms/AccessDashboardForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ import { Button } from '../ui/button'
import { getVendor } from '@/appwrite/vendor.actions'

const AccessDashboardSchema = z.object({
pin: z.string().min(6, {
message: "Your dashboard access code must be 6 characters.",
}),
pin: z.string().optional(),

email: z.string().email({
message: "Invalid email address"
Expand All @@ -44,17 +42,19 @@ const AccessDashboardForm = () => {
const router = useRouter()

const onSubmit = async (values: z.infer<typeof AccessDashboardSchema>) => {
console.log(loginType);


if (loginType === "admin") {
if (values.pin === process.env.NEXT_PUBLIC_ADMIN_PIN) {
const encryptedPin = encryptKey(values.pin)
saveAdminPasskey(encryptedPin)
router.push("/dashboard")
if (values.pin) {
if (values.pin === process.env.NEXT_PUBLIC_ADMIN_PIN) {
const encryptedPin = encryptKey(values.pin)
saveAdminPasskey(encryptedPin)
router.push("/dashboard")
} else {
toast.error("Incorrect admin pin")
form.reset()
}
} else {
toast.error("Incorrect admin pin")
form.reset()
toast.warning("Pin is required")
}

return
Expand All @@ -65,12 +65,15 @@ const AccessDashboardForm = () => {
if (!values.email || !values.password) {
toast.warning("Email & password is required!")
console.log("Email not entered");

} else {
setIsLoading(true)
try {
const data = await getVendor(values.email)
console.log(data);
const data = await getVendor(values.email, values.password)

if (data && data?.length > 0) {
router.push("/dashboard")
}

} catch (error) {
if (error instanceof Error) {
Expand Down Expand Up @@ -125,6 +128,7 @@ const AccessDashboardForm = () => {
type='password'
/>


<SubmitButton isLoading={isLoading}>Access Dashboard</SubmitButton>
</>
)}
Expand Down
2 changes: 1 addition & 1 deletion components/landing-page/nav/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const Header = () => {
<div className='w-full grid grid-cols-[auto,1fr,auto] justify-between items-center py-3 gap-4'>
<div className='w-[60px] md:w-[150px]'>
<Link href="/">
<Image src="/images/logo.png" alt="alt" width={1000} height={1000} className='w-24 md:w-28' />
<Image src="/images/logo.png" alt="alt" width={1000} height={1000} className='w-10 md:w-14' />
</Link>
</div>
<SearchComponent />
Expand Down
16 changes: 16 additions & 0 deletions lib/helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"use server"

import { cookies } from "next/headers"

export const userIsAuthorized = async () => {
const cookieStore = await cookies()

const isAdmin = cookieStore.get("isAdmin")
const isVendor = cookieStore.get("vendorId")

if (isAdmin || isVendor) {
return true
}

return false
}
Loading

0 comments on commit fcc86f1

Please sign in to comment.