diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 23d3a4c..e56cc41 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -47,22 +47,19 @@ model Scientist { } model Earthquake { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - date DateTime - code String @unique - magnitude Float - type String // e.g. 'volcanic' - latitude Float - longitude Float - location String - depth String - - creatorId Int? - creator Scientist? @relation("ScientistEarthquakeCreator", fields: [creatorId], references: [id]) - + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + date DateTime + code String @unique + magnitude Float + type String // e.g. 'volcanic' + latitude Float + longitude Float + location String + depth String + creatorId Int? + creator Scientist? @relation("ScientistEarthquakeCreator", fields: [creatorId], references: [id]) artefacts Artefact[] observatories Observatory[] @relation("EarthquakeObservatory") } @@ -91,6 +88,7 @@ model Artefact { type String @db.VarChar(50) // Lava, Tephra, Ash, Soil warehouseArea String description String + imagePath String earthquakeId Int earthquake Earthquake @relation(fields: [earthquakeId], references: [id]) creatorId Int? @@ -101,6 +99,8 @@ model Artefact { isSold Boolean @default(false) purchasedById Int? purchasedBy User? @relation("UserPurchasedArtefacts", fields: [purchasedById], references: [id], onDelete: NoAction, onUpdate: NoAction) + // todo unlink purchase from user + // todo link purchase to order isCollected Boolean @default(false) } @@ -111,3 +111,11 @@ model Pallet { warehouseArea String palletNote String } + +model Order { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + orderNumber String + // todo link order to user +} diff --git a/src/app/administrator/page.tsx b/src/app/administrator/page.tsx index 5ea03fe..c46cd79 100644 --- a/src/app/administrator/page.tsx +++ b/src/app/administrator/page.tsx @@ -1,375 +1,384 @@ "use client"; -import React, { useState, useRef } from "react"; +import React, { useRef, useState } from 'react'; + type Role = "ADMIN" | "GUEST" | "SCIENTIST"; const roleLabels: Record = { - ADMIN: "Admin", - GUEST: "Guest", - SCIENTIST: "Scientist", - }; + ADMIN: "Admin", + GUEST: "Guest", + SCIENTIST: "Scientist", +}; type User = { - id: number; - email: string; - name: string; - role: Role; - password: string; - createdAt: string; + id: number; + email: string; + name: string; + role: Role; + password: string; + createdAt: string; }; +// todo create api route to get users, with auth for only admin +// todo add management of only junior scientists if senior scientist const initialUsers: User[] = [ - { email: "john@example.com", name: "John Doe", role: "ADMIN", password: "secret1", createdAt: "2024-06-21T09:15:01Z" ,id:1}, - { email: "jane@example.com", name: "Jane Smith", role: "GUEST", password: "secret2", createdAt: "2024-06-21T10:01:09Z" ,id:2}, - { email: "bob@example.com", name: "Bob Brown", role: "SCIENTIST", password: "secret3", createdAt: "2024-06-21T12:13:45Z" ,id:3}, - { email: "alice@example.com", name: "Alice Johnson",role: "GUEST", password: "secret4", createdAt: "2024-06-20T18:43:20Z" ,id:4}, - { email: "eve@example.com", name: "Eve Black", role: "ADMIN", password: "secret5", createdAt: "2024-06-20T19:37:10Z" ,id:5}, - { email: "dave@example.com", name: "Dave Clark", role: "GUEST", password: "pw", createdAt: "2024-06-19T08:39:10Z" ,id:6}, - { email: "fred@example.com", name: "Fred Fox", role: "GUEST", password: "pw", createdAt: "2024-06-19T09:11:52Z" ,id:7}, - { email: "ginny@example.com", name: "Ginny Hall", role: "SCIENTIST", password: "pw", createdAt: "2024-06-17T14:56:27Z" ,id:8}, - { email: "harry@example.com", name: "Harry Lee", role: "ADMIN", password: "pw", createdAt: "2024-06-16T19:28:11Z" ,id:9}, - { email: "ivy@example.com", name: "Ivy Volt", role: "ADMIN", password: "pw", createdAt: "2024-06-15T21:04:05Z" ,id:10}, - { email: "kate@example.com", name: "Kate Moss", role: "SCIENTIST", password: "pw", createdAt: "2024-06-14T11:16:35Z" ,id:11}, - { email: "leo@example.com", name: "Leo Garrison", role: "GUEST", password: "pw", createdAt: "2024-06-12T08:02:51Z" ,id:12}, - { email: "isaac@example.com", name: "Isaac Yang", role: "GUEST", password: "pw", createdAt: "2024-06-12T15:43:29Z" ,id:13}, - ]; -const sortFields = [ // Sort box options - { label: "Name", value: "name" }, - { label: "Email", value: "email" }, + { email: "john@example.com", name: "John Doe", role: "ADMIN", password: "secret1", createdAt: "2024-06-21T09:15:01Z", id: 1 }, + { email: "jane@example.com", name: "Jane Smith", role: "GUEST", password: "secret2", createdAt: "2024-06-21T10:01:09Z", id: 2 }, + { + email: "bob@example.com", + name: "Bob Brown", + role: "SCIENTIST", + password: "secret3", + createdAt: "2024-06-21T12:13:45Z", + id: 3, + }, + { + email: "alice@example.com", + name: "Alice Johnson", + role: "GUEST", + password: "secret4", + createdAt: "2024-06-20T18:43:20Z", + id: 4, + }, + { email: "eve@example.com", name: "Eve Black", role: "ADMIN", password: "secret5", createdAt: "2024-06-20T19:37:10Z", id: 5 }, + { email: "dave@example.com", name: "Dave Clark", role: "GUEST", password: "pw", createdAt: "2024-06-19T08:39:10Z", id: 6 }, + { email: "fred@example.com", name: "Fred Fox", role: "GUEST", password: "pw", createdAt: "2024-06-19T09:11:52Z", id: 7 }, + { email: "ginny@example.com", name: "Ginny Hall", role: "SCIENTIST", password: "pw", createdAt: "2024-06-17T14:56:27Z", id: 8 }, + { email: "harry@example.com", name: "Harry Lee", role: "ADMIN", password: "pw", createdAt: "2024-06-16T19:28:11Z", id: 9 }, + { email: "ivy@example.com", name: "Ivy Volt", role: "ADMIN", password: "pw", createdAt: "2024-06-15T21:04:05Z", id: 10 }, + { email: "kate@example.com", name: "Kate Moss", role: "SCIENTIST", password: "pw", createdAt: "2024-06-14T11:16:35Z", id: 11 }, + { email: "leo@example.com", name: "Leo Garrison", role: "GUEST", password: "pw", createdAt: "2024-06-12T08:02:51Z", id: 12 }, + { email: "isaac@example.com", name: "Isaac Yang", role: "GUEST", password: "pw", createdAt: "2024-06-12T15:43:29Z", id: 13 }, +]; +const sortFields = [ + // Sort box options + { label: "Name", value: "name" }, + { label: "Email", value: "email" }, ] as const; -type SortField = typeof sortFields[number]["value"]; +type SortField = (typeof sortFields)[number]["value"]; type SortDir = "asc" | "desc"; const dirLabels: Record = { asc: "ascending", desc: "descending" }; const fieldLabels: Record = { name: "Name", email: "Email" }; export default function AdminPage() { - const [users, setUsers] = useState(initialUsers); - const [selectedEmail, setSelectedEmail] = useState(null); + const [users, setUsers] = useState(initialUsers); + const [selectedEmail, setSelectedEmail] = useState(null); - // Local edit state for SCIENTIST form - const [editUser, setEditUser] = useState(null); - // Reset editUser when the selected user changes - React.useEffect(() => { - if (!selectedEmail) setEditUser(null); - else { - const user = users.find(u => u.email === selectedEmail); - setEditUser(user ? { ...user } : null); - } - }, [selectedEmail, users]); + // Local edit state for SCIENTIST form + const [editUser, setEditUser] = useState(null); + // Reset editUser when the selected user changes + React.useEffect(() => { + if (!selectedEmail) setEditUser(null); + else { + const user = users.find((u) => u.email === selectedEmail); + setEditUser(user ? { ...user } : null); + } + }, [selectedEmail, users]); - // Search/filter/sort state - const [searchField, setSearchField] = useState<"name" | "email">("name"); - const [searchText, setSearchText] = useState(""); - const [roleFilter, setRoleFilter] = useState("all"); - const [sortField, setSortField] = useState("name"); - const [sortDir, setSortDir] = useState("asc"); - // Dropdown states - const [filterDropdownOpen, setFilterDropdownOpen] = useState(false); - const [sortDropdownOpen, setSortDropdownOpen] = useState(false); - const filterDropdownRef = useRef(null); - const sortDropdownRef = useRef(null); + // Search/filter/sort state + const [searchField, setSearchField] = useState<"name" | "email">("name"); + const [searchText, setSearchText] = useState(""); + const [roleFilter, setRoleFilter] = useState("all"); + const [sortField, setSortField] = useState("name"); + const [sortDir, setSortDir] = useState("asc"); + // Dropdown states + const [filterDropdownOpen, setFilterDropdownOpen] = useState(false); + const [sortDropdownOpen, setSortDropdownOpen] = useState(false); + const filterDropdownRef = useRef(null); + const sortDropdownRef = useRef(null); - React.useEffect(() => { - const handleClick = (e: MouseEvent) => { - if ( - filterDropdownRef.current && !filterDropdownRef.current.contains(e.target as Node) - ) setFilterDropdownOpen(false); - if ( - sortDropdownRef.current && !sortDropdownRef.current.contains(e.target as Node) - ) setSortDropdownOpen(false); - }; - document.addEventListener("mousedown", handleClick); - return () => document.removeEventListener("mousedown", handleClick); - }, []); + React.useEffect(() => { + const handleClick = (e: MouseEvent) => { + if (filterDropdownRef.current && !filterDropdownRef.current.contains(e.target as Node)) setFilterDropdownOpen(false); + if (sortDropdownRef.current && !sortDropdownRef.current.contains(e.target as Node)) setSortDropdownOpen(false); + }; + document.addEventListener("mousedown", handleClick); + return () => document.removeEventListener("mousedown", handleClick); + }, []); - // Filtering, searching, sorting logic - const filteredUsers = users.filter( - (user) => roleFilter === "all" || user.role === roleFilter - ); - const searchedUsers = filteredUsers.filter(user => - user[searchField].toLowerCase().includes(searchText.toLowerCase()) - ); - const sortedUsers = [...searchedUsers].sort((a, b) => { - let cmp = a[sortField].localeCompare(b[sortField]); - return sortDir === "asc" ? cmp : -cmp; - }); + // Filtering, searching, sorting logic + const filteredUsers = users.filter((user) => roleFilter === "all" || user.role === roleFilter); + const searchedUsers = filteredUsers.filter((user) => user[searchField].toLowerCase().includes(searchText.toLowerCase())); + const sortedUsers = [...searchedUsers].sort((a, b) => { + let cmp = a[sortField].localeCompare(b[sortField]); + return sortDir === "asc" ? cmp : -cmp; + }); - // Form input change handler - const handleEditChange = (e: React.ChangeEvent) => { - if (!editUser) return; - const { name, value } = e.target; - setEditUser(prev => - prev ? { ...prev, [name]: value } : null - ); - }; + // Form input change handler + const handleEditChange = (e: React.ChangeEvent) => { + if (!editUser) return; + const { name, value } = e.target; + setEditUser((prev) => (prev ? { ...prev, [name]: value } : null)); + }; - // Update button logic (compare original selectedUser and editUser) - const selectedUser = users.find((u) => u.email === selectedEmail); - const isEditChanged = React.useMemo(() => { - if (!editUser || !selectedUser) return false; - // Compare primitive fields - return ( - editUser.name !== selectedUser.name || - editUser.role !== selectedUser.role || - editUser.password !== selectedUser.password - ); - }, [editUser, selectedUser]); + // Update button logic (compare original selectedUser and editUser) + const selectedUser = users.find((u) => u.email === selectedEmail); + const isEditChanged = React.useMemo(() => { + if (!editUser || !selectedUser) return false; + // Compare primitive fields + return ( + editUser.name !== selectedUser.name || editUser.role !== selectedUser.role || editUser.password !== selectedUser.password + ); + }, [editUser, selectedUser]); - // Update/save changes - const handleUpdate = (e: React.FormEvent) => { - e.preventDefault(); - if (!editUser) return; - setUsers(prev => - prev.map(u => - u.email === editUser.email ? { ...editUser } : u - ) - ); - // After successful update, update selectedUser local state - // (editUser will auto-sync due to useEffect on users) - }; + // Update/save changes + const handleUpdate = (e: React.FormEvent) => { + e.preventDefault(); + if (!editUser) return; + setUsers((prev) => prev.map((u) => (u.email === editUser.email ? { ...editUser } : u))); + // todo create receiving api route + // todo send to api route + // After successful update, update selectedUser local state + // (editUser will auto-sync due to useEffect on users) + }; - // Delete user logic - const handleDelete = () => { - if (!selectedUser) return; - if (!window.confirm(`Are you sure you want to delete "${selectedUser.name}"? This cannot be undone.`)) return; - setUsers(prev => prev.filter(u => u.email !== selectedUser.email)); - setSelectedEmail(null); - setEditUser(null); - }; + // Delete user logic + const handleDelete = () => { + if (!selectedUser) return; + if (!window.confirm(`Are you sure you want to delete "${selectedUser.name}"? This cannot be undone.`)) return; + setUsers((prev) => prev.filter((u) => u.email !== selectedUser.email)); + setSelectedEmail(null); + setEditUser(null); + }; - const allRoles: Role[] = ["ADMIN", "GUEST", "SCIENTIST"]; + const allRoles: Role[] = ["ADMIN", "GUEST", "SCIENTIST"]; - // Tooltip handling for email field - const [showEmailTooltip, setShowEmailTooltip] = useState(false); + // Tooltip handling for email field + const [showEmailTooltip, setShowEmailTooltip] = useState(false); - return ( -
-
- {/* SIDEBAR */} -
-
- {/* Search Bar */} -
- setSearchText(e.target.value)} - /> - -
- {/* Filter and Sort Buttons */} -
- {/* Filter */} -
- +
+ {/* Filter and Sort Buttons */} +
+ {/* Filter */} +
+ - {filterDropdownOpen && ( -
- - {allRoles.map(role => ( - - ))} -
- )} -
- {/* Sort */} -
- - {sortDropdownOpen && ( -
- {sortFields.map(opt => ( - - ))} -
- )} -
- {/* Asc/Desc Toggle */} - -
- {/* Sort status text */} - - Users sorted by {fieldLabels[sortField]} {dirLabels[sortDir]} - - {/* USERS LIST: full height, scrollable */} -
    - {sortedUsers.map((user) => ( -
  • setSelectedEmail(user.email)} - className={`rounded-lg cursor-pointer border + onClick={() => setFilterDropdownOpen((v) => !v)} + type="button" + > + Filter{" "} + + + + + {filterDropdownOpen && ( +
    + + {allRoles.map((role) => ( + + ))} +
    + )} +
+ {/* Sort */} +
+ + {sortDropdownOpen && ( +
+ {sortFields.map((opt) => ( + + ))} +
+ )} +
+ {/* Asc/Desc Toggle */} + +
+ {/* Sort status text */} + + Users sorted by {fieldLabels[sortField]} {dirLabels[sortDir]} + + {/* USERS LIST: full height, scrollable */} +
    + {sortedUsers.map((user) => ( +
  • setSelectedEmail(user.email)} + className={`rounded-lg cursor-pointer border ${selectedEmail === user.email ? "bg-blue-100 border-blue-400" : "hover:bg-gray-200 border-transparent"} transition px-2 py-1 mb-1`} - > -
    - {user.name} - {roleLabels[user.role]} -
    -
    - {user.email} -
    -
  • - ))} - {sortedUsers.length === 0 && ( -
  • No users found.
  • - )} -
-
-
- {/* MAIN PANEL */} -
- {editUser ? ( -
-

Edit User

-
-
- - {editUser.createdAt} -
-
- - {editUser.id} -
-
- - setShowEmailTooltip(true)} - onMouseLeave={() => setShowEmailTooltip(false)} - /> - {/* Custom tooltip */} - {showEmailTooltip && ( -
- This field cannot be changed.
- To change the email, delete and re-add the user. -
- )} -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- ) : ( -
- Select a user... -
- )} -
-
- - ); -} \ No newline at end of file + > +
+ {user.name} + {roleLabels[user.role]} +
+
+ {user.email} +
+ + ))} + {sortedUsers.length === 0 &&
  • No users found.
  • } + + + + {/* MAIN PANEL */} +
    + {editUser ? ( +
    +

    Edit User

    +
    +
    + + {editUser.createdAt} +
    +
    + + {editUser.id} +
    +
    + + setShowEmailTooltip(true)} + onMouseLeave={() => setShowEmailTooltip(false)} + /> + {/* Custom tooltip */} + {showEmailTooltip && ( +
    + This field cannot be changed.
    + To change the email, delete and re-add the user. +
    + )} +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    + ) : ( +
    Select a user...
    + )} +
    + + + ); +} diff --git a/src/app/api/earthquakes/route.ts b/src/app/api/earthquakes/route.ts index c44dbd5..7e2975a 100644 --- a/src/app/api/earthquakes/route.ts +++ b/src/app/api/earthquakes/route.ts @@ -1,11 +1,13 @@ -import { NextResponse } from "next/server"; +import { NextResponse } from 'next/server'; -import { PrismaClient } from "@prismaclient"; +import { PrismaClient } from '@prismaclient'; const usingPrisma = false; let prisma: PrismaClient; if (usingPrisma) prisma = new PrismaClient(); +// todo add specification of date range in request + export async function POST(req: Request) { try { const json = await req.json(); diff --git a/src/app/api/observatories/route.ts b/src/app/api/observatories/route.ts index 28258fe..9460497 100644 --- a/src/app/api/observatories/route.ts +++ b/src/app/api/observatories/route.ts @@ -1,11 +1,14 @@ -import { NextResponse } from "next/server"; +import { NextResponse } from 'next/server'; -import { PrismaClient } from "@prismaclient"; +import { PrismaClient } from '@prismaclient'; const usingPrisma = false; let prisma: PrismaClient; if (usingPrisma) prisma = new PrismaClient(); +// todo remove if (usingPrisma) code +// todo add specification of date range in request + export async function GET(request: Request) { try { const events = [ diff --git a/src/app/api/signup/route.ts b/src/app/api/signup/route.ts index b7449c3..0eb21d0 100644 --- a/src/app/api/signup/route.ts +++ b/src/app/api/signup/route.ts @@ -11,6 +11,8 @@ const usingPrisma = false; let prisma: PrismaClient; if (usingPrisma) prisma = new PrismaClient(); +// todo remove if (usingPrisma) code + export async function POST(req: Request) { try { const { email, password, name } = await req.json(); // Parse incoming JSON data @@ -18,6 +20,7 @@ export async function POST(req: Request) { const userData = await readUserCsv(); + // todo remove console logs console.log(userData); console.log("Name:", name); // ! remove console.log("Email:", email); // ! remove diff --git a/src/app/api/warehouse/route.ts b/src/app/api/warehouse/route.ts index 0eedb14..b0eaaab 100644 --- a/src/app/api/warehouse/route.ts +++ b/src/app/api/warehouse/route.ts @@ -1,13 +1,16 @@ -import { NextResponse } from "next/server"; +import { NextResponse } from 'next/server'; -import { PrismaClient } from "@prismaclient"; -import { env } from "@utils/env"; -import { verifyJwt } from "@utils/verifyJwt"; +import { PrismaClient } from '@prismaclient'; +import { env } from '@utils/env'; +import { verifyJwt } from '@utils/verifyJwt'; const usingPrisma = false; let prisma: PrismaClient; if (usingPrisma) prisma = new PrismaClient(); +// todo remove if (usingPrisma) code +// todo add specification of date range in request + // Artefact type interface Artefact { id: number; diff --git a/src/app/profile/page.tsx b/src/app/profile/page.tsx index a83b849..fbe18ce 100644 --- a/src/app/profile/page.tsx +++ b/src/app/profile/page.tsx @@ -1,11 +1,12 @@ "use client"; -import { useState, useEffect } from "react"; -import { useStoreActions } from "@hooks/store"; -import axios, { AxiosError } from "axios"; -import { useRouter } from "next/navigation"; -import { User } from "@appTypes/Prisma"; -import { FaSignOutAlt } from "react-icons/fa"; -import { FaUser } from "react-icons/fa6"; +import axios, { AxiosError } from 'axios'; +import { useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; +import { FaSignOutAlt } from 'react-icons/fa'; +import { FaUser } from 'react-icons/fa6'; + +import { User } from '@appTypes/Prisma'; +import { useStoreActions } from '@hooks/store'; export default function Profile() { const router = useRouter(); @@ -50,6 +51,8 @@ export default function Profile() { } setIsSubmitting(true); try { + // todo create receiving api route + // todo handle sending fields to api route await new Promise((resolve) => setTimeout(resolve, 500)); setUserState({ ...user!, name, email, role }); alert("Profile updated successfully."); diff --git a/src/app/shop/page.tsx b/src/app/shop/page.tsx index 3665e94..e0d1547 100644 --- a/src/app/shop/page.tsx +++ b/src/app/shop/page.tsx @@ -1,10 +1,10 @@ "use client"; -import Image from "next/image"; -import { Dispatch, SetStateAction, useCallback, useState } from "react"; +import Image from 'next/image'; +import { Dispatch, SetStateAction, useCallback, useState } from 'react'; -import Artefact from "@appTypes/Artefact"; -import { Currency } from "@appTypes/StoreModel"; -import { useStoreState } from "@hooks/store"; +import Artefact from '@appTypes/Artefact'; +import { Currency } from '@appTypes/StoreModel'; +import { useStoreState } from '@hooks/store'; // Artefacts Data const artefacts: Artefact[] = [ @@ -322,6 +322,10 @@ export default function Shop() { setError("CVC must be 3 or 4 digits."); return; } + // todo create receiving api route + // todo handle sending to api route + // todo remove order number generation - we don't need one + // todo add option to save details in new account const genOrder = () => "#" + Math.random().toString(36).substring(2, 10).toUpperCase(); setOrderNumber(genOrder()); onClose(); diff --git a/src/app/warehouse/page.tsx b/src/app/warehouse/page.tsx index bd5a3b2..dde7625 100644 --- a/src/app/warehouse/page.tsx +++ b/src/app/warehouse/page.tsx @@ -1,8 +1,8 @@ "use client"; -import { Dispatch, SetStateAction, useMemo, useState } from "react"; -import { FaTimes } from "react-icons/fa"; -import { FaCalendarPlus, FaCartShopping, FaWarehouse } from "react-icons/fa6"; -import { IoFilter, IoFilterCircleOutline, IoFilterOutline, IoToday } from "react-icons/io5"; +import { Dispatch, SetStateAction, useMemo, useState } from 'react'; +import { FaTimes } from 'react-icons/fa'; +import { FaCalendarPlus, FaCartShopping, FaWarehouse } from 'react-icons/fa6'; +import { IoFilter, IoFilterCircleOutline, IoFilterOutline, IoToday } from 'react-icons/io5'; // import { Artefact } from "@appTypes/Prisma"; @@ -275,6 +275,8 @@ function LogModal({ onClose }: { onClose: () => void }) { } setIsSubmitting(true); try { + // todo create receiving api route + // todo handle sending fields to api route await new Promise((resolve) => setTimeout(resolve, 500)); // Simulated API call alert(`Logged ${name} to storage: ${storageLocation}`); onClose(); @@ -406,6 +408,8 @@ function BulkLogModal({ onClose }: { onClose: () => void }) { }; const handleLog = async () => { + // todo create receiving api route + // todo handle sending fields to api route if (!palletNote || !storageLocation) { setError("All fields are required."); return; @@ -504,6 +508,8 @@ function EditModal({ artefact, onClose }: { artefact: Artefact; onClose: () => v const [error, setError] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); + // todo add image display + const handleOverlayClick = (e: { target: any; currentTarget: any }) => { if (e.target === e.currentTarget) { onClose(); diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 3ee96c8..57fbb4b 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -50,6 +50,7 @@ export default function Sidebar({ button1Name, button2Name, }: SidebarProps) { + // todo add buttons 1 and 2 click handlers return (