From 551a0ea71a8b6b34dd0c7a0c2eb5035d9d2d6f53 Mon Sep 17 00:00:00 2001 From: RKWojs Date: Fri, 12 Sep 2025 13:36:28 +0200 Subject: [PATCH] feat: Implement mobile-friendly filter toggle and enhance project list filters --- src/app/projects/[id]/page.js | 186 ++++++++++++++++------- src/app/projects/page.js | 276 +++++++++++++++++++++++++--------- 2 files changed, 333 insertions(+), 129 deletions(-) diff --git a/src/app/projects/[id]/page.js b/src/app/projects/[id]/page.js index 412fa4a..d278b73 100644 --- a/src/app/projects/[id]/page.js +++ b/src/app/projects/[id]/page.js @@ -99,62 +99,140 @@ export default function ProjectViewPage() { if (days <= 7) return "warning"; return "success"; }; + return ( - - - {daysRemaining !== null && ( - - {daysRemaining === 0 - ? "Termin dzisiaj" - : daysRemaining > 0 - ? `${daysRemaining} dni pozostało` - : `${Math.abs(daysRemaining)} dni po terminie`} - - )} - - - - - - + {/* Mobile: Full-width title, Desktop: Standard PageHeader */} +
+ {/* Mobile Layout */} +
+ {/* Full-width title */} +
+

+ {project.project_name} +

+

+ {project.city} • {project.address} +

- } - />{" "} + + {/* Mobile action bar */} +
+ {/* Status and deadline badges */} +
+ + {daysRemaining !== null && ( + + {daysRemaining === 0 + ? "Termin dzisiaj" + : daysRemaining > 0 + ? `${daysRemaining} dni pozostało` + : `${Math.abs(daysRemaining)} dni po terminie`} + + )} +
+ + {/* Action buttons - full width */} +
+ + + + + + +
+
+
+
+ + {/* Desktop: Standard PageHeader */} +
+ + + {daysRemaining !== null && ( + + {daysRemaining === 0 + ? "Termin dzisiaj" + : daysRemaining > 0 + ? `${daysRemaining} dni pozostało` + : `${Math.abs(daysRemaining)} dni po terminie`} + + )} + + + + + + +
+ } + /> + +
{/* Main Project Information */}
@@ -446,7 +524,7 @@ export default function ProjectViewPage() {
-
{" "} + {/* Project Location Map */} {project.coordinates && (
diff --git a/src/app/projects/page.js b/src/app/projects/page.js index 674157b..a12045f 100644 --- a/src/app/projects/page.js +++ b/src/app/projects/page.js @@ -25,6 +25,7 @@ export default function ProjectListPage() { }); const [customers, setCustomers] = useState([]); + const [filtersExpanded, setFiltersExpanded] = useState(true); // Start expanded on mobile so users know filters exist useEffect(() => { fetch("/api/projects") @@ -113,6 +114,21 @@ export default function ProjectListPage() { setSearchTerm(''); }; + const toggleFilters = () => { + setFiltersExpanded(!filtersExpanded); + }; + + const hasActiveFilters = filters.status !== 'all' || filters.type !== 'all' || filters.customer !== 'all' || searchTerm.trim() !== ''; + + const getActiveFilterCount = () => { + let count = 0; + if (filters.status !== 'all') count++; + if (filters.type !== 'all') count++; + if (filters.customer !== 'all') count++; + if (searchTerm.trim()) count++; + return count; + }; + const getStatusLabel = (status) => { switch(status) { case "registered": return t('projectStatus.registered'); @@ -185,76 +201,186 @@ export default function ProjectListPage() { {/* Filters */} - -
-
- - -
- -
- - -
- -
- - -
- - {(filters.status !== 'all' || filters.type !== 'all' || filters.customer !== 'all' || searchTerm) && ( + {/* Mobile collapsible header */} +
+
+ + + +

+ {t('common.filters') || 'Filtry'} + {hasActiveFilters && ( + + {getActiveFilterCount()} + + )} +

+
+
+ {hasActiveFilters && ( )} - -
+
{t('projects.showingResults', { shown: filteredProjects.length, total: projects.length }) || `Wyświetlono ${filteredProjects.length} z ${projects.length} projektów`}
- +
+ + {/* Mobile collapsible content */} +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+
+
+
+ + {/* Desktop always visible content */} +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ + {(filters.status !== 'all' || filters.type !== 'all' || filters.customer !== 'all' || searchTerm) && ( + + )} + +
+ {t('projects.showingResults', { shown: filteredProjects.length, total: projects.length }) || `Wyświetlono ${filteredProjects.length} z ${projects.length} projektów`} +
+
+
+
{filteredProjects.length === 0 && searchTerm ? ( @@ -314,37 +440,37 @@ export default function ProjectListPage() {
{/* Mobile scroll container */}
- +
- - - - - - - - - - @@ -362,15 +488,15 @@ export default function ProjectListPage() { {project.project_number} -
+ Nr. + {t('projects.projectName')} + WP + {t('projects.city')} + {t('projects.address')} + {t('projects.plot')} + {t('projects.finishDate')} + {t('common.type') || 'Typ'} + {t('common.status') || 'Status'} + {t('common.actions') || 'Akcje'}
+ - {project.project_name.length > 30 - ? `${project.project_name.substring(0, 30)}...` + {project.project_name.length > 20 + ? `${project.project_name.substring(0, 20)}...` : project.project_name}