Skip to content

Commit

Permalink
Issue Fix: Issue 165 - isAdmin state is moved to zustand store and as…
Browse files Browse the repository at this point in the history
…sociated functions are changed
pingaipl committed Jan 27, 2025
1 parent 4f8bac4 commit 4b5e817
Showing 11 changed files with 65 additions and 35 deletions.
5 changes: 5 additions & 0 deletions .infisical.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"workspaceId": "abd68259-a067-4c9b-be6d-a40d6c161b4c",
"defaultEnvironment": "",
"gitBranchToEnvironmentMapping": null
}
8 changes: 5 additions & 3 deletions app/(default)/achievements/page.tsx
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import axios from "axios";
import { onAuthStateChanged } from "firebase/auth";
import { auth } from "@/Firebase";
import AchievementCard from "@/components/AchievementCard";
import { useStore} from "@/lib/zustand/store";

interface Achiever {
id?: string;
@@ -25,7 +26,8 @@ export default function AchievementsPage() {
const [newAchievement, setNewAchievement] = useState<Partial<Achiever>>({
achievements: [""],
});
const [isAdmin, setIsAdmin] = useState(false);
// const [isAdmin, setIsAdmin] = useState(false);
const { isAdmin , setAdmin } = useStore();
const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [editName, setEditName] = useState("");
const [editAchievements, setEditAchievements] = useState<Partial<Achiever>>({
@@ -40,14 +42,14 @@ export default function AchievementsPage() {
const resp = await fetch(`/api/admin?uid=${uid}`);
const data = await resp.json();
if (data.isAdmin) {
setIsAdmin(true);
setAdmin(true);
}
} catch (error) {
console.log("Error getting document:", error);
}
}
});
},[]);
},[isAdmin]);

useEffect(() => {
async function fetchAchievers() {
19 changes: 10 additions & 9 deletions app/(default)/events/page.tsx
Original file line number Diff line number Diff line change
@@ -7,11 +7,12 @@ import EventForm from "../../../components/EventForm";
import EventUpdateForm from "../../../components/EventUpdateForm";
import EventCard from "../../../components/EventCard";
import Sidebar from "../../../components/Sidebar";

import { useStore} from "@/lib/zustand/store";

const EventsPage = () => {
const [showForm, setShowForm] = useState(false);
const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false);
// const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false);
const { isAdmin , setAdmin } = useStore();
const [events, setEvents] = useState<
{
id: string;
@@ -48,14 +49,14 @@ const EventsPage = () => {
const resp = await fetch(`/api/admin?uid=${uid}`);
const data = await resp.json();
if (data.isAdmin) {
setIsAdminLoggedIn(true);
setAdmin(true);
}
} catch (error) {
console.log("Error getting document:", error);
}
}
});
});
}, [isAdmin]);

