Skip to content

Commit ed13342

Browse files
database created with the tables of projects, user, members, dropdown(catagories). Admin page created with the fuctions to edit end delete projects and catagories
1 parent 1361ac2 commit ed13342

42 files changed

Lines changed: 9302 additions & 3846 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/add-project/page.tsx

Lines changed: 14 additions & 387 deletions
Large diffs are not rendered by default.
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
"use client";
2+
3+
import React, { useState, useEffect } from "react";
4+
import { Input } from "@/components/ui/input";
5+
import { Button } from "@/components/ui/button";
6+
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
7+
import { addDropdownOption, deleteDropdownOption, getDropdownOptions } from "@/server-action/db-actions";
8+
9+
interface DropdownOption {
10+
id: number;
11+
category: string;
12+
option_value: string;
13+
}
14+
15+
export default function ManageCategoriesPage() {
16+
const [activeTab, setActiveTab] = useState("add"); // State to manage active tab
17+
const [categories, setCategories] = useState<string[]>([]);
18+
19+
useEffect(() => {
20+
fetchCategories();
21+
}, []);
22+
23+
const fetchCategories = async () => {
24+
try {
25+
const allCategories = await getDropdownOptions("all"); // Fetch all categories
26+
const uniqueCategories = Array.from(new Set(allCategories.map((option: DropdownOption) => option.category)));
27+
setCategories(uniqueCategories);
28+
} catch (error) {
29+
console.error("Error fetching categories:", error);
30+
}
31+
};
32+
33+
return (
34+
<div className="p-6">
35+
<h1 className="text-2xl font-bold mb-6">Manage Categories</h1>
36+
<Tabs defaultValue="add" value={activeTab} onValueChange={setActiveTab}>
37+
<TabsList className="mb-4">
38+
<TabsTrigger value="add">Add Category Option</TabsTrigger>
39+
<TabsTrigger value="delete">Delete Category Option</TabsTrigger>
40+
</TabsList>
41+
<TabsContent value="add">
42+
<AddCategoryOption fetchCategories={fetchCategories} categories={categories} />
43+
</TabsContent>
44+
<TabsContent value="delete">
45+
<DeleteCategoryOption fetchCategories={fetchCategories} categories={categories} />
46+
</TabsContent>
47+
</Tabs>
48+
</div>
49+
);
50+
}
51+
52+
interface CategoryManagementProps {
53+
fetchCategories: () => void;
54+
categories: string[];
55+
}
56+
57+
function AddCategoryOption({ fetchCategories }: CategoryManagementProps) {
58+
const [categoryName, setCategoryName] = useState("");
59+
const [optionValue, setOptionValue] = useState("");
60+
const [status, setStatus] = useState<string | null>(null);
61+
const [loading, setLoading] = useState(false);
62+
63+
const handleSubmit = async (e: React.FormEvent) => {
64+
e.preventDefault();
65+
if (!categoryName || !optionValue) {
66+
setStatus("Please fill in both fields.");
67+
return;
68+
}
69+
setLoading(true);
70+
setStatus(null);
71+
try {
72+
const result = await addDropdownOption(categoryName, optionValue);
73+
if (result.success) {
74+
setStatus("Category option added successfully!");
75+
setCategoryName("");
76+
setOptionValue("");
77+
fetchCategories(); // Refresh categories list
78+
} else {
79+
setStatus(`Failed to add category option: ${result.error}`);
80+
}
81+
} catch (error) {
82+
console.error("Error adding category option:", error);
83+
setStatus("An unexpected error occurred.");
84+
} finally {
85+
setLoading(false);
86+
}
87+
};
88+
89+
return (
90+
<div className="space-y-4">
91+
<h3 className="text-lg font-semibold">Add New Category Option</h3>
92+
<form onSubmit={handleSubmit} className="space-y-4">
93+
<div>
94+
<label htmlFor="categoryName" className="block text-sm font-medium text-gray-700">Category Name</label>
95+
<Input
96+
type="text"
97+
id="categoryName"
98+
placeholder="e.g., project_types, departments, domains, submission_years"
99+
value={categoryName}
100+
onChange={(e) => setCategoryName(e.target.value)}
101+
className="w-full"
102+
/>
103+
</div>
104+
<div>
105+
<label htmlFor="optionValue" className="block text-sm font-medium text-gray-700">Option Value</label>
106+
<Input
107+
type="text"
108+
id="optionValue"
109+
placeholder="e.g., Research Project, Computer Science, Web Development, 2023"
110+
value={optionValue}
111+
onChange={(e) => setOptionValue(e.target.value)}
112+
className="w-full"
113+
/>
114+
</div>
115+
<Button type="submit" disabled={loading}>
116+
{loading ? "Adding..." : "Add Option"}
117+
</Button>
118+
{status && <p className="mt-2 text-sm">{status}</p>}
119+
</form>
120+
</div>
121+
);
122+
}
123+
124+
function DeleteCategoryOption({ fetchCategories }: CategoryManagementProps) {
125+
const [categoryName, setCategoryName] = useState("");
126+
const [optionValue, setOptionValue] = useState("");
127+
const [categoryOptions, setCategoryOptions] = useState<DropdownOption[]>([]);
128+
const [status, setStatus] = useState<string | null>(null);
129+
const [loading, setLoading] = useState(false);
130+
const [confirming, setConfirming] = useState(false);
131+
132+
useEffect(() => {
133+
const fetchOptions = async () => {
134+
if (categoryName) {
135+
try {
136+
const options = await getDropdownOptions(categoryName);
137+
setCategoryOptions(options);
138+
} catch (error) {
139+
console.error(`Error fetching options for category ${categoryName}:`, error);
140+
setCategoryOptions([]);
141+
}
142+
} else {
143+
setCategoryOptions([]);
144+
}
145+
};
146+
fetchOptions();
147+
}, [categoryName]);
148+
149+
const handleDelete = async () => {
150+
if (!categoryName || !optionValue) {
151+
setStatus("Please select both category and option value.");
152+
return;
153+
}
154+
setLoading(true);
155+
setStatus(null);
156+
try {
157+
const result = await deleteDropdownOption(categoryName, optionValue);
158+
if (result.success) {
159+
setStatus("Category option deleted successfully!");
160+
setCategoryName("");
161+
setOptionValue("");
162+
fetchCategories(); // Refresh categories list
163+
} else {
164+
setStatus(`Failed to delete category option: ${result.error}`);
165+
}
166+
} catch (error) {
167+
console.error("Error deleting category option:", error);
168+
setStatus("An unexpected error occurred.");
169+
} finally {
170+
setLoading(false);
171+
setConfirming(false);
172+
}
173+
};
174+
175+
return (
176+
<div className="space-y-4">
177+
<h3 className="text-lg font-semibold">Delete Existing Category Option</h3>
178+
<form onSubmit={(e) => e.preventDefault()} className="space-y-4">
179+
<div>
180+
<label htmlFor="deleteCategoryName" className="block text-sm font-medium text-gray-700">Category Name</label>
181+
<select
182+
id="deleteCategoryName"
183+
value={categoryName}
184+
onChange={(e) => {
185+
setCategoryName(e.target.value);
186+
setOptionValue(""); // Reset option value when category changes
187+
}}
188+
className="w-full px-4 py-2 border rounded-lg"
189+
>
190+
<option value="">Select Category</option>
191+
{categories.map((cat) => (
192+
<option key={cat} value={cat}>{cat}</option>
193+
))}
194+
</select>
195+
</div>
196+
<div>
197+
<label htmlFor="deleteOptionValue" className="block text-sm font-medium text-gray-700">Option Value</label>
198+
<select
199+
id="deleteOptionValue"
200+
value={optionValue}
201+
onChange={(e) => setOptionValue(e.target.value)}
202+
className="w-full px-4 py-2 border rounded-lg"
203+
disabled={!categoryName}
204+
>
205+
<option value="">Select Option</option>
206+
{categoryOptions.map((option) => (
207+
<option key={option.id} value={option.option_value}>
208+
{option.option_value}
209+
</option>
210+
))}
211+
</select>
212+
</div>
213+
{!confirming ? (
214+
<Button
215+
type="button"
216+
onClick={() => setConfirming(true)}
217+
disabled={loading || !categoryName || !optionValue}
218+
variant="destructive"
219+
>
220+
Delete Option
221+
</Button>
222+
) : (
223+
<div className="space-x-4">
224+
<Button onClick={handleDelete} disabled={loading} variant="destructive">
225+
Confirm Delete
226+
</Button>
227+
<Button onClick={() => setConfirming(false)} disabled={loading} variant="outline">
228+
Cancel
229+
</Button>
230+
</div>
231+
)}
232+
{status && <p className="mt-2 text-sm">{status}</p>}
233+
</form>
234+
</div>
235+
);
236+
}

app/admin/ManageCateogory/page.tsx

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)