commit
ae541bf2f5
|
@ -1,21 +1,20 @@
|
|||
import { IconProp } from "@fortawesome/fontawesome-svg-core";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
type Props = {
|
||||
export default function dashboardItem({
|
||||
name,
|
||||
value,
|
||||
icon,
|
||||
}: {
|
||||
name: string;
|
||||
value: number;
|
||||
icon: IconProp;
|
||||
};
|
||||
|
||||
export default function dashboardItem({ name, value, icon }: Props) {
|
||||
icon: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex gap-4 items-end">
|
||||
<div className="p-4 bg-primary/20 rounded-xl select-none">
|
||||
<FontAwesomeIcon icon={icon} className="w-8 h-8 text-primary" />
|
||||
<div className="flex items-center">
|
||||
<div className="w-20 aspect-square flex justify-center items-center bg-primary/20 rounded-xl select-none">
|
||||
<i className={`${icon} text-primary text-4xl drop-shadow`}></i>
|
||||
</div>
|
||||
<div className="flex flex-col justify-center">
|
||||
<p className="text-neutral text-sm tracking-wider">{name}</p>
|
||||
<p className="font-thin text-6xl text-primary mt-2">{value}</p>
|
||||
<div className="ml-4 flex flex-col justify-center">
|
||||
<p className="text-neutral text-xs tracking-wider">{name}</p>
|
||||
<p className="font-thin text-6xl text-primary mt-0.5">{value}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { signOut } from "next-auth/react";
|
||||
import { faPlus, faBars, faCaretDown } from "@fortawesome/free-solid-svg-icons";
|
||||
import { useEffect, useState } from "react";
|
||||
import ClickAwayHandler from "@/components/ClickAwayHandler";
|
||||
import Sidebar from "@/components/Sidebar";
|
||||
|
@ -52,16 +50,16 @@ export default function Navbar() {
|
|||
const [uploadFileModal, setUploadFileModal] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="flex justify-between gap-2 items-center px-4 py-2 border-solid border-b-neutral-content border-b">
|
||||
<div className="flex justify-between gap-2 items-center pl-3 pr-4 py-2 border-solid border-b-neutral-content border-b">
|
||||
<div
|
||||
onClick={toggleSidebar}
|
||||
className="text-neutral btn btn-square btn-sm btn-ghost lg:hidden"
|
||||
>
|
||||
<FontAwesomeIcon icon={faBars} className="w-5 h-5" />
|
||||
<i className="bi-list text-xl"></i>
|
||||
</div>
|
||||
<SearchBar />
|
||||
<div className="flex items-center gap-2">
|
||||
<ToggleDarkMode className="sm:inline-grid hidden" />
|
||||
<ToggleDarkMode className="hidden sm:inline-grid" />
|
||||
|
||||
<div className="dropdown dropdown-end">
|
||||
<div className="tooltip tooltip-bottom" data-tip="Create New...">
|
||||
|
@ -70,11 +68,12 @@ export default function Navbar() {
|
|||
role="button"
|
||||
className="flex min-w-[3.4rem] items-center group btn btn-accent dark:border-violet-400 text-white btn-sm px-2"
|
||||
>
|
||||
<FontAwesomeIcon icon={faPlus} className="w-5 h-5" />
|
||||
<FontAwesomeIcon
|
||||
icon={faCaretDown}
|
||||
className="w-2 h-2 sm:w-3 sm:h-3"
|
||||
/>
|
||||
<span>
|
||||
<i className="bi-plus text-xl"></i>
|
||||
</span>
|
||||
<span>
|
||||
<i className="bi-caret-down-fill text-xs"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="dropdown-content z-[1] menu shadow bg-base-200 border border-neutral-content rounded-box w-40 mt-1">
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import React from "react";
|
||||
|
||||
export default function PageHeader({
|
||||
title,
|
||||
description,
|
||||
icon,
|
||||
}: {
|
||||
title: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<i
|
||||
className={`${icon} text-primary text-3xl sm:text-4xl drop-shadow`}
|
||||
></i>
|
||||
<div>
|
||||
<p className="text-3xl capitalize font-thin">{title}</p>
|
||||
<p>{description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faUser } from "@fortawesome/free-solid-svg-icons";
|
||||
import Image from "next/image";
|
||||
|
||||
type Props = {
|
||||
|
@ -39,10 +37,7 @@ export default function ProfilePhoto({
|
|||
{name ? (
|
||||
<span className="text-2xl capitalize">{name.slice(0, 1)}</span>
|
||||
) : (
|
||||
<FontAwesomeIcon
|
||||
icon={faUser}
|
||||
className="w-1/2 h-1/2 aspect-square"
|
||||
/>
|
||||
<i className="bi-person text-xl"></i>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { toast } from "react-hot-toast";
|
||||
|
@ -23,9 +21,9 @@ export default function SearchBar({ placeholder }: Props) {
|
|||
<div className="flex items-center relative group">
|
||||
<label
|
||||
htmlFor="search-box"
|
||||
className="inline-flex w-fit absolute left-1 pointer-events-none rounded-md p-1 text-primary"
|
||||
className="inline-flex items-center w-fit absolute left-1 pointer-events-none rounded-md p-1 text-primary"
|
||||
>
|
||||
<FontAwesomeIcon icon={faMagnifyingGlass} className="w-5 h-5" />
|
||||
<i className="bi-search"></i>
|
||||
</label>
|
||||
|
||||
<input
|
||||
|
@ -49,11 +47,11 @@ export default function SearchBar({ placeholder }: Props) {
|
|||
"/public/collections/" +
|
||||
router.query.id +
|
||||
"?q=" +
|
||||
encodeURIComponent(searchQuery || "")
|
||||
encodeURIComponent(searchQuery || ""),
|
||||
);
|
||||
} else {
|
||||
return router.push(
|
||||
"/search?q=" + encodeURIComponent(searchQuery)
|
||||
"/search?q=" + encodeURIComponent(searchQuery),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,4 @@
|
|||
import useCollectionStore from "@/store/collections";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faFolder,
|
||||
faHashtag,
|
||||
faChartSimple,
|
||||
faChevronDown,
|
||||
faLink,
|
||||
faGlobe,
|
||||
faThumbTack,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import useTagStore from "@/store/tags";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/router";
|
||||
|
@ -25,7 +15,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
() => {
|
||||
const storedValue = localStorage.getItem("collectionDisclosure");
|
||||
return storedValue ? storedValue === "true" : true;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const { collections } = useCollectionStore();
|
||||
|
@ -42,7 +32,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
useEffect(() => {
|
||||
localStorage.setItem(
|
||||
"collectionDisclosure",
|
||||
collectionDisclosure ? "true" : "false"
|
||||
collectionDisclosure ? "true" : "false",
|
||||
);
|
||||
}, [collectionDisclosure]);
|
||||
|
||||
|
@ -52,21 +42,19 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
|
||||
return (
|
||||
<div
|
||||
id="sidebar"
|
||||
className={`bg-base-200 h-full w-64 xl:w-80 overflow-y-auto border-solid border border-base-200 border-r-neutral-content px-2 z-20 ${
|
||||
className || ""
|
||||
}`}
|
||||
>
|
||||
<div className="flex flex-col gap-2 mt-2">
|
||||
<div className="flex flex-col gap-1 mt-2">
|
||||
<Link href={`/dashboard`}>
|
||||
<div
|
||||
className={`${
|
||||
active === `/dashboard` ? "bg-primary/20" : "hover:bg-neutral/20"
|
||||
} duration-100 py-5 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faChartSimple}
|
||||
className="w-7 h-7 drop-shadow text-primary"
|
||||
/>
|
||||
<i className="bi-house text-primary text-2xl drop-shadow"></i>
|
||||
<p className="truncate w-full">Dashboard</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
@ -77,10 +65,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
active === `/links` ? "bg-primary/20" : "hover:bg-neutral/20"
|
||||
} duration-100 py-5 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faLink}
|
||||
className="w-7 h-7 drop-shadow text-primary"
|
||||
/>
|
||||
<i className="bi-link-45deg text-primary text-2xl drop-shadow"></i>
|
||||
<p className="truncate w-full">All Links</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
@ -93,10 +78,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
: "hover:bg-neutral/20"
|
||||
} duration-100 py-5 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faFolder}
|
||||
className="w-7 h-7 drop-shadow text-primary"
|
||||
/>
|
||||
<i className="bi-folder2 text-primary text-2xl drop-shadow"></i>
|
||||
<p className="truncate w-full">All Collections</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
@ -109,10 +91,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
: "hover:bg-neutral/20"
|
||||
} duration-100 py-5 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faThumbTack}
|
||||
className="w-7 h-7 drop-shadow text-primary"
|
||||
/>
|
||||
<i className="bi-pin-angle text-primary text-2xl drop-shadow"></i>
|
||||
<p className="truncate w-full">Pinned Links</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
@ -123,16 +102,14 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
onClick={() => {
|
||||
setCollectionDisclosure(!collectionDisclosure);
|
||||
}}
|
||||
className="flex items-center justify-between text-sm w-full text-left mb-2 pl-2 font-bold text-neutral mt-5"
|
||||
className="flex items-center justify-between w-full text-left mb-2 pl-2 font-bold text-neutral mt-5"
|
||||
>
|
||||
<p>Collections</p>
|
||||
|
||||
<FontAwesomeIcon
|
||||
icon={faChevronDown}
|
||||
className={`w-3 h-3 ${
|
||||
<p className="text-sm ">Collections</p>
|
||||
<i
|
||||
className={`bi-chevron-down text-primary drop-shadow ${
|
||||
collectionDisclosure ? "rotate-reverse" : "rotate"
|
||||
}`}
|
||||
/>
|
||||
></i>
|
||||
</Disclosure.Button>
|
||||
<Transition
|
||||
enter="transition duration-100 ease-out"
|
||||
|
@ -156,19 +133,17 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
: "hover:bg-neutral/20"
|
||||
} duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faFolder}
|
||||
className="w-6 h-6 drop-shadow"
|
||||
<i
|
||||
className="bi-folder2 text-2xl drop-shadow"
|
||||
style={{ color: e.color }}
|
||||
/>
|
||||
></i>
|
||||
<p className="truncate w-full">{e.name}</p>
|
||||
|
||||
{e.isPublic ? (
|
||||
<FontAwesomeIcon
|
||||
icon={faGlobe}
|
||||
<i
|
||||
className="bi-globe-americas text-sm text-black/50 dark:text-white/50 drop-shadow"
|
||||
title="This collection is being shared publicly."
|
||||
className="w-4 h-4 drop-shadow text-neutral"
|
||||
/>
|
||||
></i>
|
||||
) : undefined}
|
||||
<div className="drop-shadow text-neutral text-xs">
|
||||
{e._count?.links}
|
||||
|
@ -194,13 +169,14 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
onClick={() => {
|
||||
setTagDisclosure(!tagDisclosure);
|
||||
}}
|
||||
className="flex items-center justify-between text-sm w-full text-left mb-2 pl-2 font-bold text-neutral mt-5"
|
||||
className="flex items-center justify-between w-full text-left mb-2 pl-2 font-bold text-neutral mt-5"
|
||||
>
|
||||
<p>Tags</p>
|
||||
<FontAwesomeIcon
|
||||
icon={faChevronDown}
|
||||
className={`w-3 h-3 ${tagDisclosure ? "rotate-reverse" : "rotate"}`}
|
||||
/>
|
||||
<p className="text-sm">Tags</p>
|
||||
<i
|
||||
className={`bi-chevron-down text-primary drop-shadow ${
|
||||
collectionDisclosure ? "rotate-reverse" : "rotate"
|
||||
}`}
|
||||
></i>
|
||||
</Disclosure.Button>
|
||||
<Transition
|
||||
enter="transition duration-100 ease-out"
|
||||
|
@ -224,11 +200,7 @@ export default function Sidebar({ className }: { className?: string }) {
|
|||
: "hover:bg-neutral/20"
|
||||
} duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8`}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faHashtag}
|
||||
className="w-4 h-4 text-primary mt-1"
|
||||
/>
|
||||
|
||||
<i className="bi-hash text-2xl text-primary drop-shadow"></i>
|
||||
<p className="truncate w-full pr-7">{e.name}</p>
|
||||
<div className="drop-shadow text-neutral text-xs">
|
||||
{e._count?.links}
|
||||
|
|
|
@ -11,11 +11,7 @@ export default function ToggleDarkMode({ className }: Props) {
|
|||
const [theme, setTheme] = useState(localStorage.getItem("theme"));
|
||||
|
||||
const handleToggle = (e: any) => {
|
||||
if (e.target.checked) {
|
||||
setTheme("dark");
|
||||
} else {
|
||||
setTheme("light");
|
||||
}
|
||||
setTheme(e.target.checked ? "dark" : "light");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -36,27 +32,8 @@ export default function ToggleDarkMode({ className }: Props) {
|
|||
className="theme-controller"
|
||||
checked={localStorage.getItem("theme") === "light" ? false : true}
|
||||
/>
|
||||
|
||||
{/* sun icon */}
|
||||
|
||||
<svg
|
||||
className="swap-on fill-current w-5 h-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8M8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0m0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13m8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5M3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8m10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0m-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707M4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z" />
|
||||
</svg>
|
||||
|
||||
{/* moon icon */}
|
||||
<svg
|
||||
className="swap-off fill-current w-5 h-5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278" />
|
||||
</svg>
|
||||
<i className="bi-sun text-xl swap-on"></i>
|
||||
<i className="bi-moon text-xl swap-off"></i>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
"@types/react-dom": "18.2.7",
|
||||
"axios": "^1.5.1",
|
||||
"bcrypt": "^5.1.0",
|
||||
"bootstrap-icons": "^1.11.2",
|
||||
"colorthief": "^2.4.0",
|
||||
"crypto-js": "^4.2.0",
|
||||
"csstype": "^3.1.2",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React from "react";
|
||||
import "@/styles/globals.css";
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||
import { SessionProvider } from "next-auth/react";
|
||||
import type { AppProps } from "next/app";
|
||||
import Head from "next/head";
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
import useCollectionStore from "@/store/collections";
|
||||
import {
|
||||
faEllipsis,
|
||||
faFolder,
|
||||
faPlus,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import CollectionCard from "@/components/CollectionCard";
|
||||
import { useState } from "react";
|
||||
import MainLayout from "@/layouts/MainLayout";
|
||||
|
@ -13,6 +7,7 @@ import SortDropdown from "@/components/SortDropdown";
|
|||
import { Sort } from "@/types/global";
|
||||
import useSort from "@/hooks/useSort";
|
||||
import NewCollectionModal from "@/components/ModalContent/NewCollectionModal";
|
||||
import PageHeader from "@/components/PageHeader";
|
||||
|
||||
export default function Collections() {
|
||||
const { collections } = useCollectionStore();
|
||||
|
@ -28,24 +23,14 @@ export default function Collections() {
|
|||
|
||||
return (
|
||||
<MainLayout>
|
||||
<div className="p-5">
|
||||
<div className="flex gap-3 justify-between mb-5">
|
||||
<div className="flex gap-3">
|
||||
<div className="flex items-center gap-3">
|
||||
<FontAwesomeIcon
|
||||
icon={faFolder}
|
||||
className="sm:w-10 sm:h-10 w-8 h-8 text-primary drop-shadow"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-3xl capitalize font-thin">
|
||||
Your Collections
|
||||
</p>
|
||||
|
||||
<p className="sm:text-sm text-xs">Collections you own</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-5 flex flex-col gap-5 w-full h-full">
|
||||
<PageHeader
|
||||
icon={"bi-folder2"}
|
||||
title={"Collections"}
|
||||
description={"Collections you own"}
|
||||
/>
|
||||
|
||||
<div className="flex gap-3 justify-end">
|
||||
<div className="relative mt-2">
|
||||
<SortDropdown sortBy={sortBy} setSort={setSortBy} />
|
||||
</div>
|
||||
|
@ -63,20 +48,15 @@ export default function Collections() {
|
|||
onClick={() => setNewCollectionModal(true)}
|
||||
>
|
||||
<p className="group-hover:opacity-0 duration-100">New Collection</p>
|
||||
<FontAwesomeIcon
|
||||
icon={faPlus}
|
||||
className="w-8 h-8 text-primary group-hover:w-12 group-hover:h-12 group-hover:-mt-10 duration-100"
|
||||
/>
|
||||
<i className="bi-plus text-5xl group-hover:text-7xl group-hover:-mt-6 text-primary drop-shadow duration-100"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{sortedCollections.filter((e) => e.ownerId !== data?.user.id)[0] ? (
|
||||
<>
|
||||
<div className="flex items-center gap-3 my-5">
|
||||
<FontAwesomeIcon
|
||||
icon={faFolder}
|
||||
className="sm:w-10 sm:h-10 w-8 h-8 text-primary drop-shadow"
|
||||
/>
|
||||
<i className="bi-folder2 text-3xl sm:text-2xl text-primary drop-shadow"></i>
|
||||
|
||||
<div>
|
||||
<p className="text-3xl capitalize font-thin">
|
||||
Other Collections
|
||||
|
|
|
@ -1,30 +1,20 @@
|
|||
import useCollectionStore from "@/store/collections";
|
||||
import {
|
||||
faChartSimple,
|
||||
faChevronRight,
|
||||
faClockRotateLeft,
|
||||
faFileImport,
|
||||
faFolder,
|
||||
faHashtag,
|
||||
faLink,
|
||||
faThumbTack,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import MainLayout from "@/layouts/MainLayout";
|
||||
import useLinkStore from "@/store/links";
|
||||
import useCollectionStore from "@/store/collections";
|
||||
import useTagStore from "@/store/tags";
|
||||
import MainLayout from "@/layouts/MainLayout";
|
||||
import LinkCard from "@/components/LinkCard";
|
||||
import LinkCard from "@/components/LinkViews/LinkComponents/LinkCard";
|
||||
import { useEffect, useState } from "react";
|
||||
import useLinks from "@/hooks/useLinks";
|
||||
import Link from "next/link";
|
||||
import useWindowDimensions from "@/hooks/useWindowDimensions";
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import React from "react";
|
||||
import useModalStore from "@/store/modals";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { MigrationFormat, MigrationRequest } from "@/types/global";
|
||||
import DashboardItem from "@/components/DashboardItem";
|
||||
import NewLinkModal from "@/components/ModalContent/NewLinkModal";
|
||||
import PageHeader from "@/components/PageHeader";
|
||||
|
||||
export default function Dashboard() {
|
||||
const { collections } = useCollectionStore();
|
||||
|
@ -44,8 +34,8 @@ export default function Dashboard() {
|
|||
collections.reduce(
|
||||
(accumulator, collection) =>
|
||||
accumulator + (collection._count as any).links,
|
||||
0
|
||||
)
|
||||
0,
|
||||
),
|
||||
);
|
||||
}, [collections]);
|
||||
|
||||
|
@ -105,24 +95,13 @@ export default function Dashboard() {
|
|||
return (
|
||||
<MainLayout>
|
||||
<div style={{ flex: "1 1 auto" }} className="p-5 flex flex-col gap-5">
|
||||
<div className="flex items-center gap-3">
|
||||
<FontAwesomeIcon
|
||||
icon={faChartSimple}
|
||||
className="sm:w-10 sm:h-10 w-8 h-8 text-primary drop-shadow"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-3xl capitalize font-thin">Dashboard</p>
|
||||
|
||||
<p className="sm:text-sm text-xs">A brief overview of your data</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PageHeader icon={'bi-house '} title={'Dashboard'} description={"A brief overview of your data"} />
|
||||
<div>
|
||||
<div className="flex justify-evenly flex-col md:flex-row md:items-center gap-2 md:w-full h-full rounded-2xl p-8 border border-neutral-content bg-base-200">
|
||||
<DashboardItem
|
||||
name={numberOfLinks === 1 ? "Link" : "Links"}
|
||||
value={numberOfLinks}
|
||||
icon={faLink}
|
||||
icon={"bi-link-45deg"}
|
||||
/>
|
||||
|
||||
<div className="divider md:divider-horizontal"></div>
|
||||
|
@ -130,7 +109,7 @@ export default function Dashboard() {
|
|||
<DashboardItem
|
||||
name={collections.length === 1 ? "Collection" : "Collections"}
|
||||
value={collections.length}
|
||||
icon={faFolder}
|
||||
icon={"bi-folder"}
|
||||
/>
|
||||
|
||||
<div className="divider md:divider-horizontal"></div>
|
||||
|
@ -138,25 +117,22 @@ export default function Dashboard() {
|
|||
<DashboardItem
|
||||
name={tags.length === 1 ? "Tag" : "Tags"}
|
||||
value={tags.length}
|
||||
icon={faHashtag}
|
||||
icon={"bi-hash"}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex gap-2 items-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faClockRotateLeft}
|
||||
className="w-5 h-5 text-primary drop-shadow"
|
||||
/>
|
||||
<p className="text-2xl">Recently Added Links</p>
|
||||
<i className="bi-clock-history text-primary text-2xl drop-shadow"></i>
|
||||
<p className="text-2xl">Recent</p>
|
||||
</div>
|
||||
<Link
|
||||
href="/links"
|
||||
className="flex items-center gap-2 cursor-pointer"
|
||||
className="flex items-center text-sm text-black/75 dark:text-white/75 gap-2 cursor-pointer"
|
||||
>
|
||||
View All
|
||||
<FontAwesomeIcon icon={faChevronRight} className={`w-4 h-4`} />
|
||||
<i className="bi-chevron-right text-sm "></i>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
|
@ -164,7 +140,7 @@ export default function Dashboard() {
|
|||
style={{ flex: "0 1 auto" }}
|
||||
className="flex flex-col 2xl:flex-row items-start 2xl:gap-2"
|
||||
>
|
||||
{links[0] ? (
|
||||
{false && links[0] ? (
|
||||
<div className="w-full">
|
||||
<div
|
||||
className={`grid 2xl:grid-cols-3 xl:grid-cols-2 grid-cols-1 gap-5 w-full`}
|
||||
|
@ -192,14 +168,11 @@ export default function Dashboard() {
|
|||
onClick={() => {
|
||||
setNewLinkModal(true);
|
||||
}}
|
||||
className="inline-flex gap-1 relative w-[11rem] items-center btn btn-accent dark:border-violet-400 text-white group"
|
||||
className="inline-flex items-center gap-2 text-sm btn btn-accent dark:border-accent text-white"
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faPlus}
|
||||
className="w-5 h-5 left-4 group-hover:ml-[4rem] absolute duration-100"
|
||||
/>
|
||||
<span className="group-hover:opacity-0 text-right w-full duration-100">
|
||||
Create New Link
|
||||
<i className="bi-plus text-xl duration-100"></i>
|
||||
<span className="group-hover:opacity-0 text-right duration-100">
|
||||
Add New Link
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
@ -207,13 +180,10 @@ export default function Dashboard() {
|
|||
<div
|
||||
tabIndex={0}
|
||||
role="button"
|
||||
className="flex gap-2 text-sm btn btn-outline btn-neutral group"
|
||||
className="inline-flex items-center gap-2 text-sm btn btn-outline btn-neutral"
|
||||
id="import-dropdown"
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={faFileImport}
|
||||
className="w-5 h-5 duration-100"
|
||||
/>
|
||||
<i className="bi-cloud-upload text-xl duration-100"></i>
|
||||
<p>Import From</p>
|
||||
</div>
|
||||
<ul className="shadow menu dropdown-content z-[1] bg-base-200 border border-neutral-content rounded-box mt-1 w-60">
|
||||
|
@ -266,18 +236,15 @@ export default function Dashboard() {
|
|||
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex gap-2 items-center">
|
||||
<FontAwesomeIcon
|
||||
icon={faThumbTack}
|
||||
className="w-5 h-5 text-primary drop-shadow"
|
||||
/>
|
||||
<p className="text-2xl">Pinned Links</p>
|
||||
<i className="bi-pin-angle text-primary text-2xl drop-shadow"></i>
|
||||
<p className="text-2xl">Pinned</p>
|
||||
</div>
|
||||
<Link
|
||||
href="/links/pinned"
|
||||
className="flex items-center gap-2 cursor-pointer"
|
||||
className="flex items-center text-sm text-black/75 dark:text-white/75 gap-2 cursor-pointer"
|
||||
>
|
||||
View All
|
||||
<FontAwesomeIcon icon={faChevronRight} className={`w-4 h-4`} />
|
||||
<i className="bi-chevron-right text-sm "></i>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ import SortDropdown from "@/components/SortDropdown";
|
|||
import useLinks from "@/hooks/useLinks";
|
||||
import MainLayout from "@/layouts/MainLayout";
|
||||
import useLinkStore from "@/store/links";
|
||||
import { Sort } from "@/types/global";
|
||||
import React, { useState } from "react";
|
||||
import PageHeader from "@/components/PageHeader";
|
||||
import { Sort, ViewMode } from "@/types/global";
|
||||
import { faLink } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
@ -13,6 +16,7 @@ import DefaultView from "@/components/LinkViews/DefaultView";
|
|||
import GridView from "@/components/LinkViews/GridView";
|
||||
import ListView from "@/components/LinkViews/ListView";
|
||||
|
||||
|
||||
export default function Links() {
|
||||
const { links } = useLinkStore();
|
||||
|
||||
|
@ -35,24 +39,18 @@ export default function Links() {
|
|||
return (
|
||||
<MainLayout>
|
||||
<div className="p-5 flex flex-col gap-5 w-full h-full">
|
||||
<div className="flex gap-3 justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<FontAwesomeIcon
|
||||
icon={faLink}
|
||||
className="sm:w-10 sm:h-10 w-8 h-8 text-primary drop-shadow"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-3xl capitalize font-thin">All Links</p>
|
||||
|
||||
<p className="sm:text-sm text-xs">Links from every Collections</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2 items-center mt-2">
|
||||
<PageHeader
|
||||
icon={"bi-link-45deg"}
|
||||
title={"All Links"}
|
||||
description={"Links from every Collections"}
|
||||
/>
|
||||
<div className="flex gap-3 justify-end">
|
||||
<div className="relative mt-2">
|
||||
<SortDropdown sortBy={sortBy} setSort={setSortBy} />
|
||||
<ViewDropdown viewMode={viewMode} setViewMode={setViewMode} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{links[0] ? (
|
||||
<LinkComponent links={links} />
|
||||
) : (
|
||||
|
|
|
@ -3,6 +3,9 @@ import SortDropdown from "@/components/SortDropdown";
|
|||
import useLinks from "@/hooks/useLinks";
|
||||
import MainLayout from "@/layouts/MainLayout";
|
||||
import useLinkStore from "@/store/links";
|
||||
import { Sort } from "@/types/global";
|
||||
import React, { useState } from "react";
|
||||
import PageHeader from "@/components/PageHeader";
|
||||
import { Sort, ViewMode } from "@/types/global";
|
||||
import { faThumbTack } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
@ -34,22 +37,13 @@ export default function PinnedLinks() {
|
|||
return (
|
||||
<MainLayout>
|
||||
<div className="p-5 flex flex-col gap-5 w-full h-full">
|
||||
<div className="flex gap-3 justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<FontAwesomeIcon
|
||||
icon={faThumbTack}
|
||||
className="sm:w-10 sm:h-10 w-8 h-8 text-primary drop-shadow"
|
||||
/>
|
||||
<div>
|
||||
<p className="text-3xl capitalize font-thin">Pinned Links</p>
|
||||
|
||||
<p className="sm:text-sm text-xs">
|
||||
Pinned Links from your Collections
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2 items-center mt-2">
|
||||
<PageHeader
|
||||
icon={"bi-pin-angle"}
|
||||
title={"Pinned Links"}
|
||||
description={"Pinned Links from your Collections"}
|
||||
/>
|
||||
<div className="flex gap-3 justify-end">
|
||||
<div className="relative mt-2">
|
||||
<SortDropdown sortBy={sortBy} setSort={setSortBy} />
|
||||
<ViewDropdown viewMode={viewMode} setViewMode={setViewMode} />
|
||||
</div>
|
||||
|
|
|
@ -1979,6 +1979,11 @@ bl@^4.0.3:
|
|||
inherits "^2.0.4"
|
||||
readable-stream "^3.4.0"
|
||||
|
||||
bootstrap-icons@^1.11.2:
|
||||
version "1.11.2"
|
||||
resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.11.2.tgz#e1c75daec154e25958db04c4eb3cbda6041e7118"
|
||||
integrity sha512-TgdiPv+IM9tgDb+dsxrnGIyocsk85d2M7T0qIgkvPedZeoZfyeG/j+yiAE4uHCEayKef2RP05ahQ0/e9Sv75Wg==
|
||||
|
||||
bowser@^2.11.0:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f"
|
||||
|
|
Ŝarĝante…
Reference in New Issue