const fetchEvents = async () => {
const resp = await fetch("/api/events");
@@ -117,7 +118,7 @@ const EventsPage = () => {
<div className="p-4 pt-20 relative">
<h1 className="text-5xl font-bold mb-2 pl-5 pt-2 text-center">Events</h1>
<div className="flex justify-end">
{isAdminLoggedIn && (
{isAdmin && (
<button
onClick={() => setShowForm(!showForm)} // Toggles the form visibility
className="bg-blue-600 text-white py-2 px-4 rounded-md mb-4"
@@ -128,7 +129,7 @@ const EventsPage = () => {
</div>

{/* Event Form to Add New Event */}
{isAdminLoggedIn && showForm && <EventForm />}
{isAdmin && showForm && <EventForm />}

{/* Displaying the Events */}
<div className="mt-2">
@@ -143,7 +144,7 @@ const EventsPage = () => {
<EventCard
key={event.id}
event={event}
isAdminLoggedIn={isAdminLoggedIn}
isAdminLoggedIn={isAdmin}
onDelete={() => deleteEvent(event.id , event)}
onSelect={handleEventSelect}
/>
@@ -162,7 +163,7 @@ const EventsPage = () => {
<EventCard
key={event.id}
event={event}
isAdminLoggedIn={isAdminLoggedIn}
isAdminLoggedIn={isAdmin}
onDelete={() => deleteEvent(event.id , event)}
onSelect={handleEventSelect}
/>
@@ -182,7 +183,7 @@ const EventsPage = () => {
)}

{/* Event Update Form */}
{isAdminLoggedIn && selectedEvent && (
{isAdmin && selectedEvent && (
<div className="mt-8 z-50">
<h2 className="text-2xl font-bold mb-4">Update Event</h2>
<EventUpdateForm
20 changes: 11 additions & 9 deletions app/(default)/hustle/page.tsx
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import { motion } from "framer-motion";
import { Trophy, RefreshCw, TableProperties } from "lucide-react";
import { auth } from "../../../Firebase"; // Firebase setup
import { onAuthStateChanged } from "firebase/auth";
import { useStore} from "@/lib/zustand/store";

interface Result {
rank: number;
@@ -15,11 +16,12 @@ interface Result {

export default function ResultsTable() {
const [tab, setTab] = useState<"latest" | "rankings">("latest");
const [isAdmin, setIsAdmin] = useState(false);
// const [isAdmin, setIsAdmin] = useState(false);
const [latestResults, setLatestResults] = useState<Result[]>([]);
const [rankings, setRankings] = useState<Result[]>([]);
const [loading, setLoading] = useState(true);
const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false);
// const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false);
const { isAdmin , setAdmin } = useStore();
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);

useEffect(() => {
@@ -52,21 +54,21 @@ export default function ResultsTable() {
try {
const response = await fetch(`/api/admin?uid=${uid}`);
const { isAdmin } = await response.json();
setIsAdmin(isAdmin);
setIsAdminLoggedIn(true);
setAdmin(isAdmin);
setAdmin(true);
} catch (error) {
console.error("Error checking admin status:", error);
setIsAdmin(false);
setIsAdminLoggedIn(false);
setAdmin(false);
setAdmin(false);
}
};

const unsubscribe = onAuthStateChanged(auth, (user) => {
if (user) {
checkAdmin(user.uid);
} else {
setIsAdmin(false);
setIsAdminLoggedIn(false);
setAdmin(false);
setAdmin(false);
}
});

@@ -162,7 +164,7 @@ export default function ResultsTable() {
</button>
))}
</div>
{isAdmin && isAdminLoggedIn && tab === "latest" && (
{isAdmin && isAdmin && tab === "latest" && (
<div className="flex justify-center mb-4">
<motion.button
whileHover={{ scale: 1.05 }}
6 changes: 4 additions & 2 deletions components/Members.tsx
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ import Image from "next/image";
import Card from "./ui/Card";
import CollapsibleSection from "./ui/CollapsibleSection";
import { useStoreMember } from "@/lib/zustand/store";
import { useStore } from "@/lib/zustand/store";

interface Member {
id?: string;
@@ -57,7 +58,8 @@ export default function Members() {
setOpenIndex(openIndex === index ? -1 : index);
};

const [isAdmin, setIsAdmin] = useState(false);
// const [isAdmin, setIsAdmin] = useState(false);
const { isAdmin, setAdmin } = useStore();

useEffect(() => {
onAuthStateChanged(auth, async (user) => {
@@ -67,7 +69,7 @@ export default function Members() {
const resp = await fetch(`/api/admin?uid=${uid}`);
const data = await resp.json();
if (data.isAdmin) {
setIsAdmin(true);
setAdmin(true);
}
} catch (error) {
console.log("Error getting document:", error);
13 changes: 7 additions & 6 deletions components/leadspage.tsx
Original file line number Diff line number Diff line change
@@ -16,7 +16,8 @@ interface Lead {
const Leads: React.FC = () => {
const [loading, setLoading] = useState(true);
const [showForm, setShowForm] = useState(false);
const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false);
// const [isAdminLoggedIn, setIsAdminLoggedIn] = useState(false);
const { isAdmin , setAdmin } = useStore();
const [currentLeads, setCurrentLeads] = useState<Lead[]>([]);
const [alumniLeads, setAlumniLeads] = useState<Lead[]>([]);
const [selectedLead, setSelectedLead] = useState<Lead | null>(null); // For editing leads
@@ -45,14 +46,14 @@ const Leads: React.FC = () => {
const resp = await fetch(`/api/admin?uid=${uid}`);
const data = await resp.json();
if (data.isAdmin) {
setIsAdminLoggedIn(true);
setAdmin(true);
}
} catch (error) {
console.log("Error getting document:", error);
}
}
});
});
}, [isAdmin]);

useEffect(() => {
fetchLeads();
@@ -186,7 +187,7 @@ const Leads: React.FC = () => {
color: "#fff",
}}
>
{isAdminLoggedIn && (
{isAdmin && (
<button
onClick={toggleForm}
style={{
@@ -219,14 +220,14 @@ const Leads: React.FC = () => {
leads={currentLeads}
onEdit={handleEditLead}
onDelete={handleDeleteLead}
isAdminLoggedIn={isAdminLoggedIn}
isAdminLoggedIn={isAdmin}
/>
<LeadSection
title="Alumni Leads"
leads={alumniLeads}
onEdit={handleEditLead}
onDelete={handleDeleteLead}
isAdminLoggedIn={isAdminLoggedIn}
isAdminLoggedIn={isAdmin}
/>
</section>
);
4 changes: 4 additions & 0 deletions components/ui/header.tsx
Original file line number Diff line number Diff line change
@@ -8,16 +8,20 @@ import MobileMenu from './mobile-menu'
import { onAuthStateChanged } from 'firebase/auth'
import { auth } from '@/Firebase'

import { useStore } from "@/lib/zustand/store";


export default function Header() {
const [top, setTop] = useState<boolean>(true)
const pathname = usePathname()

const [loggedIn, setLoggedIn] = useState(false);
const { reset } = useStore();

const handleLogout = async () => {
await auth.signOut();
setLoggedIn(false);
reset();
}

useEffect(() => {
3 changes: 3 additions & 0 deletions components/ui/mobile-menu.tsx
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import { Transition } from '@headlessui/react';
import Link from 'next/link';
import { onAuthStateChanged } from 'firebase/auth';
import { auth } from '@/Firebase';
import { useStore } from "@/lib/zustand/store";


export default function MobileMenu() {
@@ -14,10 +15,12 @@ export default function MobileMenu() {
const trigger = useRef<HTMLButtonElement>(null);
const mobileNav = useRef<HTMLDivElement>(null);
const [loggedIn, setLoggedIn] = useState(false);
const { reset } = useStore();

const handleLogout = async () => {
await auth.signOut();
setLoggedIn(false);
reset();
}

useEffect(() => {
13 changes: 11 additions & 2 deletions lib/zustand/store.ts
Original file line number Diff line number Diff line change
@@ -2,16 +2,25 @@
import {create} from 'zustand';

interface SharedState {
image: string | File | null| Blob; // Store image as base64 string or Blob URL
setImage: (image: string | File|Blob) => void; // Function to update the image
image: string | File | null | Blob; // Store image as base64 string or Blob URL
setImage: (image: string | File | Blob) => void; // Function to update the image
isAdmin: boolean; // State to track if the user is an admin
setAdmin: (isAdmin: boolean) => void; // Function to update the isAdmin state
reset: () => void; // Function to reset the state
}

export const useStore = create<SharedState>((set) => ({
image: null,
setImage: (image) => set({ image }), // Set the image in state
isAdmin: false,
setAdmin: (isAdmin) => set({ isAdmin }), // Set the isAdmin state
reset: () => set({ image: null, isAdmin: false }), // Reset the state
}));

export const useStoreMember = create<SharedState>((set) => ({
image: null,
setImage: (image) => set({ image }), // Set the image in state
isAdmin: false,
setAdmin: (isAdmin) => set({ isAdmin }), // Set the isAdmin state
reset: () => set({ image: null, isAdmin: false }), // Reset the state
}));
3 changes: 2 additions & 1 deletion next.config.mjs
Original file line number Diff line number Diff line change
@@ -9,7 +9,8 @@ const nextConfig = {
"img.icons8.com",
"icpc.global",
"img.freepik.com",
"media.licdn.com"
"media.licdn.com",
"res.cloudinary.com"
],
},
};
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4b5e817

Please sign in to comment.