@@ -3,22 +3,25 @@ import type { Rule, RulePayload } from "../@types/rules";
33import { getRules , createRule , updateRule , deleteRule } from "../services/rules" ;
44import RuleFormModal from "./RuleFormModal" ;
55
6+ const PAGE_SIZE = 3 ;
7+
68const RulesAdminView : React . FC = ( ) => {
79 const [ rules , setRules ] = useState < Rule [ ] > ( [ ] ) ;
8- const [ _ , setTotal ] = useState ( 0 ) ;
10+ const [ currentPage , setCurrentPage ] = useState ( 1 ) ;
11+ const [ total , setTotal ] = useState ( 0 ) ;
912 const [ selectedRule , setSelectedRule ] = useState < Rule | null > ( null ) ;
1013 const [ showModal , setShowModal ] = useState ( false ) ;
1114 const [ expandedRuleId , setExpandedRuleId ] = useState < string | null > ( null ) ;
1215
13- const fetchRules = async ( ) => {
14- const { rules, total } = await getRules ( ) ;
16+ const fetchRules = async ( page = 1 ) => {
17+ const { rules, total } = await getRules ( { page } ) ;
1518 setRules ( rules ) ;
1619 setTotal ( total ) ;
1720 } ;
1821
1922 useEffect ( ( ) => {
20- fetchRules ( ) ;
21- } , [ ] ) ;
23+ fetchRules ( currentPage ) ;
24+ } , [ currentPage ] ) ;
2225
2326 const handleCreate = ( ) => {
2427 setSelectedRule ( null ) ;
@@ -33,7 +36,14 @@ const RulesAdminView: React.FC = () => {
3336 const handleDelete = async ( id : string ) => {
3437 if ( window . confirm ( "Are you sure you want to delete this rule?" ) ) {
3538 await deleteRule ( id ) ;
36- fetchRules ( ) ;
39+
40+ const newTotal = total - 1 ;
41+ const newTotalPages = Math . ceil ( newTotal / PAGE_SIZE ) ;
42+ const newPage = currentPage > newTotalPages ? Math . max ( 1 , currentPage - 1 ) : currentPage ;
43+
44+ setCurrentPage ( newPage ) ;
45+ await fetchRules ( newPage ) ;
46+
3747 if ( expandedRuleId === id ) {
3848 setExpandedRuleId ( null ) ;
3949 }
@@ -43,11 +53,13 @@ const RulesAdminView: React.FC = () => {
4353 const handleSubmit = async ( data : RulePayload ) => {
4454 if ( selectedRule ) {
4555 await updateRule ( selectedRule . id , data ) ;
56+ await fetchRules ( currentPage ) ;
4657 } else {
4758 await createRule ( data ) ;
59+ setCurrentPage ( 1 ) ;
60+ await fetchRules ( 1 ) ;
4861 }
4962 setShowModal ( false ) ;
50- fetchRules ( ) ;
5163 } ;
5264
5365 const toggleExpandRule = ( id : string ) => {
@@ -136,6 +148,35 @@ const RulesAdminView: React.FC = () => {
136148 ) ) }
137149 </ div >
138150
151+ < div className = "flex items-center justify-between border-t border-gray-200 pt-4" >
152+ < div >
153+ < p className = "text-sm text-gray-700" >
154+ Showing < span className = "font-medium" > { ( currentPage - 1 ) * PAGE_SIZE + 1 } </ span > to{ ' ' }
155+ < span className = "font-medium" > { Math . min ( currentPage * PAGE_SIZE , total ) } </ span > of{ ' ' }
156+ < span className = "font-medium" > { total } </ span > results
157+ </ p >
158+ </ div >
159+ < div className = "flex justify-end items-center space-x-2 pt-4" >
160+ < button
161+ onClick = { ( ) => setCurrentPage ( ( p ) => Math . max ( 1 , p - 1 ) ) }
162+ disabled = { currentPage === 1 }
163+ className = "px-3 py-1 border border-gray-300 rounded text-sm disabled:opacity-50 hover:bg-gray-50"
164+ >
165+ Previous
166+ </ button >
167+ < span className = "text-sm text-gray-600" >
168+ Page { currentPage } of { Math . ceil ( total / PAGE_SIZE ) }
169+ </ span >
170+ < button
171+ onClick = { ( ) => setCurrentPage ( ( p ) => p + 1 ) }
172+ disabled = { currentPage >= Math . ceil ( total / PAGE_SIZE ) }
173+ className = "px-3 py-1 border border-gray-300 rounded text-sm disabled:opacity-50 hover:bg-gray-50"
174+ >
175+ Next
176+ </ button >
177+ </ div >
178+ </ div >
179+
139180 { showModal && (
140181 < RuleFormModal
141182 initialData = { selectedRule }
0 commit comments