Skip to content

Commit e55fcae

Browse files
Merge pull request #5 from upayanmazumder-DevLabs/resources-fix
Refactor resource handling in application components
2 parents a0b3bea + 52cdba2 commit e55fcae

13 files changed

Lines changed: 1915 additions & 1928 deletions

File tree

app/src/app/admin/plans/page.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ import AdminPlansDashboard from "../../../components/Admin/AdminPlansDashboard/A
22
import PageHeading from "@/components/ui/PageHeading/PageHeading";
33
const title = "Admin Plans";
44
const description =
5-
"Manage all subscription plans, view plan details, and control plan features. Use the actions below to create, edit, or delete plans. Changes are applied instantly.";
5+
"Manage all subscription plans, view plan details, and control plan features. Use the actions below to create, edit, or delete plans. Changes are applied instantly.";
66

77
export const metadata = {
8-
title,
9-
description,
8+
title,
9+
description,
1010
};
1111

1212
export default function AdminPlansPage() {
13-
return (
14-
<main>
15-
<PageHeading title={title} subtitle={description} />
16-
<AdminPlansDashboard />
17-
</main>
18-
);
13+
return (
14+
<main>
15+
<PageHeading title={title} subtitle={description} />
16+
<AdminPlansDashboard />
17+
</main>
18+
);
1919
}

app/src/components/Admin/AdminPlansDashboard/PlansTable/PlanTable.tsx

Lines changed: 161 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -7,175 +7,175 @@ import Plan from "../../../../types/Plan/Plan";
77
import type PlanTableProps from "../../../../types/Plan/PlanTableProps";
88
import { FaEdit, FaTrash, FaCheckCircle, FaRegCircle } from "react-icons/fa";
99
import {
10-
formatCpu,
11-
formatMemory,
12-
formatStorage,
13-
formatPrice,
10+
formatCpu,
11+
formatMemory,
12+
formatStorage,
13+
formatPrice,
1414
} from "../../../../utils/resources";
1515

