settings page responsive design fixes

This commit is contained in:
corgifist 2025-07-28 18:27:23 +03:00
parent fb5cf87b43
commit 2304b7223f
8 changed files with 71 additions and 51 deletions

View File

@ -2,6 +2,7 @@
@import "tw-animate-css";
@import "tailwindcss-safe-area";
@custom-variant dark (&:is(.dark *));
@custom-variant adjust (&:where([data-adjust="true"] *));
@theme inline {
--color-background: var(--background);

View File

@ -34,6 +34,7 @@ import StaticSidebarTrigger from "@/components/static-sidebar-trigger";
import SidebarTriggerAdjustable from "@/components/sidebar-trigger-adjustable";
import ScrollFadingTitle from "@/components/scroll-fading-title";
import { fa } from "zod/v4/locales";
import AscendingCard from "@/components/ascending-card";
type SortingType = "byCreationDate"
| "byEditDate"
@ -412,7 +413,7 @@ const ProjectContainer = ({
return (
<AspectRatio data-selectable="true" ratio={16 / 9} onClick={handleCheck}>
<Card className="relative rounded-lg shadow-md w-full h-full overflow-hidden hover:scale-[101%] hover:drop-shadow-xl duration-100" data-selectable="true">
<AscendingCard className="relative rounded-lg w-full h-full overflow-hidden" data-selectable="true">
<div className="absolute bottom-0 left-0 w-full h-full bg-gradient-to-t from-white dark:from-black to-transparent opacity-50" data-selectable="true" />
<div className="absolute bottom-0 left-0 p-2 w-full flex flex-row justify-between items-center" data-selectable="true">
<div data-selectable="true">
@ -430,7 +431,7 @@ const ProjectContainer = ({
<Checkbox checked={selectedProjects.includes(project.uuid)} onCheckedChange={(_) => handleCheck} />
</div>
)}
</Card>
</AscendingCard>
</AspectRatio>
)
};

View File

@ -3,7 +3,7 @@ import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { SidebarTrigger } from "@/components/ui/sidebar";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { ChartPieIcon, InfoIcon } from "lucide-react";
import { ChartPieIcon, ChevronRightIcon, InfoIcon } from "lucide-react";
import { ReactNode, useEffect, useState } from "react";
import { usePersistenceContext } from "../persistence-provider";
import StaticSidebarTrigger from "@/components/static-sidebar-trigger";
@ -14,12 +14,12 @@ import { useIsMobile } from "@/hooks/use-mobile";
import { cn } from "@/lib/utils";
import AscendingCard from "@/components/ascending-card";
import Link from "next/link";
import WideAscendingCard from "@/components/wide-container";
import WideContainer from "@/components/wide-container";
export default function Settings(): ReactNode {
const isMobile = useIsMobile();
const cardWidth = isMobile ? "w-full" : "w-2xl";
return (
<div className="p-5 w-full h-full">
<div className="flex flex-row items-center gap-2">
@ -29,22 +29,29 @@ export default function Settings(): ReactNode {
</ScrollFadingTitle>
</div>
<div className="flex flex-col sticky top-safe bg-background gap-2 mt-2 pb-2 pt-2 p-5 w-[100% + 5 * var(--spacing)] z-10 -mx-5">
<SidebarTriggerAdjustable className={cn("flex justify-center",)}>
<Search placeholder="Search Settings" className={cardWidth} />
<SidebarTriggerAdjustable adjustWidth={!isMobile ? 0 : 12} className="flex items-center justify-center">
<WideContainer>
<Search />
</WideContainer>
</SidebarTriggerAdjustable>
</div>
<div className="flex flex-col justify-center items-center w-full gap-1 md:lg:gap-2 mt-2">
<Link href="/settings/storage" className="w-full flex items-center justify-center">
<AscendingCard className={`flex flex-row gap-3 p-3 ${cardWidth}`}>
<div className="flex items-center justify-center">
<ChartPieIcon />
</div>
<div className="flex flex-col items-start">
<h3 className="font-semibold break-keep text-lg sm:text-xl">Storage</h3>
<p className="text-sm text-secondary-foreground">Memory usage, media, cache etc.</p>
</div>
</AscendingCard>
</Link>
<div className="flex flex-col items-center gap-1 md:lg:gap-2 mt-2 h-screen">
<WideContainer>
<Link href="/settings/storage">
<AscendingCard className="flex flex-row justify-between items-center gap-2 p-4">
<div className="flex flex-row justify-between items-center gap-3">
<div className="flex items-center justify-center">
<ChartPieIcon />
</div>
<div className="flex flex-col items-start">
<h3 className="font-semibold break-keep text-lg sm:text-xl">Storage</h3>
<p className="text-sm text-secondary-foreground">Memory usage, media, cache etc.</p>
</div>
</div>
<ChevronRightIcon />
</AscendingCard>
</Link>
</WideContainer>
</div>
</div>
);

View File

@ -1,11 +1,13 @@
"use client";
import { usePersistenceContext } from "@/app/persistence-provider";
import AscendingCard from "@/components/ascending-card";
import ScrollFadingTitle from "@/components/scroll-fading-title";
import Search from "@/components/search";
import SidebarTriggerAdjustable from "@/components/sidebar-trigger-adjustable";
import StaticSidebarTrigger from "@/components/static-sidebar-trigger";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import WideContainer from "@/components/wide-container";
import { useIsMobile } from "@/hooks/use-mobile";
import { cn } from "@/lib/utils";
import { ArrowLeftIcon } from "lucide-react";
@ -33,8 +35,6 @@ export default function Storage() {
setStatus(localStorage.getItem("persistence-status"));
}, []);
const cardWidth = isMobile ? "w-full" : "w-2xl";
return (
<div className="p-5 w-full">
<div className="flex flex-row items-center gap-2">
@ -49,15 +49,21 @@ export default function Storage() {
</ScrollFadingTitle>
</div>
<div className="flex flex-col sticky top-safe bg-background gap-2 mt-2 pb-2 pt-2 p-5 w-[100% + 5 * var(--spacing)] z-10 -mx-5">
<SidebarTriggerAdjustable adjustWidth="20" className={cn("flex justify-center", cardWidth)}>
<Search placeholder="Search Settings" className={cardWidth} />
<SidebarTriggerAdjustable adjustWidth={!isMobile ? 0 : 12} className="flex items-center justify-center">
<WideContainer>
<Search />
</WideContainer>
</SidebarTriggerAdjustable>
</div>
<div className="flex flex-row justify-between items-center w-full max-w-96">
<div className="flex flex-row gap-2 items-center">
<Label>Persistent Storage</Label>
</div>
<PersistentStorageControl status={status} />
<div className="flex flex-col items-center justify-start gap-1 md:lg:gap-2 mt-2 h-screen">
<WideContainer>
<AscendingCard className="flex flex-row justify-between items-center p-4">
<div className="flex flex-row gap-2 ">
<Label>Persistent Storage</Label>
</div>
<PersistentStorageControl status={status} />
</AscendingCard>
</WideContainer>
</div>
</div>
)

View File

@ -7,6 +7,7 @@ import { cn } from "@/lib/utils";
export const Search = (props: ComponentProps<typeof Input>): ReactNode => (
<div className={cn("relative", props.className)}>
<Input
placeholder="Search"
{...props}
type="text"
className="peer block w-full rounded-md border py-[9px] pl-10"

View File

@ -1,7 +1,5 @@
"use client";
import { useIsMobile } from "@/hooks/use-mobile";
import { cn } from "@/lib/utils";
import { sign } from "crypto";
import { ComponentProps, useEffect, useState } from "react";
const easeSlide = (x: number) => (
@ -11,41 +9,32 @@ const easeSlide = (x: number) => (
const lerp = (a: number, b: number, t: number) => (
a * t + b * (1 - t)
);
const cssLerp = (a: string, b: string, t: string) => (
`${a} * ${t} + ${b} * (1 - ${t})`
);
export const SidebarTriggerAdjustable = (props: ComponentProps<"div"> & {
adjustWidth?: number | `${number}`;
adjustWidth?: number | `${number}`
}) => {
const adjustWidth = props.adjustWidth ? +props.adjustWidth : 12;
const adjustWidth = props.adjustWidth === undefined ? 12 : +props.adjustWidth;
const isMobile = useIsMobile();
const [slideAmount, setSlideAmount] = useState(0);
useEffect(() => {
const triggerElement = document.querySelector('div[data-sidebar-trigger="true"]');
const handleScroll = () => {
if (!triggerElement) {
console.log("triggerElement is null");
return;
}
const triggerDiv = triggerElement as HTMLDivElement;
const slideAmount = easeSlide(
const handleScroll = () =>
setSlideAmount(easeSlide(
Math.max(0, Math.min(1, window.scrollY / (window.innerHeight / 20)))
);
triggerDiv.style.transform = `translateX(calc(var(--spacing) * ${adjustWidth * slideAmount}))`;
triggerDiv.style.paddingTop = `calc(var(--spacing) * ${(isMobile ? 1 : 3) * slideAmount})`;
triggerDiv.style.width = `calc(100% - var(--spacing) * ${lerp(0, adjustWidth, 1 - slideAmount)})`;
};
));
handleScroll();
window.addEventListener('scroll', handleScroll, {passive: true});
window.addEventListener('scroll', handleScroll, { passive: true });
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, [isMobile]);
return <div data-sidebar-trigger="true" className={props.className}>{props.children}</div>;
return <div style={{
transform: `translateX(calc(var(--spacing) * ${adjustWidth * slideAmount}))`,
marginTop: `calc(var(--spacing) * ${(isMobile ? 1 : 3) * slideAmount})`,
width: `calc(100% - var(--spacing) * ${lerp(0, adjustWidth, 1 - slideAmount)})`
}} className={props.className}>{props.children}</div>;
}

View File

@ -0,0 +1,12 @@
import { ComponentProps } from "react";
import { useIsMobile } from "@/hooks/use-mobile";
import { cn } from "@/lib/utils";
export const WideContainer = (props: ComponentProps<"div">) => {
const isMobile = useIsMobile();
const cardWidth = "max-w-2xl w-full md:w-85 lg:w-130 xl:w-2xl";
return (
<div {...props} className={cn(`${isMobile ? "w-full" : cardWidth}`, props.className)}/>
);
};

View File

@ -0,0 +1,3 @@
import { WideContainer } from "./WideContainer";
export default WideContainer;