@@ -6,6 +6,14 @@ import { useRef, useState } from "react";
66import ItemForm from "@/components/admin/items/ItemForm" ;
77import { router } from "@inertiajs/react" ;
88
9+ interface PriceRevertPreviewItem {
10+ id : number ;
11+ name : string ;
12+ current_price : number ;
13+ revert_to : number ;
14+ changed_at : string ;
15+ }
16+
917ModuleRegistry . registerModules ( [ AllCommunityModule ] ) ;
1018
1119interface Props {
@@ -19,6 +27,8 @@ export default function Items({ items, categories }: Props) {
1927 const [ selectedIds , setSelectedIds ] = useState < number [ ] > ( [ ] ) ;
2028 const [ percentage , setPercentage ] = useState < number > ( 0 ) ;
2129 const [ bulkCategory , setBulkCategory ] = useState < string > ( "" ) ;
30+ const [ revertPreview , setRevertPreview ] = useState < PriceRevertPreviewItem [ ] | null > ( null ) ;
31+ const [ previewLoading , setPreviewLoading ] = useState ( false ) ;
2232
2333 const [ colDefs ] = useState ( [
2434 {
@@ -67,6 +77,19 @@ export default function Items({ items, categories }: Props) {
6777 } ) ;
6878 } ;
6979
80+ const openRevertPreview = async ( ) => {
81+ setPreviewLoading ( true ) ;
82+ const res = await fetch ( "/admin/items/preview_price_revert" ) ;
83+ const data : PriceRevertPreviewItem [ ] = await res . json ( ) ;
84+ setRevertPreview ( data ) ;
85+ setPreviewLoading ( false ) ;
86+ } ;
87+
88+ const confirmRevert = ( ) => {
89+ router . post ( "/admin/items/revert_price_changes" ) ;
90+ setRevertPreview ( null ) ;
91+ } ;
92+
7093 const selectionLabel = `${ selectedIds . length } item${ selectedIds . length !== 1 ? "s" : "" } selected` ;
7194
7295 return (
@@ -131,8 +154,71 @@ export default function Items({ items, categories }: Props) {
131154 Apply
132155 </ button >
133156 </ div >
157+
158+ < div className = "ml-auto" >
159+ < button
160+ onClick = { openRevertPreview }
161+ disabled = { previewLoading }
162+ className = "cursor-pointer rounded-lg bg-red-600 px-4 py-1.5 text-sm font-semibold text-white hover:bg-red-700 disabled:cursor-not-allowed disabled:opacity-40"
163+ >
164+ { previewLoading ? "Loading…" : "Revert All Price Changes" }
165+ </ button >
166+ </ div >
134167 </ div >
135168
169+ { revertPreview !== null && (
170+ < div className = "fixed inset-0 z-50 flex items-center justify-center bg-black/40" >
171+ < div className = "w-full max-w-lg rounded-xl bg-white p-6 shadow-xl" >
172+ < h2 className = "mb-1 text-lg font-bold" > Revert Price Changes</ h2 >
173+ { revertPreview . length === 0 ? (
174+ < p className = "py-4 text-sm text-gray-500" > No price changes found in version history.</ p >
175+ ) : (
176+ < >
177+ < p className = "mb-4 text-sm text-gray-500" >
178+ { revertPreview . length } item{ revertPreview . length !== 1 ? "s" : "" } will be reverted:
179+ </ p >
180+ < div className = "max-h-72 overflow-y-auto rounded-lg border border-gray-200" >
181+ < table className = "w-full text-sm" >
182+ < thead className = "sticky top-0 bg-gray-50 text-xs font-semibold uppercase text-gray-500" >
183+ < tr >
184+ < th className = "px-3 py-2 text-left" > Item</ th >
185+ < th className = "px-3 py-2 text-right" > Current</ th >
186+ < th className = "px-3 py-2 text-right" > Revert to</ th >
187+ </ tr >
188+ </ thead >
189+ < tbody className = "divide-y divide-gray-100" >
190+ { revertPreview . map ( ( row ) => (
191+ < tr key = { row . id } >
192+ < td className = "px-3 py-2" > { row . name } </ td >
193+ < td className = "px-3 py-2 text-right text-gray-400" > { row . current_price } </ td >
194+ < td className = "px-3 py-2 text-right font-medium text-green-700" > { row . revert_to } </ td >
195+ </ tr >
196+ ) ) }
197+ </ tbody >
198+ </ table >
199+ </ div >
200+ </ >
201+ ) }
202+ < div className = "mt-5 flex justify-end gap-3" >
203+ < button
204+ onClick = { ( ) => setRevertPreview ( null ) }
205+ className = "cursor-pointer rounded-lg border border-gray-200 px-4 py-1.5 text-sm font-semibold text-gray-700 hover:bg-gray-50"
206+ >
207+ Cancel
208+ </ button >
209+ { revertPreview . length > 0 && (
210+ < button
211+ onClick = { confirmRevert }
212+ className = "cursor-pointer rounded-lg bg-red-600 px-4 py-1.5 text-sm font-semibold text-white hover:bg-red-700"
213+ >
214+ Confirm Revert
215+ </ button >
216+ ) }
217+ </ div >
218+ </ div >
219+ </ div >
220+ ) }
221+
136222 < div style = { { height : 500 } } >
137223 < AgGridReact
138224 ref = { gridRef }
0 commit comments