Hide Archived Productions
Deploy / deploy (push) Successful in 2m43s

This commit is contained in:
twotalesanimation
2026-08-06 10:42:49 +02:00
parent d2c91e7b65
commit 7b36329769
3 changed files with 55 additions and 1 deletions
+12 -1
View File
@@ -7,10 +7,16 @@ import { Input } from "@/components/ui/input";
import { ProjectCard } from "@/components/projects/ProjectCard"; import { ProjectCard } from "@/components/projects/ProjectCard";
import { NewProjectDialog } from "@/components/projects/NewProjectDialog"; import { NewProjectDialog } from "@/components/projects/NewProjectDialog";
import { Plus, Search, Loader2 } from "lucide-react"; import { Plus, Search, Loader2 } from "lucide-react";
import { HIDE_ARCHIVED_KEY } from "@/components/settings/HideArchivedToggle";
export default function ProjectsPage() { export default function ProjectsPage() {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
const [showNew, setShowNew] = useState(false); const [showNew, setShowNew] = useState(false);
const [hideArchived, setHideArchived] = useState(false);
useEffect(() => {
setHideArchived(localStorage.getItem(HIDE_ARCHIVED_KEY) === "1");
}, []);
const { data, isLoading } = useQuery({ const { data, isLoading } = useQuery({
queryKey: ["projects", search], queryKey: ["projects", search],
@@ -35,6 +41,8 @@ export default function ProjectsPage() {
const projects = data?.projects ?? []; const projects = data?.projects ?? [];
const clients = clientsData?.clients ?? []; const clients = clientsData?.clients ?? [];
const visibleProjects = hideArchived ? projects.filter((p: any) => p.status !== "ARCHIVED") : projects;
const SCROLL_KEY = 'projects-scroll'; const SCROLL_KEY = 'projects-scroll';
useEffect(() => { useEffect(() => {
@@ -56,6 +64,9 @@ export default function ProjectsPage() {
<h1 className="text-3xl font-bold text-white">Projects</h1> <h1 className="text-3xl font-bold text-white">Projects</h1>
<p className="text-zinc-400 mt-1"> <p className="text-zinc-400 mt-1">
{projects.length} project{projects.length !== 1 ? "s" : ""} {projects.length} project{projects.length !== 1 ? "s" : ""}
{hideArchived && projects.length !== visibleProjects.length && (
<span className="text-zinc-600 ml-1">({projects.length - visibleProjects.length} archived hidden)</span>
)}
</p> </p>
</div> </div>
<Button onClick={() => setShowNew(true)} className="gap-2"> <Button onClick={() => setShowNew(true)} className="gap-2">
@@ -94,7 +105,7 @@ export default function ProjectsPage() {
</div> </div>
) : ( ) : (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
{projects.map((project) => ( {visibleProjects.map((project: any) => (
<div key={project.id} onClick={saveScroll}> <div key={project.id} onClick={saveScroll}>
<ProjectCard project={project} /> <ProjectCard project={project} />
</div> </div>
+10
View File
@@ -5,6 +5,7 @@ import { getInitials } from "@/lib/utils";
import { ChangePasswordForm } from "@/components/settings/ChangePasswordForm"; import { ChangePasswordForm } from "@/components/settings/ChangePasswordForm";
import { HetznerConfigForm } from "@/components/settings/HetznerConfigForm"; import { HetznerConfigForm } from "@/components/settings/HetznerConfigForm";
import { SketchTemplatesSection } from "@/components/settings/SketchTemplatesSection"; import { SketchTemplatesSection } from "@/components/settings/SketchTemplatesSection";
import { HideArchivedToggle } from "@/components/settings/HideArchivedToggle";
import { getHetznerConfig } from "@/actions/settings"; import { getHetznerConfig } from "@/actions/settings";
export const metadata = { title: "Settings" }; export const metadata = { title: "Settings" };
@@ -42,6 +43,15 @@ export default async function SettingsPage() {
</CardContent> </CardContent>
</Card> </Card>
<Card>
<CardHeader>
<CardTitle className="text-base">Display Preferences</CardTitle>
</CardHeader>
<CardContent>
<HideArchivedToggle />
</CardContent>
</Card>
<ChangePasswordForm mustChangePassword={session.user.mustChangePassword ?? false} /> <ChangePasswordForm mustChangePassword={session.user.mustChangePassword ?? false} />
{isAdmin && hetznerConfig && ( {isAdmin && hetznerConfig && (
@@ -0,0 +1,33 @@
"use client";
import { useState, useEffect } from "react";
export const HIDE_ARCHIVED_KEY = "app:hideArchivedProjects";
export function HideArchivedToggle() {
const [checked, setChecked] = useState(false);
useEffect(() => {
setChecked(localStorage.getItem(HIDE_ARCHIVED_KEY) === "1");
}, []);
const toggle = (val: boolean) => {
setChecked(val);
localStorage.setItem(HIDE_ARCHIVED_KEY, val ? "1" : "0");
};
return (
<label className="flex items-center gap-3 cursor-pointer select-none">
<input
type="checkbox"
checked={checked}
onChange={(e) => toggle(e.target.checked)}
className="cursor-pointer accent-blue-500 w-4 h-4 shrink-0"
/>
<div>
<p className="text-sm font-medium text-zinc-200">Hide archived productions</p>
<p className="text-xs text-muted-foreground mt-0.5">Archived projects won&apos;t appear on the Projects page</p>
</div>
</label>
);
}