@@ -7,175 +7,175 @@ import Plan from "../../../../types/Plan/Plan";
77import type PlanTableProps from "../../../../types/Plan/PlanTableProps" ;
88import { FaEdit , FaTrash , FaCheckCircle , FaRegCircle } from "react-icons/fa" ;
99import {
10- formatCpu ,
11- formatMemory ,
12- formatStorage ,
13- formatPrice ,
10+ formatCpu ,
11+ formatMemory ,
12+ formatStorage ,
13+ formatPrice ,
1414} from "../../../../utils/resources" ;
1515
1616const 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
181181export default PlanTable ;
0 commit comments