diff --git a/package-lock.json b/package-lock.json index dd73cb5..e807177 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,8 @@ "react-hook-form": "^7.60.0", "sonner": "^2.0.6", "tailwind-merge": "^3.3.1", + "tailwindcss-safe-area": "^1.0.0", + "use-debounce": "^10.0.5", "zod": "^4.0.5" }, "devDependencies": { @@ -6870,6 +6872,21 @@ "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", "license": "MIT" }, + "node_modules/tailwindcss-safe-area": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tailwindcss-safe-area/-/tailwindcss-safe-area-1.0.0.tgz", + "integrity": "sha512-cg4eFaTe4dFKZ4H6Vrobxqen6Jki/sSvssmHEYX5rFu1IojwGjTmab/eWzzN2gVrtMSIJoYSMS49p4TjBnWBeA==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "url": "https://github.com/sponsors/mvllow" + }, + "peerDependencies": { + "tailwindcss": "^4.0.0" + } + }, "node_modules/tapable": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", @@ -7195,6 +7212,18 @@ } } }, + "node_modules/use-debounce": { + "version": "10.0.5", + "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.5.tgz", + "integrity": "sha512-Q76E3lnIV+4YT9AHcrHEHYmAd9LKwUAbPXDm7FlqVGDHiSOhX3RDjT8dm0AxbJup6WgOb1YEcKyCr11kBJR5KQ==", + "license": "MIT", + "engines": { + "node": ">= 16.0.0" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/use-sidecar": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", diff --git a/package.json b/package.json index edc62f4..2df1ac3 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,8 @@ "react-hook-form": "^7.60.0", "sonner": "^2.0.6", "tailwind-merge": "^3.3.1", + "tailwindcss-safe-area": "^1.0.0", + "use-debounce": "^10.0.5", "zod": "^4.0.5" }, "devDependencies": { diff --git a/src/app/globals.css b/src/app/globals.css index 087ba6a..709e8a5 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,6 +1,6 @@ @import "tailwindcss"; @import "tw-animate-css"; - +@import "tailwindcss-safe-area"; @custom-variant dark (&:is(.dark *)); @theme inline { @@ -47,6 +47,7 @@ body { font-family: var(--font-geist), sans-serif; background-color: var(--background); } + :root { --radius: 0.625rem; --background: oklch(1 0 0); diff --git a/src/app/layout.tsx b/src/app/layout.tsx index d1b1f03..122224f 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,4 +1,4 @@ -import type { Metadata } from "next"; +import type { Metadata, Viewport } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import { ReactNode } from "react"; import { SidebarProvider } from "@/components/ui/sidebar"; @@ -24,6 +24,15 @@ export const metadata: Metadata = { description: "Desktop power right in your browser", }; +export const viewport: Viewport = { + width: 'device-width', + initialScale: 1, + viewportFit: 'cover', + themeColor: [ + { media: "(prefers-color-scheme: dark)", color: "#0a0a0a" }, + { media: "(prefers-color-scheme: light)", color: "#ffffff" } + ] +}; export default async function RootLayout({ children, @@ -35,7 +44,6 @@ export default async function RootLayout({ - diff --git a/src/app/page.tsx b/src/app/page.tsx index 851ba17..1bae159 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -5,7 +5,7 @@ import { useLiveQuery } from "dexie-react-hooks"; import { db } from "@/lib/db"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; -import { CopyIcon, EditIcon, EllipsisIcon, InfoIcon, ListCheckIcon, PencilIcon, PlusIcon, TrashIcon } from "lucide-react"; +import { CheckCheckIcon, CopyIcon, EditIcon, EllipsisIcon, InfoIcon, ListCheckIcon, PencilIcon, PlusIcon, TrashIcon } from "lucide-react"; import { Toggle } from "@/components/ui/toggle"; import Search from "@/components/search"; import { useIsMobile } from "@/hooks/use-mobile"; @@ -23,6 +23,7 @@ import { generateUUID } from "@/lib/uuid"; import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"; import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; +import { useDebounce } from "use-debounce"; const ProjectInfoFormSchema = z.object({ title: z.string().nonempty("Title cannot be empty"), @@ -118,6 +119,7 @@ const DeleteProjectDialog = ({ project }: { project: Project }) => { const ProjectDropdown = ({ project }: { project: Project }): ReactNode => { const [renameDialogOpen, setRenameDialogOpen] = useState(false); const [deleteAlertOpen, setDeleteAlertOpen] = useState(false); + const isMobile = useIsMobile(); const handleDuplicate = async () => { const newProject = { @@ -138,7 +140,7 @@ const ProjectDropdown = ({ project }: { project: Project }): ReactNode => { - +
{project.title} setRenameDialogOpen(true)}> @@ -221,10 +223,11 @@ const ProjectContainer = ({ export default function Home(): ReactNode { const isMobile = useIsMobile(); const [search, setSearch] = useState(''); + const [debouncedSearch] = useDebounce(search, 300); - const projects = useLiveQuery(() => { - return db.projects.filter((project) => project.title.includes(search)).toArray(); - }); + const projects = useLiveQuery(() => ( + db.projects.filter((project) => project.title.toLowerCase().includes(debouncedSearch.toLowerCase())).toArray() + ), [debouncedSearch]); const newProjectForm = useForm>({ resolver: zodResolver(ProjectInfoFormSchema), diff --git a/src/components/dashboard/Dashboard.tsx b/src/components/dashboard/Dashboard.tsx index 1ff7364..3fd74c2 100644 --- a/src/components/dashboard/Dashboard.tsx +++ b/src/components/dashboard/Dashboard.tsx @@ -33,7 +33,7 @@ const items: DashboardItem[] = [ export const Dashboard = (): ReactNode => { return ( - +

ClipFusion

@@ -84,7 +84,7 @@ export const Dashboard = (): ReactNode => { - + Links diff --git a/src/components/search/Search.tsx b/src/components/search/Search.tsx index 66384ac..1b0dae5 100644 --- a/src/components/search/Search.tsx +++ b/src/components/search/Search.tsx @@ -7,7 +7,7 @@ export const Search = (props: ComponentProps): ReactNode => ( diff --git a/tailwind.config.js b/tailwind.config.js index 69ee36f..ce3cc1e 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,5 +1,5 @@ module.exports = { plugins: [ - require("@tailwindcss/line-clamp"), + require("@tailwindcss/line-clamp") ] }; \ No newline at end of file