feat: Add 'mine' filter to ProjectListPage and update translations

This commit is contained in:
2025-09-29 22:07:18 +02:00
parent 769fc73898
commit a59dc83678
2 changed files with 41 additions and 4 deletions

View File

@@ -12,16 +12,19 @@ import SearchBar from "@/components/ui/SearchBar";
import { LoadingState } from "@/components/ui/States"; import { LoadingState } from "@/components/ui/States";
import { formatDate } from "@/lib/utils"; import { formatDate } from "@/lib/utils";
import { useTranslation } from "@/lib/i18n"; import { useTranslation } from "@/lib/i18n";
import { useSession } from "next-auth/react";
export default function ProjectListPage() { export default function ProjectListPage() {
const { t } = useTranslation(); const { t } = useTranslation();
const { data: session } = useSession();
const [projects, setProjects] = useState([]); const [projects, setProjects] = useState([]);
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState("");
const [filteredProjects, setFilteredProjects] = useState([]); const [filteredProjects, setFilteredProjects] = useState([]);
const [filters, setFilters] = useState({ const [filters, setFilters] = useState({
status: 'all', status: 'all',
type: 'all', type: 'all',
customer: 'all' customer: 'all',
mine: false
}); });
const [customers, setCustomers] = useState([]); const [customers, setCustomers] = useState([]);
@@ -63,6 +66,11 @@ export default function ProjectListPage() {
filtered = filtered.filter(project => project.customer === filters.customer); filtered = filtered.filter(project => project.customer === filters.customer);
} }
// Apply mine filter
if (filters.mine && session?.user?.id) {
filtered = filtered.filter(project => project.assigned_to === session.user.id);
}
// Apply search term // Apply search term
if (searchTerm.trim()) { if (searchTerm.trim()) {
const searchLower = searchTerm.toLowerCase(); const searchLower = searchTerm.toLowerCase();
@@ -80,7 +88,7 @@ export default function ProjectListPage() {
} }
setFilteredProjects(filtered); setFilteredProjects(filtered);
}, [searchTerm, projects, filters]); }, [searchTerm, projects, filters, session]);
async function handleDelete(id) { async function handleDelete(id) {
const confirmed = confirm(t('projects.deleteConfirm')); const confirmed = confirm(t('projects.deleteConfirm'));
@@ -109,7 +117,8 @@ export default function ProjectListPage() {
setFilters({ setFilters({
status: 'all', status: 'all',
type: 'all', type: 'all',
customer: 'all' customer: 'all',
mine: false
}); });
setSearchTerm(''); setSearchTerm('');
}; };
@@ -118,13 +127,14 @@ export default function ProjectListPage() {
setFiltersExpanded(!filtersExpanded); setFiltersExpanded(!filtersExpanded);
}; };
const hasActiveFilters = filters.status !== 'all' || filters.type !== 'all' || filters.customer !== 'all' || searchTerm.trim() !== ''; const hasActiveFilters = filters.status !== 'all' || filters.type !== 'all' || filters.customer !== 'all' || filters.mine || searchTerm.trim() !== '';
const getActiveFilterCount = () => { const getActiveFilterCount = () => {
let count = 0; let count = 0;
if (filters.status !== 'all') count++; if (filters.status !== 'all') count++;
if (filters.type !== 'all') count++; if (filters.type !== 'all') count++;
if (filters.customer !== 'all') count++; if (filters.customer !== 'all') count++;
if (filters.mine) count++;
if (searchTerm.trim()) count++; if (searchTerm.trim()) count++;
return count; return count;
}; };
@@ -170,6 +180,29 @@ export default function ProjectListPage() {
{t('projects.mapView') || 'Widok mapy'} {t('projects.mapView') || 'Widok mapy'}
</Button> </Button>
</Link> </Link>
{session?.user && (
<Button
variant={filters.mine ? "primary" : "outline"}
size="lg"
className="w-full sm:w-auto"
onClick={() => handleFilterChange('mine', !filters.mine)}
>
<svg
className="w-5 h-5 mr-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
{t('projects.mine') || 'Moje'}
</Button>
)}
<Link href="/projects/new" className="w-full sm:w-auto"> <Link href="/projects/new" className="w-full sm:w-auto">
<Button variant="primary" size="lg" className="w-full"> <Button variant="primary" size="lg" className="w-full">
<svg <svg

View File

@@ -71,6 +71,7 @@ const translations = {
view: "Wyświetl", view: "Wyświetl",
clearSearch: "Wyczyść wyszukiwanie", clearSearch: "Wyczyść wyszukiwanie",
filters:"Filtry", filters:"Filtry",
clearAll: "Wyczyść",
clearAllFilters: "Wyczyść wszystkie filtry", clearAllFilters: "Wyczyść wszystkie filtry",
sortBy: "Sortuj według", sortBy: "Sortuj według",
days: "dni" days: "dni"
@@ -162,6 +163,7 @@ const translations = {
notFinished: "Nie zakończone", notFinished: "Nie zakończone",
projects: "projektów", projects: "projektów",
mapView: "Widok mapy", mapView: "Widok mapy",
mine: "Moje",
createFirstProject: "Utwórz pierwszy projekt", createFirstProject: "Utwórz pierwszy projekt",
noMatchingResults: "Brak projektów pasujących do kryteriów wyszukiwania. Spróbuj zmienić wyszukiwane frazy.", noMatchingResults: "Brak projektów pasujących do kryteriów wyszukiwania. Spróbuj zmienić wyszukiwane frazy.",
showingResults: "Wyświetlono {shown} z {total} projektów", showingResults: "Wyświetlono {shown} z {total} projektów",
@@ -631,6 +633,7 @@ const translations = {
view: "View", view: "View",
clearSearch: "Clear search", clearSearch: "Clear search",
filters: "Filters", filters: "Filters",
clearAll: "Clear",
clearAllFilters: "Clear all filters", clearAllFilters: "Clear all filters",
sortBy: "Sort by", sortBy: "Sort by",
days: "days" days: "days"
@@ -717,6 +720,7 @@ const translations = {
notFinished: "Not finished", notFinished: "Not finished",
projects: "projects", projects: "projects",
mapView: "Map View", mapView: "Map View",
mine: "Mine",
createFirstProject: "Create first project", createFirstProject: "Create first project",
noMatchingResults: "No projects match the search criteria. Try changing your search terms.", noMatchingResults: "No projects match the search criteria. Try changing your search terms.",
showingResults: "Showing {shown} of {total} projects", showingResults: "Showing {shown} of {total} projects",