diff --git a/src/app/admin/interests/page.js b/src/app/admin/interests/page.js
new file mode 100644
index 000000000..9835c572d
--- /dev/null
+++ b/src/app/admin/interests/page.js
@@ -0,0 +1,18 @@
+import ProtectedPage from "@/components/dynamic/ProtectedPage";
+import Interests from "@/components/dynamic/admin/dashboards/Interests";
+
+const Page = () => {
+ return (
+
+
+
+ );
+};
+
+export default Page;
diff --git a/src/app/api/interests/route.js b/src/app/api/interests/route.js
new file mode 100644
index 000000000..9e231475c
--- /dev/null
+++ b/src/app/api/interests/route.js
@@ -0,0 +1,114 @@
+import { NextResponse } from "next/server";
+import { db } from "../../../../firebase";
+import {
+ collection,
+ getDocs,
+ doc,
+ updateDoc,
+ Timestamp,
+ query,
+ where,
+} from "firebase/firestore";
+import { authenticate } from "@/utils/auth";
+import { AUTH } from "@/data/dynamic/admin/Feedback";
+
+export async function POST() {
+ const res = NextResponse;
+ const { auth, uid } = await authenticate(AUTH.POST);
+
+ if (auth !== 200) {
+ return res.json(
+ { message: `Authentication Error: ${message}` },
+ { status: auth }
+ );
+ }
+
+ try {
+ await updateDoc(doc(db, "users", uid), {
+ "roles.interests": 0,
+ timestamp: Timestamp.now(),
+ });
+ return res.json({ message: "OK" }, { status: 200 });
+ } catch (err) {
+ return res.json(
+ { message: `Internal Server Error: ${err}` },
+ { status: 500 }
+ );
+ }
+}
+
+export async function GET() {
+ const res = NextResponse;
+ const { auth, message } = await authenticate(AUTH.GET);
+
+ if (auth !== 200) {
+ return res.json(
+ { message: `Authentication Error: ${message}` },
+ { status: auth }
+ );
+ }
+
+ const output = [];
+
+ try {
+ const snapshot = await getDocs(
+ query(collection(db, "users"), where("roles.interests", "in", [-1, 0, 1]))
+ );
+ snapshot.forEach((doc) => {
+ const { name, email, timestamp, roles } = doc.data();
+ output.push({
+ uid: doc.id,
+ name,
+ email,
+ status: roles.interests,
+ timestamp: timestamp,
+ });
+ });
+
+ const sorted = output.sort((a, b) =>
+ a.timestamp.seconds < b.timestamp.seconds ? 1 : -1
+ );
+
+ return res.json({ message: "OK", items: sorted }, { status: 200 });
+ } catch (err) {
+ return res.json(
+ { message: `Internal Server Error: ${err}` },
+ { status: 500 }
+ );
+ }
+}
+
+export async function PUT(req) {
+ const res = NextResponse;
+ const { auth, message } = await authenticate(AUTH.PUT);
+
+ if (auth !== 200) {
+ return res.json(
+ { message: `Authentication Error: ${message}` },
+ { status: auth }
+ );
+ }
+
+ const { objects, attribute, status } = await req.json();
+
+ try {
+ objects.forEach(async (object) => {
+ if (attribute === "role") {
+ await updateDoc(doc(db, "users", object.uid), {
+ "roles.interests": deleteField(),
+ });
+ } else if (attribute === "status") {
+ await updateDoc(doc(db, "users", object.uid), {
+ "roles.interests": status,
+ });
+ }
+ });
+
+ return res.json({ message: "OK" }, { status: 200 });
+ } catch (err) {
+ return res.json(
+ { message: `Internal Server Error: ${err}` },
+ { status: 500 }
+ );
+ }
+}
diff --git a/src/app/form/interest/page.js b/src/app/form/interest/page.js
new file mode 100644
index 000000000..6d90bc9b0
--- /dev/null
+++ b/src/app/form/interest/page.js
@@ -0,0 +1,12 @@
+import Interest from "@/components/dynamic/form/Interest";
+import ProtectedPage from "@/components/dynamic/ProtectedPage";
+
+const Page = () => {
+ return (
+
+
+
+ );
+};
+
+export default Page;
diff --git a/src/components/dynamic/admin/Table.jsx b/src/components/dynamic/admin/Table.jsx
index b7f61a66f..72e04532a 100644
--- a/src/components/dynamic/admin/Table.jsx
+++ b/src/components/dynamic/admin/Table.jsx
@@ -53,6 +53,7 @@ const Table = ({
})
);
};
+
return !objects ? (
) : (
diff --git a/src/components/dynamic/admin/dashboards/Interests.jsx b/src/components/dynamic/admin/dashboards/Interests.jsx
new file mode 100644
index 000000000..ae1152370
--- /dev/null
+++ b/src/components/dynamic/admin/dashboards/Interests.jsx
@@ -0,0 +1,23 @@
+"use client";
+import {
+ FILTERS,
+ HEADERS,
+ STATUSES,
+ TAGS,
+} from "@/data/dynamic/admin/Interest";
+import Dashboard from "../Dashboard";
+
+const Feedback = () => {
+ return (
+
+ );
+};
+export default Feedback;
diff --git a/src/components/dynamic/form/Interest.jsx b/src/components/dynamic/form/Interest.jsx
new file mode 100644
index 000000000..5a4933fa8
--- /dev/null
+++ b/src/components/dynamic/form/Interest.jsx
@@ -0,0 +1,44 @@
+"use client";
+
+import { useState } from "react";
+import Form from "@/components/dynamic/form/Form.jsx";
+import axios from "axios";
+import toast from "react-hot-toast";
+import { FIELDS, ATTRIBUTES } from "@/data/dynamic/form/Interest";
+import { useSession } from "next-auth/react";
+import { STATUSES } from "@/data/dynamic/admin/Interest";
+
+const Interest = () => {
+ const { data: session } = useSession();
+ const [interest, setInterest] = useState({
+ ...ATTRIBUTES,
+ name: session.user.name,
+ email: session.user.email,
+ roles: session.user.roles,
+ form: "interests",
+ });
+
+ const onSubmit = (setLoading, setState) => {
+ axios
+ .post("/api/interests", interest)
+ .then(() => toast(`✅ Submitted successfully!`))
+ .catch(() => toast(`❌ Internal Server Error`))
+ .finally(() => {
+ setLoading(false);
+ setState(2);
+ });
+ };
+
+ return (
+
+ );
+};
+
+export default Interest;
diff --git a/src/data/dynamic/Navigation.js b/src/data/dynamic/Navigation.js
index e04d6c801..2ab1880c9 100644
--- a/src/data/dynamic/Navigation.js
+++ b/src/data/dynamic/Navigation.js
@@ -13,6 +13,7 @@ import {
FaLock,
FaCalendarDay,
FaMedal,
+ FaExclamation,
} from "react-icons/fa";
import { AiOutlineQrcode } from "react-icons/ai";
import { signOut } from "next-auth/react";
@@ -61,6 +62,11 @@ export const TABS = {
link: "/admin/committees",
icon: ,
},
+ {
+ name: "interests",
+ link: "/admin/interest",
+ icon: ,
+ },
{
name: "feedback",
link: "/admin/feedback",
diff --git a/src/data/dynamic/admin/Interest.js b/src/data/dynamic/admin/Interest.js
new file mode 100644
index 000000000..cc7537afa
--- /dev/null
+++ b/src/data/dynamic/admin/Interest.js
@@ -0,0 +1,51 @@
+export const FILTERS = {
+ unnotified: {
+ state: true,
+ value: 0,
+ },
+ notified: {
+ state: true,
+ value: 1,
+ },
+};
+
+export const TAGS = [
+ {
+ text: "notified",
+ value: 1,
+ },
+ {
+ text: "unnotified",
+ value: 0,
+ },
+];
+
+export const HEADERS = [
+ { text: "name", size: "w-5/12", icon: true, sort: "off" },
+ { text: "email", size: "w-5/12", icon: true, sort: "off" },
+ {
+ text: "status",
+ size: "w-2/12",
+ icon: true,
+ sort: "off",
+ hasTag: true,
+ },
+];
+
+export const AUTH = {
+ POST: {},
+ GET: {
+ admins: 1,
+ },
+ PUT: {
+ admins: 1,
+ },
+ DELETE: {
+ admins: 1,
+ },
+};
+
+export const STATUSES = {
+ 1: "notified",
+ 0: "unnotified",
+};
diff --git a/src/data/dynamic/form/Interest.js b/src/data/dynamic/form/Interest.js
new file mode 100644
index 000000000..8ec691a17
--- /dev/null
+++ b/src/data/dynamic/form/Interest.js
@@ -0,0 +1,35 @@
+export const FIELDS = {
+ description: {
+ input: "description",
+ width: 12,
+ texts: [
+ "Welcome to HACKATHON_NAME. Thank you for taking interestin in HACKAHTON_NAME, we appreciate your efforts to help support HACKATHON_NAME. HACKATHON_NAME is a DESCRIPTION hackathon spanning HACKATHON_LENGTH on HACKATHON_DATE.",
+ "This is simply an interest form, once applications are released, you will be notified immediately and will be required to register again. We hope to see you there!",
+ ],
+ },
+ name: {
+ input: "input",
+ name: "name",
+ type: "text",
+ title: "Name",
+ maxLength: 50,
+ width: 12,
+ editable: false,
+ required: true,
+ },
+ email: {
+ input: "input",
+ name: "email",
+ type: "email",
+ title: "Email Address",
+ maxLength: 50,
+ width: 12,
+ editable: false,
+ required: true,
+ },
+};
+
+export const ATTRIBUTES = {
+ name: "",
+ email: "",
+};