1616
const PlanTable: React.FC<PlanTableProps> = ({
17-
plans,
18-
planLoading,
19-
planError,
20-
onEdit,
21-
onDelete,
17+
plans,
18+
planLoading,
19+
planError,
20+
onEdit,
21+
onDelete,
2222
}) => {
23-
const [deleteId, setDeleteId] = useState<string | null>(null);
24-
const [deleteName, setDeleteName] = useState<string>("");
23+
const [deleteId, setDeleteId] = useState<string | null>(null);
24+
const [deleteName, setDeleteName] = useState<string>("");
2525

26-
const handleDeleteClick = (plan: Plan) => {
27-
setDeleteId(plan._id);
28-
setDeleteName(plan.name);
29-
};
26+
const handleDeleteClick = (plan: Plan) => {
27+
setDeleteId(plan._id);
28+
setDeleteName(plan.name);
29+
};
3030

31-
const handleConfirmDelete = () => {
32-
if (deleteId) {
33-
onDelete(deleteId);
34-
setDeleteId(null);
35-
setDeleteName("");
36-
}
37-
};
31+
const handleConfirmDelete = () => {
32+
if (deleteId) {
33+
onDelete(deleteId);
34+
setDeleteId(null);
35+
setDeleteName("");
36+
}
37+
};
3838

39-
const handleCancelDelete = () => {
40-
setDeleteId(null);
41-
setDeleteName("");
42-
};
39+
const handleCancelDelete = () => {
40+
setDeleteId(null);
41+
setDeleteName("");
42+
};
4343

44-
return (
45-
<>
46-
<Modal
47-
open={!!deleteId}
48-
onClose={handleCancelDelete}
49-
title="Confirm Delete"
50-
>
51-
<div className="mb-4">
52-
Are you sure you want to delete the plan{" "}
53-
<span className="font-semibold">{deleteName}</span>?
54-
</div>
55-
<div className="flex gap-2 justify-end">
56-
<AnimatedButton
57-
className="px-3 py-1 text-xs rounded bg-zinc-600 hover:bg-zinc-700"
58-
onClick={handleCancelDelete}
59-
variant="secondary"
60-
>
61-
Cancel
62-
</AnimatedButton>
63-
<AnimatedButton
64-
className="px-3 py-1 text-xs rounded bg-rose-600 hover:bg-rose-700"
65-
onClick={handleConfirmDelete}
66-
variant="danger"
67-
icon={<FaTrash className="text-white" />}
68-
>
69-
Delete
70-
</AnimatedButton>
71-
</div>
72-
</Modal>
73-
{planLoading ? (
74-
<div className="flex justify-center py-8">
75-
<Loader />
76-
</div>
77-
) : planError ? (
78-
<Card>
79-
<div className="text-red-500">{planError}</div>
80-
</Card>
81-
) : (
82-
<Card>
83-
<table className="w-full border text-sm mb-4">
84-
<thead>
85-
<tr className="bg-zinc-800 text-zinc-200">
86-
<th className="p-2">Name</th>
87-
<th className="p-2">Description</th>
88-
<th className="p-2">Resources</th>
89-
<th className="p-2">Price</th>
90-
<th className="p-2">Default</th>
91-
<th className="p-2">Active</th>
92-
<th className="p-2">Actions</th>
93-
</tr>
94-
</thead>
95-
<tbody>
96-
{plans.map((plan: Plan) => (
97-
<tr key={plan._id} className="border-b border-zinc-700">
98-
<td className="p-2 font-semibold">{plan.name}</td>
99-
<td className="p-2">{plan.description}</td>
100-
<td className="p-2">
101-
{plan.resources ? (
102-
<div className="text-xs p-2 rounded flex flex-col gap-1">
103-
<div>
104-
<span className="font-semibold">Req:</span> CPU:{" "}
105-
{formatCpu(plan.resources.requests?.cpuMilli)}, Mem:{" "}
106-
{formatMemory(plan.resources.requests?.memoryMB)},
107-
Storage:{" "}
108-
{formatStorage(plan.resources.requests?.storageGB)}
109-
</div>
110-
<div>
111-
<span className="font-semibold">Lim:</span> CPU:{" "}
112-
{formatCpu(plan.resources.limits?.cpuMilli)}, Mem:{" "}
113-
{formatMemory(plan.resources.limits?.memoryMB)},
114-
Storage:{" "}
115-
{formatStorage(plan.resources.limits?.storageGB)}
116-
</div>
117-
</div>
118-
) : (
119-
"-"
120-
)}
121-
</td>
122-
<td className="p-2 font-mono text-green-400">
123-
{formatPrice(plan.price)}
124-
</td>
125-
<td className="p-2 text-center align-middle">
126-
<div className="flex items-center justify-center h-full min-h-[28px]">
127-
{plan.isDefault ? (
128-
<FaCheckCircle
129-
className="text-emerald-400 text-lg align-middle"
130-
title="Default plan"
131-
/>
132-
) : (
133-
<FaRegCircle
134-
className="text-zinc-500 text-lg align-middle"
135-
title="Not default"
136-
/>
137-
)}
138-
</div>
139-
</td>
140-
<td className="p-2 text-center align-middle">
141-
<div className="flex items-center justify-center h-full min-h-[28px]">
142-
{plan.isActive !== false ? (
143-
<FaCheckCircle
144-
className="text-emerald-400 text-lg align-middle"
145-
title="Active"
146-
/>
147-
) : (
148-
<FaRegCircle
149-
className="text-zinc-500 text-lg align-middle"
150-
title="Inactive"
151-
/>
152-
)}
153-
</div>
154-
</td>
155-
<td className="p-2 flex gap-2">
156-
<AnimatedButton
157-
className="!px-2 !py-1 !text-xs !rounded !bg-sky-600 hover:!bg-sky-700"
158-
onClick={() => onEdit(plan)}
159-
icon={<FaEdit className="text-white" />}
160-
>
161-
Edit
162-
</AnimatedButton>
163-
<AnimatedButton
164-
className="!px-2 !py-1 !text-xs !rounded !bg-rose-600 hover:!bg-rose-700"
165-
onClick={() => handleDeleteClick(plan)}
166-
icon={<FaTrash className="text-white" />}
167-
>
168-
Delete
169-
</AnimatedButton>
170-
</td>
171-
</tr>
172-
))}
173-
</tbody>
174-
</table>
175-
</Card>
176-
)}
177-
</>
178-
);
44+
return (
45+
<>
46+
<Modal
47+
open={!!deleteId}
48+
onClose={handleCancelDelete}
49+
title="Confirm Delete"
50+
>
51+
<div className="mb-4">
52+
Are you sure you want to delete the plan{" "}
53+
<span className="font-semibold">{deleteName}</span>?
54+
</div>
55+
<div className="flex gap-2 justify-end">
56+
<AnimatedButton
57+
className="px-3 py-1 text-xs rounded bg-zinc-600 hover:bg-zinc-700"
58+
onClick={handleCancelDelete}
59+
variant="secondary"
60+
>
61+
Cancel
62+
</AnimatedButton>
63+
<AnimatedButton
64+
className="px-3 py-1 text-xs rounded bg-rose-600 hover:bg-rose-700"
65+
onClick={handleConfirmDelete}
66+
variant="danger"
67+
icon={<FaTrash className="text-white" />}
68+
>
69+
Delete
70+
</AnimatedButton>
71+
</div>
72+
</Modal>
73+
{planLoading ? (
74+
<div className="flex justify-center py-8">
75+
<Loader />
76+
</div>
77+
) : planError ? (
78+
<Card>
79+
<div className="text-red-500">{planError}</div>
80+
</Card>
81+
) : (
82+
<Card>
83+
<table className="w-full border text-sm mb-4">
84+
<thead>
85+
<tr className="bg-zinc-800 text-zinc-200">
86+
<th className="p-2">Name</th>
87+
<th className="p-2">Description</th>
88+
<th className="p-2">Resources</th>
89+
<th className="p-2">Price</th>
90+
<th className="p-2">Default</th>
91+
<th className="p-2">Active</th>
92+
<th className="p-2">Actions</th>
93+
</tr>
94+
</thead>
95+
<tbody>
96+
{plans.map((plan: Plan) => (
97+
<tr key={plan._id} className="border-b border-zinc-700">
98+
<td className="p-2 font-semibold">{plan.name}</td>
99+
<td className="p-2">{plan.description}</td>
100+
<td className="p-2">
101+
{plan.resources ? (
102+
<div className="text-xs p-2 rounded flex flex-col gap-1">
103+
<div>
104+
<span className="font-semibold">Req:</span> CPU:{" "}
105+
{formatCpu(plan.resources.requests?.cpu)}, Mem:{" "}
106+
{formatMemory(plan.resources.requests?.memory)},
107+
Storage:{" "}
108+
{formatStorage(plan.resources.requests?.storage)}
109+
</div>
110+
<div>
111+
<span className="font-semibold">Lim:</span> CPU:{" "}
112+
{formatCpu(plan.resources.limits?.cpu)}, Mem:{" "}
113+
{formatMemory(plan.resources.limits?.memory)},
114+
Storage:{" "}
115+
{formatStorage(plan.resources.limits?.storage)}
116+
</div>
117+
</div>
118+
) : (
119+
"-"
120+
)}
121+
</td>
122+
<td className="p-2 font-mono text-green-400">
123+
{formatPrice(plan.price)}
124+
</td>
125+
<td className="p-2 text-center align-middle">
126+
<div className="flex items-center justify-center h-full min-h-[28px]">
127+
{plan.isDefault ? (
128+
<FaCheckCircle
129+
className="text-emerald-400 text-lg align-middle"
130+
title="Default plan"
131+
/>
132+
) : (
133+
<FaRegCircle
134+
className="text-zinc-500 text-lg align-middle"
135+
title="Not default"
136+
/>
137+
)}
138+
</div>
139+
</td>
140+
<td className="p-2 text-center align-middle">
141+
<div className="flex items-center justify-center h-full min-h-[28px]">
142+
{plan.isActive !== false ? (
143+
<FaCheckCircle
144+
className="text-emerald-400 text-lg align-middle"
145+
title="Active"
146+
/>
147+
) : (
148+
<FaRegCircle
149+
className="text-zinc-500 text-lg align-middle"
150+
title="Inactive"
151+
/>
152+
)}
153+
</div>
154+
</td>
155+
<td className="p-2 flex gap-2">
156+
<AnimatedButton
157+
className="!px-2 !py-1 !text-xs !rounded !bg-sky-600 hover:!bg-sky-700"
158+
onClick={() => onEdit(plan)}
159+
icon={<FaEdit className="text-white" />}
160+
>
161+
Edit
162+
</AnimatedButton>
163+
<AnimatedButton
164+
className="!px-2 !py-1 !text-xs !rounded !bg-rose-600 hover:!bg-rose-700"
165+
onClick={() => handleDeleteClick(plan)}
166+
icon={<FaTrash className="text-white" />}
167+
>
168+
Delete
169+
</AnimatedButton>
170+
</td>
171+
</tr>
172+
))}
173+
</tbody>
174+
</table>
175+
</Card>
176+
)}
177+
</>
178+
);
179179
};
180180

181181
export default PlanTable;

0 commit comments

Comments
 (0)