much better coloring

This commit is contained in:
Daniel 2023-08-14 23:25:25 -04:00
parent 7da89a35e2
commit 1701ba07d4
44 changed files with 331 additions and 211 deletions

View File

@ -32,24 +32,24 @@ export default function CollectionCard({ collection, className }: Props) {
return ( return (
<div <div
className={`bg-gradient-to-tr from-sky-100 dark:from-sky-800 from-10% via-gray-100 via-20% to-white to-100% self-stretch min-h-[12rem] rounded-2xl shadow duration-100 hover:shadow-none group relative ${className}`} className={`bg-gradient-to-tr from-sky-100 dark:from-gray-800 from-10% via-gray-100 via-20% to-white dark:to-neutral-800 to-100% self-stretch min-h-[12rem] rounded-2xl shadow duration-100 hover:shadow-none group relative ${className}`}
> >
<div <div
onClick={() => setExpandDropdown(!expandDropdown)} onClick={() => setExpandDropdown(!expandDropdown)}
id={"expand-dropdown" + collection.id} id={"expand-dropdown" + collection.id}
className="inline-flex absolute top-5 right-5 rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-sky-800 duration-100 p-1" className="inline-flex absolute top-5 right-5 rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faEllipsis} icon={faEllipsis}
id={"expand-dropdown" + collection.id} id={"expand-dropdown" + collection.id}
className="w-5 h-5 text-gray-500 dark:text-white" className="w-5 h-5 text-gray-500 dark:text-gray-300"
/> />
</div> </div>
<Link <Link
href={`/collections/${collection.id}`} href={`/collections/${collection.id}`}
className="flex flex-col gap-2 justify-between min-h-[12rem] h-full select-none p-5" className="flex flex-col gap-2 justify-between min-h-[12rem] h-full select-none p-5"
> >
<p className="text-2xl font-bold capitalize text-black dark:text-white break-words line-clamp-3 w-4/5"> <p className="text-2xl capitalize text-black dark:text-white break-words line-clamp-3 w-4/5">
{collection.name} {collection.name}
</p> </p>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">

View File

@ -25,12 +25,12 @@ export default function Dropdown({ onClickOutside, className, items }: Props) {
return ( return (
<ClickAwayHandler <ClickAwayHandler
onClickOutside={onClickOutside} onClickOutside={onClickOutside}
className={`${className} py-1 shadow-md border border-sky-100 dark:border-sky-800 bg-gray-50 dark:bg-sky-900 rounded-md flex flex-col z-20`} className={`${className} py-1 shadow-md border border-sky-100 dark:border-neutral-700 bg-gray-50 dark:bg-neutral-800 rounded-md flex flex-col z-20`}
> >
{items.map((e, i) => { {items.map((e, i) => {
const inner = e && ( const inner = e && (
<div className="cursor-pointer rounded-md"> <div className="cursor-pointer rounded-md">
<div className="flex items-center gap-2 py-1 px-2 hover:bg-slate-200 duration-100"> <div className="flex items-center gap-2 py-1 px-2 hover:bg-slate-200 dark:hover:bg-neutral-700 duration-100">
<p className="text-black dark:text-white select-none">{e.name}</p> <p className="text-black dark:text-white select-none">{e.name}</p>
</div> </div>
</div> </div>

View File

@ -20,7 +20,7 @@ export default function FilterSearchDropdown({
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
if (target.id !== "filter-dropdown") setFilterDropdown(false); if (target.id !== "filter-dropdown") setFilterDropdown(false);
}} }}
className="absolute top-8 right-0 border border-sky-100 dark:border-sky-800 shadow-md bg-gray-50 dark:bg-sky-900 rounded-md p-2 z-20 w-40" className="absolute top-8 right-0 border border-sky-100 dark:border-neutral-700 shadow-md bg-gray-50 dark:bg-neutral-800 rounded-md p-2 z-20 w-40"
> >
<p className="mb-2 text-black dark:text-white text-center font-semibold"> <p className="mb-2 text-black dark:text-white text-center font-semibold">
Filter by Filter by

View File

@ -45,6 +45,8 @@ export default function CollectionSelection({ onChange, defaultValue }: Props) {
return ( return (
<Select <Select
isClearable isClearable
className="react-select-container"
classNamePrefix="react-select"
placeholder="Default: Unnamed Collection" placeholder="Default: Unnamed Collection"
onChange={onChange} onChange={onChange}
options={options} options={options}

View File

@ -28,6 +28,8 @@ export default function TagSelection({ onChange, defaultValue }: Props) {
return ( return (
<CreatableSelect <CreatableSelect
isClearable isClearable
className="react-select-container"
classNamePrefix="react-select"
onChange={onChange} onChange={onChange}
options={options} options={options}
styles={styles} styles={styles}

View File

@ -106,7 +106,7 @@ export default function LinkCard({ link, count, className }: Props) {
return ( return (
<div <div
className={`bg-gradient-to-tr from-slate-200 dark:from-sky-800 from-10% to-gray-50 via-20% shadow hover:shadow-none cursor-pointer duration-100 rounded-2xl relative group ${className}`} className={`bg-gradient-to-tr from-slate-200 dark:from-neutral-800 from-10% to-gray-50 dark:to-[#303030] via-20% shadow hover:shadow-none cursor-pointer duration-100 rounded-2xl relative group ${className}`}
> >
{(permissions === true || {(permissions === true ||
permissions?.canUpdate || permissions?.canUpdate ||
@ -114,7 +114,7 @@ export default function LinkCard({ link, count, className }: Props) {
<div <div
onClick={() => setExpandDropdown(!expandDropdown)} onClick={() => setExpandDropdown(!expandDropdown)}
id={"expand-dropdown" + link.id} id={"expand-dropdown" + link.id}
className="text-gray-500 dark:text-white inline-flex rounded-md cursor-pointer hover:bg-slate-200 absolute right-5 top-5 z-10 duration-100 p-1" className="text-gray-500 dark:text-gray-300 inline-flex rounded-md cursor-pointer hover:bg-slate-200 dark:hover:bg-neutral-700 absolute right-5 top-5 z-10 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faEllipsis} icon={faEllipsis}
@ -156,10 +156,10 @@ export default function LinkCard({ link, count, className }: Props) {
<div className="flex justify-between gap-5 w-full h-full z-0"> <div className="flex justify-between gap-5 w-full h-full z-0">
<div className="flex flex-col justify-between w-full"> <div className="flex flex-col justify-between w-full">
<div className="flex items-baseline gap-1"> <div className="flex items-baseline gap-1">
<p className="text-sm text-black dark:text-white font-bold"> <p className="text-sm text-gray-500 dark:text-gray-300">
{count + 1}. {count + 1}
</p> </p>
<p className="text-lg text-black dark:text-white font-bold truncate capitalize w-full pr-8"> <p className="text-lg text-black dark:text-white truncate capitalize w-full pr-8">
{link.name || link.description} {link.name || link.description}
</p> </p>
</div> </div>
@ -175,11 +175,11 @@ export default function LinkCard({ link, count, className }: Props) {
</p> </p>
</div> </div>
</div> </div>
<div className="flex items-center gap-1 w-full pr-20 text-gray-500 dark:text-white"> <div className="flex items-center gap-1 w-full pr-20 text-gray-500 dark:text-gray-300">
<FontAwesomeIcon icon={faLink} className="mt-1 w-4 h-4" /> <FontAwesomeIcon icon={faLink} className="mt-1 w-4 h-4" />
<p className="truncate w-full">{shortendURL}</p> <p className="truncate w-full">{shortendURL}</p>
</div> </div>
<div className="flex items-center gap-1 text-gray-500 dark:text-white"> <div className="flex items-center gap-1 text-gray-500 dark:text-gray-300">
<FontAwesomeIcon icon={faCalendarDays} className="w-4 h-4" /> <FontAwesomeIcon icon={faCalendarDays} className="w-4 h-4" />
<p>{formattedDate}</p> <p>{formattedDate}</p>
</div> </div>

View File

@ -72,7 +72,7 @@ export default function CollectionInfo({
} }
type="text" type="text"
placeholder="e.g. Example Collection" placeholder="e.g. Example Collection"
className="w-full rounded-md p-3 border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-3 dark:bg-neutral-900 border-solid border outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
<div className="color-picker flex justify-between"> <div className="color-picker flex justify-between">
<div className="flex flex-col justify-between items-center w-32"> <div className="flex flex-col justify-between items-center w-32">
@ -86,7 +86,7 @@ export default function CollectionInfo({
/> />
</div> </div>
<div <div
className="py-1 px-2 rounded-md text-xs font-semibold cursor-pointer text-black dark:text-white hover:bg-slate-200 duration-100" className="py-1 px-2 rounded-md text-xs font-semibold cursor-pointer text-black dark:text-white hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100"
onClick={() => onClick={() =>
setCollection({ ...collection, color: "#0ea5e9" }) setCollection({ ...collection, color: "#0ea5e9" })
} }
@ -105,7 +105,7 @@ export default function CollectionInfo({
<div className="w-full"> <div className="w-full">
<p className="text-sm text-black dark:text-white mb-2">Description</p> <p className="text-sm text-black dark:text-white mb-2">Description</p>
<textarea <textarea
className="w-full h-[11.4rem] resize-none border rounded-md duration-100 bg-white dark:bg-sky-950 p-3 outline-none border-sky-100 dark:border-sky-800 focus:border-sky-700" className="w-full h-[11.4rem] resize-none border rounded-md duration-100 bg-white dark:bg-neutral-900 p-3 outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600"
placeholder="The purpose of this Collection..." placeholder="The purpose of this Collection..."
value={collection.description} value={collection.description}
onChange={(e) => onChange={(e) =>

View File

@ -83,7 +83,7 @@ export default function DeleteCollection({
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<p className="text-black dark:text-white select-none text-center"> <p className="text-black dark:text-white select-none text-center">
To confirm, type &quot; To confirm, type &quot;
<span className="font-bold text-black">{collection.name}</span> <span className="font-bold">{collection.name}</span>
&quot; in the box below: &quot; in the box below:
</p> </p>
@ -93,7 +93,7 @@ export default function DeleteCollection({
onChange={(e) => setInputField(e.target.value)} onChange={(e) => setInputField(e.target.value)}
type="text" type="text"
placeholder={`Type "${collection.name}" Here.`} placeholder={`Type "${collection.name}" Here.`}
className="w-72 sm:w-96 rounded-md p-3 mx-auto border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-72 sm:w-96 rounded-md p-3 mx-auto border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 dark:bg-neutral-900 border-solid border outline-none duration-100"
/> />
</div> </div>
</> </>
@ -107,9 +107,9 @@ export default function DeleteCollection({
className={`mx-auto mt-2 text-white flex items-center gap-2 py-2 px-5 rounded-md select-none font-bold duration-100 ${ className={`mx-auto mt-2 text-white flex items-center gap-2 py-2 px-5 rounded-md select-none font-bold duration-100 ${
permissions === true permissions === true
? inputField === collection.name ? inputField === collection.name
? "bg-red-500 hover:bg-red-400 cursor-pointer" ? "bg-red-500 hover:bg-red-400 hover:dark:bg-red-600 cursor-pointer"
: "cursor-not-allowed bg-red-300" : "cursor-not-allowed bg-red-300 dark:bg-red-900"
: "bg-red-500 hover:bg-red-400 cursor-pointer" : "bg-red-500 hover:bg-red-400 hover:dark:bg-red-600 cursor-pointer"
}`} }`}
onClick={submit} onClick={submit}
> >

View File

@ -148,7 +148,7 @@ export default function TeamManagement({
console.log(err); console.log(err);
} }
}} }}
className="w-full hide-scrollbar overflow-x-auto whitespace-nowrap rounded-md p-3 border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none hover:border-sky-700 duration-100 cursor-text" className="w-full hide-scrollbar overflow-x-auto whitespace-nowrap rounded-md p-3 border-sky-100 dark:border-neutral-700 border-solid border outline-none hover:border-sky-300 dark:hover:border-sky-600 duration-100 cursor-text"
> >
{publicCollectionURL} {publicCollectionURL}
</div> </div>
@ -183,7 +183,7 @@ export default function TeamManagement({
} }
type="text" type="text"
placeholder="Username (without the '@')" placeholder="Username (without the '@')"
className="w-full rounded-md p-3 border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-3 dark:bg-neutral-900 border-solid border outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
<div <div
@ -215,7 +215,7 @@ export default function TeamManagement({
return ( return (
<div <div
key={i} key={i}
className="relative border p-2 rounded-md border-sky-100 flex flex-col sm:flex-row sm:items-center gap-2 justify-between" className="relative border p-2 rounded-md border-sky-100 dark:border-neutral-700 flex flex-col sm:flex-row sm:items-center gap-2 justify-between"
> >
{permissions === true && ( {permissions === true && (
<FontAwesomeIcon <FontAwesomeIcon
@ -244,7 +244,9 @@ export default function TeamManagement({
<p className="text-sm font-bold text-black dark:text-white"> <p className="text-sm font-bold text-black dark:text-white">
{e.user.name} {e.user.name}
</p> </p>
<p className="text-black">@{e.user.username}</p> <p className="text-gray-500 dark:text-gray-300">
@{e.user.username}
</p>
</div> </div>
</div> </div>
<div className="flex sm:block items-center gap-5 min-w-[10rem]"> <div className="flex sm:block items-center gap-5 min-w-[10rem]">
@ -307,11 +309,11 @@ export default function TeamManagement({
}} }}
/> />
<span <span
className={`text-black dark:text-white peer-checked:bg-sky-700 text-sm ${ className={`text-black dark:text-white peer-checked:bg-sky-200 dark:peer-checked:bg-sky-600 text-sm ${
permissions === true permissions === true
? "hover:bg-slate-200 duration-75" ? "hover:bg-slate-200 hover:dark:bg-neutral-700 duration-75"
: "" : ""
} peer-checked:text-white rounded p-1 select-none`} } rounded p-1 select-none`}
> >
Create Create
</span> </span>
@ -352,11 +354,11 @@ export default function TeamManagement({
}} }}
/> />
<span <span
className={`text-black dark:text-white peer-checked:bg-sky-700 text-sm ${ className={`text-black dark:text-white peer-checked:bg-sky-200 dark:peer-checked:bg-sky-600 text-sm ${
permissions === true permissions === true
? "hover:bg-slate-200 duration-75" ? "hover:bg-slate-200 hover:dark:bg-neutral-700 duration-75"
: "" : ""
} peer-checked:text-white rounded p-1 select-none`} } rounded p-1 select-none`}
> >
Update Update
</span> </span>
@ -397,11 +399,11 @@ export default function TeamManagement({
}} }}
/> />
<span <span
className={`text-black dark:text-white peer-checked:bg-sky-700 text-sm ${ className={`text-black dark:text-white peer-checked:bg-sky-200 dark:peer-checked:bg-sky-600 text-sm ${
permissions === true permissions === true
? "hover:bg-slate-200 duration-75" ? "hover:bg-slate-200 hover:dark:bg-neutral-700 duration-75"
: "" : ""
} peer-checked:text-white rounded p-1 select-none`} } rounded p-1 select-none`}
> >
Delete Delete
</span> </span>
@ -417,13 +419,13 @@ export default function TeamManagement({
)} )}
<div <div
className="relative border px-2 rounded-md border-sky-100 dark:border-sky-800 flex min-h-[7rem] sm:min-h-[5rem] gap-2 justify-between" className="relative border px-2 rounded-md border-sky-100 dark:border-neutral-700 flex min-h-[7rem] sm:min-h-[5rem] gap-2 justify-between"
title={`'@${collectionOwner.username}' is the owner of this collection.`} title={`'@${collectionOwner.username}' is the owner of this collection.`}
> >
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ProfilePhoto <ProfilePhoto
src={`/api/avatar/${collection.ownerId}?${Date.now()}`} src={`/api/avatar/${collection.ownerId}?${Date.now()}`}
className="border-[3px] dark:border-sky-800" className="border-[3px]"
/> />
<div> <div>
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
@ -435,7 +437,7 @@ export default function TeamManagement({
className="w-3 h-3 text-yellow-500" className="w-3 h-3 text-yellow-500"
/> />
</div> </div>
<p className="text-black dark:text-white"> <p className="text-gray-500 dark:text-gray-300">
@{collectionOwner.username} @{collectionOwner.username}
</p> </p>
</div> </div>

View File

@ -58,7 +58,7 @@ export default function CollectionModal({
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 hover:dark:bg-sky-300 hover:dark:text-white rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none"
} }
> >
Collection Info Collection Info
@ -68,7 +68,7 @@ export default function CollectionModal({
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 hover:dark:bg-sky-300 hover:dark:text-white rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none"
} }
> >
{isOwner ? "Share & Collaborate" : "View Team"} {isOwner ? "Share & Collaborate" : "View Team"}
@ -77,7 +77,7 @@ export default function CollectionModal({
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 hover:dark:bg-sky-300 hover:dark:text-white rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none"
} }
> >
{isOwner ? "Delete Collection" : "Leave Collection"} {isOwner ? "Delete Collection" : "Leave Collection"}

View File

@ -115,10 +115,10 @@ export default function AddOrEditLink({
<div className="flex flex-col gap-3 sm:w-[35rem] w-80"> <div className="flex flex-col gap-3 sm:w-[35rem] w-80">
{method === "UPDATE" ? ( {method === "UPDATE" ? (
<p <p
className="text-gray-500 my-2 text-center truncate w-full" className="text-gray-500 dark:text-gray-300 my-2 text-center truncate w-full"
title={link.url} title={link.url}
> >
<Link href={link.url} target="_blank" className=" font-bold"> <Link href={link.url} target="_blank" className="font-bold">
{link.url} {link.url}
</Link> </Link>
</p> </p>
@ -135,11 +135,11 @@ export default function AddOrEditLink({
onChange={(e) => setLink({ ...link, url: e.target.value })} onChange={(e) => setLink({ ...link, url: e.target.value })}
type="text" type="text"
placeholder="e.g. http://example.com/" placeholder="e.g. http://example.com/"
className="w-full rounded-md p-2 border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 dark:bg-neutral-900 border-solid border outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
) : null} ) : null}
<hr className="dark:border-sky-800" /> <hr className="dark:border-neutral-700" />
<div className="grid sm:grid-cols-2 gap-3"> <div className="grid sm:grid-cols-2 gap-3">
<div> <div>
<p className="text-sm text-black dark:text-white mb-2">Collection</p> <p className="text-sm text-black dark:text-white mb-2">Collection</p>
@ -177,7 +177,7 @@ export default function AddOrEditLink({
onChange={(e) => setLink({ ...link, name: e.target.value })} onChange={(e) => setLink({ ...link, name: e.target.value })}
type="text" type="text"
placeholder="e.g. Example Link" placeholder="e.g. Example Link"
className="w-full rounded-md p-2 border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 dark:bg-neutral-900 border-solid border outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
@ -191,7 +191,7 @@ export default function AddOrEditLink({
? "Will be auto generated if nothing is provided." ? "Will be auto generated if nothing is provided."
: "" : ""
} }
className="resize-none w-full rounded-md p-2 border-sky-100 dark:border-sky-800 border-solid border outline-none focus:border-sky-700 duration-100 dark:bg-sky-950" className="resize-none w-full rounded-md p-2 border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 border-solid border outline-none duration-100 dark:bg-neutral-900"
/> />
</div> </div>
</div> </div>

View File

@ -20,12 +20,15 @@ import {
faFilePdf, faFilePdf,
} from "@fortawesome/free-regular-svg-icons"; } from "@fortawesome/free-regular-svg-icons";
import isValidUrl from "@/lib/client/isValidUrl"; import isValidUrl from "@/lib/client/isValidUrl";
import { useTheme } from "next-themes";
type Props = { type Props = {
link: LinkIncludingShortenedCollectionAndTags; link: LinkIncludingShortenedCollectionAndTags;
}; };
export default function LinkDetails({ link }: Props) { export default function LinkDetails({ link }: Props) {
const { theme, setTheme } = useTheme();
const [imageError, setImageError] = useState<boolean>(false); const [imageError, setImageError] = useState<boolean>(false);
const formattedDate = new Date(link.createdAt as string).toLocaleString( const formattedDate = new Date(link.createdAt as string).toLocaleString(
"en-US", "en-US",
@ -71,6 +74,9 @@ export default function LinkDetails({ link }: Props) {
useEffect(() => { useEffect(() => {
const banner = document.getElementById("link-banner"); const banner = document.getElementById("link-banner");
const bannerInner = document.getElementById("link-banner-inner"); const bannerInner = document.getElementById("link-banner-inner");
const bannerOut = document.getElementById("link-banner-outside");
if (theme === "dark") bannerOut?.classList.toggle("banner-dark-mode");
if (colorPalette && banner && bannerInner) { if (colorPalette && banner && bannerInner) {
banner.style.background = `linear-gradient(to right, ${rgbToHex( banner.style.background = `linear-gradient(to right, ${rgbToHex(
@ -93,7 +99,7 @@ export default function LinkDetails({ link }: Props) {
colorPalette[3][2] colorPalette[3][2]
)})`; )})`;
} }
}, [colorPalette]); }, [colorPalette, theme]);
const handleDownload = (format: "png" | "pdf") => { const handleDownload = (format: "png" | "pdf") => {
const path = `/api/archives/${link.collection.id}/${link.id}.${format}`; const path = `/api/archives/${link.collection.id}/${link.id}.${format}`;
@ -115,7 +121,10 @@ export default function LinkDetails({ link }: Props) {
}; };
return ( return (
<div className="flex flex-col gap-3 sm:w-[35rem] w-80"> <div
id="link-banner-outside"
className="flex flex-col gap-3 sm:w-[35rem] w-80"
>
{!imageError && ( {!imageError && (
<div id="link-banner" className="link-banner h-32 -mx-5 -mt-5 relative"> <div id="link-banner" className="link-banner h-32 -mx-5 -mt-5 relative">
<div id="link-banner-inner" className="link-banner-inner"></div> <div id="link-banner-inner" className="link-banner-inner"></div>
@ -131,7 +140,7 @@ export default function LinkDetails({ link }: Props) {
height={42} height={42}
alt="" alt=""
id={"favicon-" + link.id} id={"favicon-" + link.id}
className="select-none mt-2 rounded-md shadow border-[3px] border-white dark:border-sky-800 bg-white dark:bg-sky-950 aspect-square" className="select-none mt-2 rounded-md shadow border-[3px] border-white dark:border-neutral-900 bg-white dark:bg-neutral-900 aspect-square"
draggable="false" draggable="false"
onLoad={(e) => { onLoad={(e) => {
try { try {
@ -158,7 +167,7 @@ export default function LinkDetails({ link }: Props) {
href={link.url} href={link.url}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="text-sm text-gray-500 dark:text-white break-all hover:underline cursor-pointer w-fit" className="text-sm text-gray-500 dark:text-gray-300 break-all hover:underline cursor-pointer w-fit"
> >
{url ? url.host : link.url} {url ? url.host : link.url}
</Link> </Link>
@ -185,7 +194,7 @@ export default function LinkDetails({ link }: Props) {
<Link key={i} href={`/tags/${e.id}`} className="z-10"> <Link key={i} href={`/tags/${e.id}`} className="z-10">
<p <p
title={e.name} title={e.name}
className="px-2 py-1 bg-sky-200 text-black text-xs rounded-3xl cursor-pointer hover:opacity-60 duration-100 truncate max-w-[19rem]" className="px-2 py-1 bg-sky-200 text-black dark:text-white dark:bg-sky-900 text-xs rounded-3xl cursor-pointer hover:opacity-60 duration-100 truncate max-w-[19rem]"
> >
{e.name} {e.name}
</p> </p>
@ -194,19 +203,19 @@ export default function LinkDetails({ link }: Props) {
</div> </div>
{link.description && ( {link.description && (
<> <>
<div className="text-gray-500 dark:text-white max-h-[20rem] my-3 rounded-md overflow-y-auto hyphens-auto"> <div className="text-black dark:text-white max-h-[20rem] my-3 rounded-md overflow-y-auto hyphens-auto">
{link.description} {link.description}
</div> </div>
</> </>
)} )}
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<div className="flex items-center gap-1 text-gray-500 dark:text-white"> <div className="flex items-center gap-1 text-gray-500 dark:text-gray-300">
<FontAwesomeIcon icon={faBoxArchive} className="w-4 h-4" /> <FontAwesomeIcon icon={faBoxArchive} className="w-4 h-4" />
<p>Archived Formats:</p> <p>Archived Formats:</p>
</div> </div>
<div <div
className="flex items-center gap-1 text-gray-500 dark:text-white" className="flex items-center gap-1 text-gray-500 dark:text-gray-300"
title={"Created at: " + formattedDate} title={"Created at: " + formattedDate}
> >
<FontAwesomeIcon icon={faCalendarDays} className="w-4 h-4" /> <FontAwesomeIcon icon={faCalendarDays} className="w-4 h-4" />
@ -214,7 +223,7 @@ export default function LinkDetails({ link }: Props) {
</div> </div>
</div> </div>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
<div className="flex justify-between items-center p-2 border border-sky-100 dark:border-sky-800 rounded-md"> <div className="flex justify-between items-center p-2 border border-sky-100 dark:border-neutral-700 rounded-md">
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<div className="text-white bg-sky-300 dark:bg-sky-600 p-2 rounded-md"> <div className="text-white bg-sky-300 dark:bg-sky-600 p-2 rounded-md">
<FontAwesomeIcon icon={faFileImage} className="w-6 h-6" /> <FontAwesomeIcon icon={faFileImage} className="w-6 h-6" />
@ -223,32 +232,32 @@ export default function LinkDetails({ link }: Props) {
<p className="text-gray-500 dark:text-white">Screenshot</p> <p className="text-gray-500 dark:text-white">Screenshot</p>
</div> </div>
<div className="flex text-black gap-1"> <div className="flex text-black dark:text-white gap-1">
<Link <Link
href={`/api/archives/${link.collectionId}/${link.id}.png`} href={`/api/archives/${link.collectionId}/${link.id}.png`}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="cursor-pointer hover:bg-slate-200 duration-100 p-2 rounded-md" className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faArrowUpRightFromSquare} icon={faArrowUpRightFromSquare}
className="w-5 h-5" className="w-5 h-5 text-sky-500 dark:text-sky-300"
/> />
</Link> </Link>
<div <div
onClick={() => handleDownload("png")} onClick={() => handleDownload("png")}
className="cursor-pointer hover:bg-slate-200 duration-100 p-2 rounded-md" className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faCloudArrowDown} icon={faCloudArrowDown}
className="w-5 h-5 cursor-pointer" className="w-5 h-5 cursor-pointer text-sky-500 dark:text-sky-300"
/> />
</div> </div>
</div> </div>
</div> </div>
<div className="flex justify-between items-center p-2 border border-sky-100 dark:border-sky-800 rounded-md"> <div className="flex justify-between items-center p-2 border border-sky-100 dark:border-neutral-700 rounded-md">
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
<div className="text-white bg-sky-300 dark:bg-sky-600 p-2 rounded-md"> <div className="text-white bg-sky-300 dark:bg-sky-600 p-2 rounded-md">
<FontAwesomeIcon icon={faFilePdf} className="w-6 h-6" /> <FontAwesomeIcon icon={faFilePdf} className="w-6 h-6" />
@ -257,26 +266,26 @@ export default function LinkDetails({ link }: Props) {
<p className="text-gray-500 dark:text-white">PDF</p> <p className="text-gray-500 dark:text-white">PDF</p>
</div> </div>
<div className="flex text-black gap-1"> <div className="flex text-black dark:text-white gap-1">
<Link <Link
href={`/api/archives/${link.collectionId}/${link.id}.pdf`} href={`/api/archives/${link.collectionId}/${link.id}.pdf`}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
className="cursor-pointer hover:bg-slate-200 duration-100 p-2 rounded-md" className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faArrowUpRightFromSquare} icon={faArrowUpRightFromSquare}
className="w-5 h-5" className="w-5 h-5 text-sky-500 dark:text-sky-300"
/> />
</Link> </Link>
<div <div
onClick={() => handleDownload("pdf")} onClick={() => handleDownload("pdf")}
className="cursor-pointer hover:bg-slate-200 duration-100 p-2 rounded-md" className="cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-2 rounded-md"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faCloudArrowDown} icon={faCloudArrowDown}
className="w-5 h-5 cursor-pointer" className="w-5 h-5 cursor-pointer text-sky-500 dark:text-sky-300"
/> />
</div> </div>
</div> </div>

View File

@ -47,8 +47,8 @@ export default function LinkModal({
<Tab <Tab
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-600 duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
} }
> >
Link Details Link Details
@ -56,8 +56,8 @@ export default function LinkModal({
<Tab <Tab
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-600 duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
} }
> >
Edit Link Edit Link

View File

@ -18,7 +18,7 @@ export default function PaymentPortal() {
return ( return (
<div className="mx-auto sm:w-[35rem] w-80"> <div className="mx-auto sm:w-[35rem] w-80">
<div className="max-w-[25rem] w-full mx-auto flex flex-col gap-3 justify-between"> <div className="max-w-[25rem] w-full mx-auto flex flex-col gap-3 justify-between">
<p className="text-md text-gray-500"> <p className="text-md text-gray-500 dark:text-gray-400">
To manage/cancel your subsciption, visit the billing portal. To manage/cancel your subsciption, visit the billing portal.
</p> </p>
@ -30,10 +30,13 @@ export default function PaymentPortal() {
className="mx-auto mt-2" className="mx-auto mt-2"
/> />
<p className="text-md text-gray-500"> <p className="text-md text-gray-500 dark:text-gray-400">
If you still need help or encountered any issues, feel free to reach If you still need help or encountered any issues, feel free to reach
out to us at:{" "} out to us at:{" "}
<a className="font-semibold" href="mailto:support@linkwarden.app"> <a
className="font-semibold underline"
href="mailto:support@linkwarden.app"
>
support@linkwarden.app support@linkwarden.app
</a> </a>
</p> </p>

View File

@ -88,7 +88,7 @@ export default function ChangePassword({
onChange={(e) => setNewPassword1(e.target.value)} onChange={(e) => setNewPassword1(e.target.value)}
type="password" type="password"
placeholder="••••••••••••••" placeholder="••••••••••••••"
className="w-full rounded-md p-3 mx-auto border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-3 mx-auto dark:bg-neutral-900 border-solid border outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
<p className="text-sm text-black dark:text-white"> <p className="text-sm text-black dark:text-white">
Confirm New Password Confirm New Password
@ -99,7 +99,7 @@ export default function ChangePassword({
onChange={(e) => setNewPassword2(e.target.value)} onChange={(e) => setNewPassword2(e.target.value)}
type="password" type="password"
placeholder="••••••••••••••" placeholder="••••••••••••••"
className="w-full rounded-md p-3 mx-auto border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-3 mx-auto dark:bg-neutral-900 border-solid border outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
<SubmitButton <SubmitButton

View File

@ -119,7 +119,9 @@ export default function PrivacySettings({
return ( return (
<div className="flex flex-col gap-3 justify-between sm:w-[35rem] w-80"> <div className="flex flex-col gap-3 justify-between sm:w-[35rem] w-80">
<div> <div>
<p className="text-sm text-black mb-2">Profile Visibility</p> <p className="text-sm text-black dark:text-white mb-2">
Profile Visibility
</p>
<Checkbox <Checkbox
label="Make profile private" label="Make profile private"
@ -128,19 +130,21 @@ export default function PrivacySettings({
onClick={() => setUser({ ...user, isPrivate: !user.isPrivate })} onClick={() => setUser({ ...user, isPrivate: !user.isPrivate })}
/> />
<p className="text-gray-500 text-sm"> <p className="text-gray-500 dark:text-gray-300 text-sm">
This will limit who can find and add you to other Collections. This will limit who can find and add you to other Collections.
</p> </p>
{user.isPrivate && ( {user.isPrivate && (
<div> <div>
<p className="text-sm text-black my-2">Whitelisted Users</p> <p className="text-sm text-black dark:text-white mt-2">
<p className="text-gray-500 text-sm mb-3"> Whitelisted Users
</p>
<p className="text-gray-500 dark:text-gray-300 text-sm mb-3">
Please provide the Username of the users you wish to grant Please provide the Username of the users you wish to grant
visibility to your profile. Separated by comma. visibility to your profile. Separated by comma.
</p> </p>
<textarea <textarea
className="w-full resize-none border rounded-md duration-100 bg-white p-2 outline-none border-sky-100 focus:border-sky-700" className="w-full resize-none border rounded-md duration-100 bg-white dark:bg-neutral-900 p-2 outline-none border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600"
placeholder="Your profile is hidden from everyone right now..." placeholder="Your profile is hidden from everyone right now..."
value={whitelistedUsersTextbox} value={whitelistedUsersTextbox}
onChange={(e) => { onChange={(e) => {
@ -152,7 +156,9 @@ export default function PrivacySettings({
</div> </div>
<div className="mt-5"> <div className="mt-5">
<p className="text-sm text-black mb-2">Import/Export Data</p> <p className="text-sm text-black dark:text-white mb-2">
Import/Export Data
</p>
<div className="flex gap-2"> <div className="flex gap-2">
<div <div
@ -162,7 +168,7 @@ export default function PrivacySettings({
> >
<div <div
id="import-dropdown" id="import-dropdown"
className="border border-slate-200 rounded-md bg-white px-2 text-center select-none cursor-pointer text-black duration-100 hover:border-sky-700" className="border border-slate-200 dark:border-neutral-700 rounded-md bg-white dark:bg-neutral-800 px-2 text-center select-none cursor-pointer duration-100 hover:border-sky-300 hover:dark:border-sky-600"
> >
Import From Import From
</div> </div>
@ -172,13 +178,13 @@ export default function PrivacySettings({
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
if (target.id !== "import-dropdown") setImportDropdown(false); if (target.id !== "import-dropdown") setImportDropdown(false);
}} }}
className={`absolute top-7 left-0 w-36 py-1 shadow-md border border-sky-100 bg-gray-50 rounded-md flex flex-col z-20`} className={`absolute top-7 left-0 w-36 py-1 shadow-md border border-sky-100 dark:border-neutral-700 bg-gray-50 dark:bg-neutral-800 rounded-md flex flex-col z-20`}
> >
<div className="cursor-pointer rounded-md"> <div className="cursor-pointer rounded-md">
<label <label
htmlFor="import-file" htmlFor="import-file"
title="JSON" title="JSON"
className="flex items-center gap-2 py-1 px-2 hover:bg-slate-200 duration-100 cursor-pointer" className="flex items-center gap-2 py-1 px-2 hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 cursor-pointer"
> >
Linkwarden Linkwarden
<input <input
@ -196,7 +202,7 @@ export default function PrivacySettings({
</div> </div>
<Link className="w-fit" href="/api/data"> <Link className="w-fit" href="/api/data">
<div className="border border-slate-200 rounded-md bg-white px-2 text-center select-none cursor-pointer text-black duration-100 hover:border-sky-700"> <div className="border border-slate-200 dark:border-neutral-700 rounded-md bg-white dark:bg-neutral-800 px-2 text-center select-none cursor-pointer duration-100 hover:border-sky-300 hover:dark:border-sky-600">
Export Data Export Data
</div> </div>
</Link> </Link>

View File

@ -129,7 +129,7 @@ export default function ProfileSettings({
<label <label
htmlFor="upload-photo" htmlFor="upload-photo"
title="PNG or JPG (Max: 3MB)" title="PNG or JPG (Max: 3MB)"
className="border border-slate-200 rounded-md bg-white px-2 text-center select-none cursor-pointer text-black duration-100 hover:border-sky-700" className="border border-slate-200 dark:border-neutral-700 rounded-md bg-white dark:bg-neutral-800 px-2 text-center select-none cursor-pointer duration-100 hover:border-sky-300 hover:dark:border-sky-600"
> >
Browse... Browse...
<input <input
@ -154,7 +154,7 @@ export default function ProfileSettings({
type="text" type="text"
value={user.name} value={user.name}
onChange={(e) => setUser({ ...user, name: e.target.value })} onChange={(e) => setUser({ ...user, name: e.target.value })}
className="w-full rounded-md p-2 border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-700 focus:dark:border-sky-600 duration-100"
/> />
</div> </div>
@ -164,7 +164,7 @@ export default function ProfileSettings({
type="text" type="text"
value={user.username || ""} value={user.username || ""}
onChange={(e) => setUser({ ...user, username: e.target.value })} onChange={(e) => setUser({ ...user, username: e.target.value })}
className="w-full rounded-md p-2 border-sky-100 dark:border-sky-800 dark:bg-sky-950 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-700 focus:dark:border-sky-600 duration-100"
/> />
</div> </div>

View File

@ -32,7 +32,7 @@ export default function UserModal({
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 hover:dark:bg-sky-700 rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
} }
> >
Profile Settings Profile Settings
@ -42,7 +42,7 @@ export default function UserModal({
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 hover:dark:bg-sky-600 rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
} }
> >
Privacy Settings Privacy Settings
@ -52,7 +52,7 @@ export default function UserModal({
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-500 dark:text-white duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 hover:dark:bg-sky-600 rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
} }
> >
Password Password
@ -62,8 +62,8 @@ export default function UserModal({
<Tab <Tab
className={({ selected }) => className={({ selected }) =>
selected selected
? "px-2 py-1 bg-sky-200 duration-100 rounded-md outline-none" ? "px-2 py-1 bg-sky-200 dark:bg-sky-500 duration-100 rounded-md outline-none"
: "px-2 py-1 hover:bg-slate-200 rounded-md duration-100 outline-none" : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 rounded-md duration-100 outline-none"
} }
> >
Billing Portal Billing Portal

View File

@ -16,10 +16,10 @@ export default function Modal({ toggleModal, className, children }: Props) {
onClickOutside={toggleModal} onClickOutside={toggleModal}
className={`m-auto ${className}`} className={`m-auto ${className}`}
> >
<div className="slide-up relative border-sky-100 dark:border-sky-800 rounded-2xl border-solid border shadow-lg p-5 bg-white dark:bg-sky-950"> <div className="slide-up relative border-sky-100 dark:border-neutral-700 rounded-2xl border-solid border shadow-lg p-5 bg-white dark:bg-neutral-900">
<div <div
onClick={toggleModal as MouseEventHandler<HTMLDivElement>} onClick={toggleModal as MouseEventHandler<HTMLDivElement>}
className="absolute top-5 left-5 inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-sky-800 duration-100 z-20 p-2" className="absolute top-5 left-5 inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 z-20 p-2"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faChevronLeft} icon={faChevronLeft}

View File

@ -9,8 +9,8 @@ import { useRouter } from "next/router";
import Search from "@/components/Search"; import Search from "@/components/Search";
import useAccountStore from "@/store/account"; import useAccountStore from "@/store/account";
import ProfilePhoto from "@/components/ProfilePhoto"; import ProfilePhoto from "@/components/ProfilePhoto";
import ToggleDarkMode from "@/components/ToggleDarkMode";
import useModalStore from "@/store/modals"; import useModalStore from "@/store/modals";
import { useTheme } from "next-themes";
export default function Navbar() { export default function Navbar() {
const { setModal } = useModalStore(); const { setModal } = useModalStore();
@ -23,6 +23,16 @@ export default function Navbar() {
const router = useRouter(); const router = useRouter();
const { theme, setTheme } = useTheme();
const handleToggle = () => {
if (theme === "dark") {
setTheme("light");
} else {
setTheme("dark");
}
};
window.addEventListener("resize", () => setSidebar(false)); window.addEventListener("resize", () => setSidebar(false));
useEffect(() => { useEffect(() => {
@ -34,10 +44,10 @@ export default function Navbar() {
}; };
return ( return (
<div className="flex justify-between gap-2 items-center px-5 py-2 border-solid border-b-sky-100 dark:border-b-sky-800 border-b h-16"> <div className="flex justify-between gap-2 items-center px-5 py-2 border-solid border-b-sky-100 dark:border-b-neutral-700 border-b h-16">
<div <div
onClick={toggleSidebar} onClick={toggleSidebar}
className="inline-flex lg:hidden gap-1 items-center select-none cursor-pointer p-[0.687rem] text-black rounded-md duration-100 hover:bg-slate-200" className="inline-flex lg:hidden gap-1 items-center select-none cursor-pointer p-[0.687rem] text-black dark:text-white rounded-md duration-100 hover:bg-slate-200 dark:hover:bg-neutral-700"
> >
<FontAwesomeIcon icon={faBars} className="w-5 h-5" /> <FontAwesomeIcon icon={faBars} className="w-5 h-5" />
</div> </div>
@ -51,7 +61,7 @@ export default function Navbar() {
method: "CREATE", method: "CREATE",
}); });
}} }}
className="inline-flex gap-1 relative sm:w-[7.2rem] items-center font-semibold select-none cursor-pointer p-[0.687rem] sm:p-2 sm:px-3 rounded-md sm:rounded-full hover:bg-sky-100 text-black sm:text-white sm:bg-sky-700 sm:dark:bg-sky-400 sm:hover:bg-sky-600 duration-100 group" className="inline-flex gap-1 relative sm:w-[7.2rem] items-center font-semibold select-none cursor-pointer p-[0.687rem] sm:p-2 sm:px-3 rounded-md sm:rounded-full hover:bg-sky-100 dark:hover:bg-sky-800 sm:dark:hover:bg-sky-600 text-sky-500 sm:text-white sm:bg-sky-700 sm:hover:bg-sky-600 duration-100 group"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faPlus} icon={faPlus}
@ -61,16 +71,15 @@ export default function Navbar() {
New Link New Link
</span> </span>
</div> </div>
<ToggleDarkMode />
<div className="relative"> <div className="relative">
<div <div
className="flex gap-1 group sm:hover:bg-slate-200 sm:hover:dark:bg-sky-900 sm:hover:p-1 sm:hover:pr-2 duration-100 h-10 rounded-full items-center w-fit bg-white dark:bg-sky-950 cursor-pointer" className="flex gap-1 group sm:hover:bg-slate-200 sm:hover:dark:bg-neutral-700 sm:hover:p-1 sm:hover:pr-2 duration-100 h-10 rounded-full items-center w-fit cursor-pointer"
onClick={() => setProfileDropdown(!profileDropdown)} onClick={() => setProfileDropdown(!profileDropdown)}
id="profile-dropdown" id="profile-dropdown"
> >
<ProfilePhoto <ProfilePhoto
src={account.profilePic} src={account.profilePic}
className="sm:group-hover:h-8 sm:group-hover:w-8 duration-100 border-[3px] dark:border-sky-800" className="sm:group-hover:h-8 sm:group-hover:w-8 duration-100 border-[3px]"
/> />
<p <p
id="profile-dropdown" id="profile-dropdown"
@ -93,6 +102,13 @@ export default function Navbar() {
setProfileDropdown(!profileDropdown); setProfileDropdown(!profileDropdown);
}, },
}, },
{
name: `Switch to ${theme === "light" ? "Dark" : "Light"}`,
onClick: () => {
handleToggle();
setProfileDropdown(!profileDropdown);
},
},
{ {
name: "Logout", name: "Logout",
onClick: () => { onClick: () => {

View File

@ -7,7 +7,7 @@ export default function NoLinksFound() {
const { setModal } = useModalStore(); const { setModal } = useModalStore();
return ( return (
<div className="border border-solid border-sky-100 dark:border-sky-800 w-full p-10 rounded-2xl"> <div className="border border-solid border-sky-100 dark:border-neutral-700 w-full p-10 rounded-2xl">
<p className="text-center text-3xl text-black dark:text-white"> <p className="text-center text-3xl text-black dark:text-white">
You haven&apos;t created any Links Here You haven&apos;t created any Links Here
</p> </p>

View File

@ -33,7 +33,7 @@ export default function ProfilePhoto({
return error || !src ? ( return error || !src ? (
<div <div
className={`bg-sky-500 dark:bg-sky-500 text-white h-10 w-10 aspect-square shadow rounded-full border border-slate-200 flex items-center justify-center ${className}`} className={`bg-sky-600 dark:bg-sky-600 text-white h-10 w-10 aspect-square shadow rounded-full border border-slate-200 dark:border-neutral-700 flex items-center justify-center ${className}`}
> >
<FontAwesomeIcon icon={faUser} className="w-1/2 h-1/2 aspect-square" /> <FontAwesomeIcon icon={faUser} className="w-1/2 h-1/2 aspect-square" />
</div> </div>
@ -43,7 +43,7 @@ export default function ProfilePhoto({
src={src} src={src}
height={112} height={112}
width={112} width={112}
className={`h-10 w-10 shadow rounded-full aspect-square border border-slate-200 ${className}`} className={`h-10 w-10 shadow rounded-full aspect-square border border-slate-200 dark:border-neutral-700 ${className}`}
/> />
); );
} }

View File

@ -58,8 +58,10 @@ export default function LinkCard({ link, count }: Props) {
<div className="flex justify-between items-center gap-5 w-full h-full z-0"> <div className="flex justify-between items-center gap-5 w-full h-full z-0">
<div className="flex flex-col justify-between"> <div className="flex flex-col justify-between">
<div className="flex items-baseline gap-1"> <div className="flex items-baseline gap-1">
<p className="text-sm text-black font-bold">{count + 1}.</p> <p className="text-xs text-gray-500">{count + 1}</p>
<p className="text-lg text-black font-bold">{link.name}</p> <p className="text-lg text-black">
{link.name || link.description}
</p>
</div> </div>
<p className="text-gray-500 text-sm font-medium"> <p className="text-gray-500 text-sm font-medium">
@ -79,7 +81,7 @@ export default function LinkCard({ link, count }: Props) {
</div> </div>
<div className="flex gap-2 items-center flex-wrap mt-2"> <div className="flex gap-2 items-center flex-wrap mt-2">
<p className="text-gray-500">{formattedDate}</p> <p className="text-gray-500">{formattedDate}</p>
<div className="text-black font-bold flex items-center gap-1"> <div className="text-black flex items-center gap-1">
<p>{url ? url.host : link.url}</p> <p>{url ? url.host : link.url}</p>
</div> </div>
</div> </div>

View File

@ -20,11 +20,11 @@ export default function RadioButton({ label, state, onClick }: Props) {
/> />
<FontAwesomeIcon <FontAwesomeIcon
icon={faCircleCheck} icon={faCircleCheck}
className="w-5 h-5 text-black dark:text-white peer-checked:block hidden" className="w-5 h-5 text-sky-500 dark:text-sky-300 peer-checked:block hidden"
/> />
<FontAwesomeIcon <FontAwesomeIcon
icon={faCircle} icon={faCircle}
className="w-5 h-5 text-black dark:text-white peer-checked:hidden block" className="w-5 h-5 text-sky-500 dark:text-sky-300 peer-checked:hidden block"
/> />
<span className="text-black dark:text-white rounded select-none"> <span className="text-black dark:text-white rounded select-none">
{label} {label}

View File

@ -44,7 +44,7 @@ export default function Search() {
router.push("/search/" + encodeURIComponent(searchQuery)) router.push("/search/" + encodeURIComponent(searchQuery))
} }
autoFocus={searchBox} autoFocus={searchBox}
className="border border-sky-100 dark:border-sky-800 rounded-md pl-10 py-2 pr-2 w-44 sm:w-60 focus:border-sky-300 dark:focus:border-sky-600 dark:hover:border-sky-600 md:focus:w-80 hover:border-sky-300 duration-100 outline-none dark:bg-sky-950" className="border border-sky-100 dark:border-neutral-700 focus:border-sky-300 dark:focus:border-sky-600 rounded-md pl-10 py-2 pr-2 w-44 sm:w-60 dark:hover:border-neutral-600 md:focus:w-80 hover:border-sky-300 duration-100 outline-none bg-inherit"
/> />
</div> </div>
); );

View File

@ -51,7 +51,7 @@ export default function Sidebar({ className }: { className?: string }) {
return ( return (
<div <div
className={`bg-gray-100 dark:bg-sky-900 h-full w-64 xl:w-80 overflow-y-auto border-solid border dark:border-sky-950 border-r-sky-100 dark:border-r-sky-800 px-2 z-20 ${className}`} className={`bg-gray-100 dark:bg-neutral-800 h-full w-64 xl:w-80 overflow-y-auto border-solid border dark:border-neutral-800 border-r-sky-100 dark:border-r-neutral-700 px-2 z-20 ${className}`}
> >
<div className="flex justify-center gap-2 mt-2"> <div className="flex justify-center gap-2 mt-2">
<Link <Link
@ -59,7 +59,7 @@ export default function Sidebar({ className }: { className?: string }) {
className={`${ className={`${
active === "/dashboard" active === "/dashboard"
? "bg-sky-200 dark:bg-sky-600" ? "bg-sky-200 dark:bg-sky-600"
: "hover:bg-slate-200 hover:dark:bg-sky-800 bg-gray-100 dark:bg-sky-900" : "hover:bg-slate-200 hover:dark:bg-neutral-700"
} outline-sky-100 outline-1 duration-100 py-1 px-2 rounded-md cursor-pointer flex justify-center flex-col items-center gap-1 w-full`} } outline-sky-100 outline-1 duration-100 py-1 px-2 rounded-md cursor-pointer flex justify-center flex-col items-center gap-1 w-full`}
> >
<FontAwesomeIcon <FontAwesomeIcon
@ -77,7 +77,7 @@ export default function Sidebar({ className }: { className?: string }) {
className={`${ className={`${
active === "/links" active === "/links"
? "bg-sky-200 dark:bg-sky-600" ? "bg-sky-200 dark:bg-sky-600"
: "hover:bg-slate-200 hover:dark:bg-sky-800 bg-gray-100 dark:bg-sky-900" : "hover:bg-slate-200 hover:dark:bg-neutral-700"
} outline-sky-100 outline-1 duration-100 py-1 px-2 rounded-md cursor-pointer flex justify-center flex-col items-center gap-1 w-full`} } outline-sky-100 outline-1 duration-100 py-1 px-2 rounded-md cursor-pointer flex justify-center flex-col items-center gap-1 w-full`}
> >
<FontAwesomeIcon <FontAwesomeIcon
@ -95,7 +95,7 @@ export default function Sidebar({ className }: { className?: string }) {
className={`${ className={`${
active === "/collections" active === "/collections"
? "bg-sky-200 dark:bg-sky-600" ? "bg-sky-200 dark:bg-sky-600"
: "hover:bg-slate-200 hover:dark:bg-sky-800" : "hover:bg-slate-200 hover:dark:bg-neutral-700"
} outline-sky-100 outline-1 duration-100 py-1 px-2 rounded-md cursor-pointer flex justify-center flex-col items-center gap-1 w-full`} } outline-sky-100 outline-1 duration-100 py-1 px-2 rounded-md cursor-pointer flex justify-center flex-col items-center gap-1 w-full`}
> >
<FontAwesomeIcon <FontAwesomeIcon
@ -144,7 +144,7 @@ export default function Sidebar({ className }: { className?: string }) {
className={`${ className={`${
active === `/collections/${e.id}` active === `/collections/${e.id}`
? "bg-sky-200 dark:bg-sky-700 " ? "bg-sky-200 dark:bg-sky-700 "
: "hover:bg-slate-200 hover:dark:bg-sky-800 bg-gray100 dark:bg-sky-900" : "hover:bg-slate-200 hover:dark:bg-neutral-700"
} duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`} } duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8 capitalize`}
> >
<FontAwesomeIcon <FontAwesomeIcon
@ -204,7 +204,7 @@ export default function Sidebar({ className }: { className?: string }) {
className={`${ className={`${
active === `/tags/${e.id}` active === `/tags/${e.id}`
? "bg-sky-200 dark:bg-sky-700" ? "bg-sky-200 dark:bg-sky-700"
: "hover:bg-slate-200 hover:dark:bg-sky-800 bg-gray-100 dark:bg-sky-900" : "hover:bg-slate-200 hover:dark:bg-neutral-700"
} duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8`} } duration-100 py-1 px-2 cursor-pointer flex items-center gap-2 w-full rounded-md h-8`}
> >
<FontAwesomeIcon <FontAwesomeIcon

View File

@ -21,7 +21,7 @@ export default function SortDropdown({
const target = e.target as HTMLInputElement; const target = e.target as HTMLInputElement;
if (target.id !== "sort-dropdown") toggleSortDropdown(); if (target.id !== "sort-dropdown") toggleSortDropdown();
}} }}
className="absolute top-8 right-0 border border-sky-100 dark:border-sky-800 shadow-md bg-gray-50 dark:bg-sky-900 rounded-md p-2 z-20 w-48" className="absolute top-8 right-0 border border-sky-100 dark:border-neutral-700 shadow-md bg-gray-50 dark:bg-neutral-800 rounded-md p-2 z-20 w-48"
> >
<p className="mb-2 text-black dark:text-white text-center font-semibold"> <p className="mb-2 text-black dark:text-white text-center font-semibold">
Sort by Sort by

View File

@ -21,7 +21,7 @@ export default function SubmitButton({
className={`text-white flex items-center gap-2 py-2 px-5 rounded-md text-lg tracking-wide select-none font-semibold duration-100 w-fit ${ className={`text-white flex items-center gap-2 py-2 px-5 rounded-md text-lg tracking-wide select-none font-semibold duration-100 w-fit ${
loading loading
? "bg-sky-600 cursor-auto" ? "bg-sky-600 cursor-auto"
: "bg-sky-700 dark:bg-sky-400 hover:bg-sky-600 hover:dark:bg-sky-300 cursor-pointer" : "bg-sky-700 hover:bg-sky-600 cursor-pointer"
} ${className}`} } ${className}`}
onClick={() => { onClick={() => {
if (!loading) onClick(); if (!loading) onClick();

View File

@ -23,7 +23,7 @@ export default function CenteredForm({ text, children }: Props) {
</p> </p>
) : undefined} ) : undefined}
{children} {children}
<p className="text-center text-xs text-gray-500 dark:text-white"> <p className="text-center text-xs text-gray-500 dark:text-gray-400">
© {new Date().getFullYear()} Linkwarden. All rights reserved. © {new Date().getFullYear()} Linkwarden. All rights reserved.
</p> </p>
</div> </div>

View File

@ -1,4 +1,4 @@
import React from "react"; import React, { useEffect } from "react";
import "@/styles/globals.css"; import "@/styles/globals.css";
import { SessionProvider } from "next-auth/react"; import { SessionProvider } from "next-auth/react";
import type { AppProps } from "next/app"; import type { AppProps } from "next/app";
@ -14,6 +14,10 @@ export default function App({
}: AppProps<{ }: AppProps<{
session: Session; session: Session;
}>) { }>) {
useEffect(() => {
if (!localStorage.getItem("theme")) localStorage.setItem("theme", "light");
}, []);
return ( return (
<SessionProvider session={pageProps.session}> <SessionProvider session={pageProps.session}>
<Head> <Head>
@ -38,13 +42,16 @@ export default function App({
/> />
<link rel="manifest" href="/site.webmanifest" /> <link rel="manifest" href="/site.webmanifest" />
</Head> </Head>
<Toaster
position="top-center"
reverseOrder={false}
toastOptions={{ className: "border border-sky-100" }}
/>
<AuthRedirect> <AuthRedirect>
<ThemeProvider attribute="class"> <ThemeProvider attribute="class">
<Toaster
position="top-center"
reverseOrder={false}
toastOptions={{
className:
"border border-sky-100 dark:dark:border-neutral-700 dark:bg-neutral-900 dark:text-white",
}}
/>
<Component {...pageProps} /> <Component {...pageProps} />
</ThemeProvider> </ThemeProvider>
</AuthRedirect> </AuthRedirect>

View File

@ -39,13 +39,13 @@ export default function Subscribe() {
return ( return (
<CenteredForm> <CenteredForm>
<div className="p-2 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100"> <div className="p-4 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 dark:border-neutral-700 dark:bg-neutral-800 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-center text-black font-bold"> <p className="text-2xl text-center text-black dark:text-white font-bold">
Choose a Username (Last step) Choose a Username (Last step)
</p> </p>
<div> <div>
<p className="text-sm text-black w-fit font-semibold mb-1"> <p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
Username Username
</p> </p>
@ -54,13 +54,16 @@ export default function Subscribe() {
placeholder="john" placeholder="john"
value={inputedUsername} value={inputedUsername}
onChange={(e) => setInputedUsername(e.target.value)} onChange={(e) => setInputedUsername(e.target.value)}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 dark:focus:border-sky-600 dark:border-neutral-700 dark:bg-neutral-900 duration-100"
/> />
</div> </div>
<div> <div>
<p className="text-md text-gray-500 mt-1"> <p className="text-md text-gray-500 dark:text-gray-400 mt-1">
Feel free to reach out to us at{" "} Feel free to reach out to us at{" "}
<a className="font-semibold" href="mailto:support@linkwarden.app"> <a
className="font-semibold underline"
href="mailto:support@linkwarden.app"
>
support@linkwarden.app support@linkwarden.app
</a>{" "} </a>{" "}
in case of any issues. in case of any issues.
@ -76,7 +79,7 @@ export default function Subscribe() {
<div <div
onClick={() => signOut()} onClick={() => signOut()}
className="w-fit mx-auto cursor-pointer text-gray-500 font-semibold " className="w-fit mx-auto cursor-pointer text-gray-500 dark:text-gray-400 font-semibold "
> >
Sign Out Sign Out
</div> </div>

View File

@ -50,7 +50,7 @@ export default function Index() {
return ( return (
<MainLayout> <MainLayout>
<div className="p-5 flex flex-col gap-5 w-full"> <div className="p-5 flex flex-col gap-5 w-full">
<div className="bg-gradient-to-tr from-sky-100 dark:from-sky-800 from-10% via-gray-100 via-20% rounded-2xl shadow min-h-[10rem] p-5 flex gap-5 flex-col justify-between"> <div className="bg-gradient-to-tr from-sky-100 dark:from-gray-800 from-10% via-gray-100 via-20% to-white dark:to-neutral-800 to-100% rounded-2xl shadow min-h-[10rem] p-5 flex gap-5 flex-col justify-between">
<div className="flex flex-col sm:flex-row gap-3 justify-between items-center sm:items-start"> <div className="flex flex-col sm:flex-row gap-3 justify-between items-center sm:items-start">
{activeCollection && ( {activeCollection && (
<div className="flex gap-3 items-center"> <div className="flex gap-3 items-center">
@ -60,7 +60,7 @@ export default function Index() {
style={{ color: activeCollection?.color }} style={{ color: activeCollection?.color }}
className="sm:w-8 sm:h-8 w-6 h-6 mt-3 drop-shadow" className="sm:w-8 sm:h-8 w-6 h-6 mt-3 drop-shadow"
/> />
<p className="sm:text-4xl text-3xl capitalize text-black dark:text-white font-bold w-full py-1 break-words hyphens-auto"> <p className="sm:text-4xl text-3xl capitalize text-black dark:text-white w-full py-1 break-words hyphens-auto">
{activeCollection?.name} {activeCollection?.name}
</p> </p>
</div> </div>
@ -116,14 +116,14 @@ export default function Index() {
) : null} ) : null}
</div> </div>
<div className="text-gray-600 dark:text-white flex justify-between items-end gap-5"> <div className="text-gray-500 dark:text-gray-300 flex justify-between items-end gap-5">
<p>{activeCollection?.description}</p> <p>{activeCollection?.description}</p>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<div className="relative"> <div className="relative">
<div <div
onClick={() => setSortDropdown(!sortDropdown)} onClick={() => setSortDropdown(!sortDropdown)}
id="sort-dropdown" id="sort-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faSort} icon={faSort}
@ -144,7 +144,7 @@ export default function Index() {
<div <div
onClick={() => setExpandDropdown(!expandDropdown)} onClick={() => setExpandDropdown(!expandDropdown)}
id="expand-dropdown" id="expand-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faEllipsis} icon={faEllipsis}

View File

@ -39,7 +39,7 @@ export default function Collections() {
icon={faFolder} icon={faFolder}
className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow" className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow"
/> />
<p className="sm:text-4xl text-3xl capitalize text-black dark:text-white font-bold"> <p className="sm:text-4xl text-3xl capitalize text-black dark:text-white">
All Collections All Collections
</p> </p>
</div> </div>
@ -47,7 +47,7 @@ export default function Collections() {
<div <div
onClick={() => setExpandDropdown(!expandDropdown)} onClick={() => setExpandDropdown(!expandDropdown)}
id="expand-dropdown" id="expand-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faEllipsis} icon={faEllipsis}
@ -86,7 +86,7 @@ export default function Collections() {
<div <div
onClick={() => setSortDropdown(!sortDropdown)} onClick={() => setSortDropdown(!sortDropdown)}
id="sort-dropdown" id="sort-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-sky-800 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faSort} icon={faSort}
@ -111,7 +111,7 @@ export default function Collections() {
})} })}
<div <div
className="p-5 self-stretch bg-gradient-to-tr from-sky-100 dark:from-sky-800 from-10% via-gray-100 via-20% min-h-[12rem] rounded-2xl cursor-pointer shadow duration-100 hover:shadow-none flex flex-col gap-4 justify-center items-center group" className="p-5 self-stretch bg-gradient-to-tr from-sky-100 dark:from-gray-800 from-10% via-gray-100 via-20% to-white dark:to-neutral-800 to-100% min-h-[12rem] rounded-2xl cursor-pointer shadow duration-100 hover:shadow-none flex flex-col gap-4 justify-center items-center group"
onClick={() => { onClick={() => {
setModal({ setModal({
modal: "COLLECTION", modal: "COLLECTION",

View File

@ -5,18 +5,18 @@ import React from "react";
export default function EmailConfirmaion() { export default function EmailConfirmaion() {
return ( return (
<CenteredForm> <CenteredForm>
<div className="p-2 sm:w-[30rem] w-80 rounded-2xl shadow-md m-auto border border-sky-100 bg-slate-50 text-black"> <div className="p-4 sm:w-[30rem] w-80 rounded-2xl shadow-md m-auto border border-sky-100 dark:border-neutral-700 bg-slate-50 text-black dark:text-white dark:bg-neutral-800">
<p className="text-center text-xl font-bold mb-2 text-black"> <p className="text-center text-xl font-bold mb-2">
Please check your Email Please check your Email
</p> </p>
<p>A sign in link has been sent to your email address.</p> <p>A sign in link has been sent to your email address.</p>
<p>You can safely close this page.</p> <p>You can safely close this page.</p>
<hr className="my-5" /> <hr className="my-5 dark:border-neutral-700" />
<p className="text-sm text-gray-500 "> <p className="text-sm text-gray-500 dark:text-gray-400">
If you didn&apos;t receive anything, go to the{" "} If you didn&apos;t receive anything, go to the{" "}
<Link href="/forgot" className="font-bold"> <Link href="/forgot" className="font-bold underline">
Password Recovery Password Recovery
</Link>{" "} </Link>{" "}
page and enter your Email to resend the sign in link. page and enter your Email to resend the sign in link.

View File

@ -85,7 +85,7 @@ export default function Dashboard() {
icon={faChartSimple} icon={faChartSimple}
className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow" className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow"
/> />
<p className="sm:text-4xl text-3xl capitalize text-black dark:text-white font-bold"> <p className="sm:text-4xl text-3xl capitalize text-black dark:text-white">
Dashboard Dashboard
</p> </p>
</div> </div>
@ -133,15 +133,17 @@ export default function Dashboard() {
onClick={() => { onClick={() => {
setLinkPinDisclosure(!linkPinDisclosure); setLinkPinDisclosure(!linkPinDisclosure);
}} }}
className="flex justify-between gap-2 items-baseline shadow active:shadow-inner duration-100 py-2 px-4 rounded-full" className="flex justify-between gap-2 items-baseline shadow active:shadow-inner dark:bg-neutral-700 duration-100 py-2 px-4 rounded-full"
> >
<p className="text-black text-xl">Pinned Links</p> <p className="text-black dark:text-white text-xl">
Pinned Links
</p>
<div className="text-black flex items-center gap-2"> <div className="text-black dark:text-white flex items-center gap-2">
{linkPinDisclosure ? "Hide" : "Show"} {linkPinDisclosure ? "Hide" : "Show"}
<FontAwesomeIcon <FontAwesomeIcon
icon={faChevronDown} icon={faChevronDown}
className={`w-4 h-4 text-black ${ className={`w-4 h-4 text-black dark:text-white ${
linkPinDisclosure ? "rotate-reverse" : "rotate" linkPinDisclosure ? "rotate-reverse" : "rotate"
}`} }`}
/> />
@ -167,7 +169,7 @@ export default function Dashboard() {
</div> </div>
</Disclosure> </Disclosure>
) : ( ) : (
<div className="border border-solid border-sky-100 dark:border-sky-800 w-full mx-auto md:w-2/3 p-10 rounded-2xl"> <div className="border border-solid border-sky-100 dark:border-neutral-700 w-full mx-auto md:w-2/3 p-10 rounded-2xl">
<p className="text-center text-2xl text-black dark:text-white"> <p className="text-center text-2xl text-black dark:text-white">
No Pinned Links No Pinned Links
</p> </p>

View File

@ -40,27 +40,31 @@ export default function Forgot() {
return ( return (
<CenteredForm> <CenteredForm>
<div className="p-2 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100"> <div className="p-4 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 dark:border-neutral-700 dark:bg-neutral-800 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-black font-bold">Password Recovery</p> <p className="text-2xl text-black dark:text-white font-bold">
Password Recovery
</p>
<div> <div>
<p className="text-md text-black"> <p className="text-md text-black dark:text-white">
Enter your Email so we can send you a link to recover your account. Enter your Email so we can send you a link to recover your account.
Make sure to change your password in the profile settings Make sure to change your password in the profile settings
afterwards. afterwards.
</p> </p>
<p className="text-sm text-gray-500"> <p className="text-sm text-gray-500 dark:text-gray-400">
You wont get logged in if you haven&apos;t created an account yet. You wont get logged in if you haven&apos;t created an account yet.
</p> </p>
</div> </div>
<div> <div>
<p className="text-sm text-black w-fit font-semibold mb-1">Email</p> <p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
Email
</p>
<input <input
type="text" type="text"
placeholder="johnny@example.com" placeholder="johnny@example.com"
value={form.email} value={form.email}
onChange={(e) => setForm({ ...form, email: e.target.value })} onChange={(e) => setForm({ ...form, email: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none dark:focus:border-sky-600 dark:border-neutral-700 dark:bg-neutral-900 focus:border-sky-700 duration-100"
/> />
</div> </div>
@ -71,7 +75,10 @@ export default function Forgot() {
loading={submitLoader} loading={submitLoader}
/> />
<div className="flex items-baseline gap-1 justify-center"> <div className="flex items-baseline gap-1 justify-center">
<Link href={"/login"} className="block text-black font-bold"> <Link
href={"/login"}
className="block text-black dark:text-white font-bold"
>
Go back Go back
</Link> </Link>
</div> </div>

View File

@ -26,7 +26,7 @@ export default function Links() {
icon={faLink} icon={faLink}
className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow" className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow"
/> />
<p className="sm:text-4xl text-3xl capitalize text-black dark:text-white font-bold"> <p className="sm:text-4xl text-3xl capitalize text-black dark:text-white">
All Links All Links
</p> </p>
</div> </div>
@ -35,7 +35,7 @@ export default function Links() {
<div <div
onClick={() => setSortDropdown(!sortDropdown)} onClick={() => setSortDropdown(!sortDropdown)}
id="sort-dropdown" id="sort-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-sky-800 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faSort} icon={faSort}

View File

@ -47,7 +47,7 @@ export default function Login() {
return ( return (
<CenteredForm text="Sign in to your account"> <CenteredForm text="Sign in to your account">
<div className="p-2 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 dark:bg-sky-950 rounded-2xl shadow-md border border-sky-100 dark:border-sky-800"> <div className="p-4 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 dark:bg-neutral-800 rounded-2xl shadow-md border border-sky-100 dark:border-neutral-700">
<p className="text-2xl text-black dark:text-white text-center font-bold"> <p className="text-2xl text-black dark:text-white text-center font-bold">
Enter your credentials Enter your credentials
</p> </p>
@ -63,7 +63,7 @@ export default function Login() {
placeholder="johnny" placeholder="johnny"
value={form.username} value={form.username}
onChange={(e) => setForm({ ...form, username: e.target.value })} onChange={(e) => setForm({ ...form, username: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-sky-800 dark:bg-sky-800 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
@ -77,11 +77,14 @@ export default function Login() {
placeholder="••••••••••••••" placeholder="••••••••••••••"
value={form.password} value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })} onChange={(e) => setForm({ ...form, password: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-sky-800 dark:bg-sky-800 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-300 dark:focus:border-sky-600 duration-100"
/> />
{emailEnabled && ( {emailEnabled && (
<div className="w-fit ml-auto mt-1"> <div className="w-fit ml-auto mt-1">
<Link href={"/forgot"} className="text-gray-500 font-semibold"> <Link
href={"/forgot"}
className="text-gray-500 dark:text-gray-400 font-semibold"
>
Forgot Password? Forgot Password?
</Link> </Link>
</div> </div>
@ -95,10 +98,10 @@ export default function Login() {
loading={submitLoader} loading={submitLoader}
/> />
<div className="flex items-baseline gap-1 justify-center"> <div className="flex items-baseline gap-1 justify-center">
<p className="w-fit text-gray-500 dark:text-white">New here?</p> <p className="w-fit text-gray-500 dark:text-gray-400">New here?</p>
<Link <Link
href={"/register"} href={"/register"}
className="block text-black dark:text-white font-bold" className="block text-black dark:text-white font-semibold"
> >
Sign Up Sign Up
</Link> </Link>

View File

@ -45,9 +45,7 @@ export default function PublicCollections() {
<div <div
className={`text-center bg-gradient-to-tr from-sky-100 from-10% via-gray-100 via-20% rounded-3xl shadow-lg p-5`} className={`text-center bg-gradient-to-tr from-sky-100 from-10% via-gray-100 via-20% rounded-3xl shadow-lg p-5`}
> >
<p className="text-5xl text-black font-bold mb-5 capitalize"> <p className="text-5xl text-black mb-5 capitalize">{data.name}</p>
{data.name}
</p>
{data.description && ( {data.description && (
<> <>

View File

@ -98,12 +98,12 @@ export default function Register() {
: "Create a new account" : "Create a new account"
} }
> >
<div className="p-2 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100"> <div className="p-4 flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 dark:bg-neutral-800 rounded-2xl shadow-md border border-sky-100 dark:border-neutral-700">
<p className="text-2xl text-black text-center font-bold"> <p className="text-2xl text-black dark:text-white text-center font-bold">
Enter your details Enter your details
</p> </p>
<div> <div>
<p className="text-sm text-black w-fit font-semibold mb-1"> <p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
Display Name Display Name
</p> </p>
@ -112,13 +112,13 @@ export default function Register() {
placeholder="Johnny" placeholder="Johnny"
value={form.name} value={form.name}
onChange={(e) => setForm({ ...form, name: e.target.value })} onChange={(e) => setForm({ ...form, name: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-700 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
{emailEnabled ? undefined : ( {emailEnabled ? undefined : (
<div> <div>
<p className="text-sm text-black w-fit font-semibold mb-1"> <p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
Username Username
</p> </p>
@ -127,27 +127,29 @@ export default function Register() {
placeholder="john" placeholder="john"
value={form.username} value={form.username}
onChange={(e) => setForm({ ...form, username: e.target.value })} onChange={(e) => setForm({ ...form, username: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-700 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
)} )}
{emailEnabled ? ( {emailEnabled ? (
<div> <div>
<p className="text-sm text-black w-fit font-semibold mb-1">Email</p> <p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
Email
</p>
<input <input
type="email" type="email"
placeholder="johnny@example.com" placeholder="johnny@example.com"
value={form.email} value={form.email}
onChange={(e) => setForm({ ...form, email: e.target.value })} onChange={(e) => setForm({ ...form, email: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-700 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
) : undefined} ) : undefined}
<div className="w-full"> <div className="w-full">
<p className="text-sm text-black w-fit font-semibold mb-1"> <p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
Password Password
</p> </p>
@ -156,12 +158,12 @@ export default function Register() {
placeholder="••••••••••••••" placeholder="••••••••••••••"
value={form.password} value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })} onChange={(e) => setForm({ ...form, password: e.target.value })}
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-700 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
<div className="w-full"> <div className="w-full">
<p className="text-sm text-black w-fit font-semibold mb-1"> <p className="text-sm text-black dark:text-white w-fit font-semibold mb-1">
Confirm Password Confirm Password
</p> </p>
@ -172,31 +174,34 @@ export default function Register() {
onChange={(e) => onChange={(e) =>
setForm({ ...form, passwordConfirmation: e.target.value }) setForm({ ...form, passwordConfirmation: e.target.value })
} }
className="w-full rounded-md p-2 mx-auto border-sky-100 border-solid border outline-none focus:border-sky-700 duration-100" className="w-full rounded-md p-2 mx-auto border-sky-100 dark:border-neutral-700 dark:bg-neutral-900 border-solid border outline-none focus:border-sky-700 dark:focus:border-sky-600 duration-100"
/> />
</div> </div>
{process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE ? ( {process.env.NEXT_PUBLIC_STRIPE_IS_ACTIVE ? (
<div> <div>
<p className="text-xs text-gray-500"> <p className="text-xs text-gray-500 dark:text-gray-400">
By signing up, you agree to our{" "} By signing up, you agree to our{" "}
<Link href="https://linkwarden.app/tos" className="font-semibold"> <Link
href="https://linkwarden.app/tos"
className="font-semibold underline"
>
Terms of Service Terms of Service
</Link>{" "} </Link>{" "}
and{" "} and{" "}
<Link <Link
href="https://linkwarden.app/privacy-policy" href="https://linkwarden.app/privacy-policy"
className="font-semibold" className="font-semibold underline"
> >
Privacy Policy Privacy Policy
</Link> </Link>
. .
</p> </p>
<p className="text-xs text-gray-500"> <p className="text-xs text-gray-500 dark:text-gray-400">
Need help?{" "} Need help?{" "}
<Link <Link
href="mailto:support@linkwarden.app" href="mailto:support@linkwarden.app"
className="font-semibold" className="font-semibold underline"
> >
Get in touch Get in touch
</Link> </Link>
@ -212,8 +217,13 @@ export default function Register() {
loading={submitLoader} loading={submitLoader}
/> />
<div className="flex items-baseline gap-1 justify-center"> <div className="flex items-baseline gap-1 justify-center">
<p className="w-fit text-gray-500">Already have an account?</p> <p className="w-fit text-gray-500 dark:text-gray-400">
<Link href={"/login"} className="block text-black font-bold"> Already have an account?
</p>
<Link
href={"/login"}
className="block text-black dark:text-white font-bold"
>
Login Login
</Link> </Link>
</div> </div>

View File

@ -42,7 +42,7 @@ export default function Links() {
icon={faSearch} icon={faSearch}
className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow" className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300 drop-shadow"
/> />
<p className="sm:text-4xl text-3xl capitalize text-black dark:text-white font-bold"> <p className="sm:text-4xl text-3xl capitalize text-black dark:text-white">
Search Results Search Results
</p> </p>
</div> </div>
@ -53,12 +53,12 @@ export default function Links() {
<div <div
onClick={() => setFilterDropdown(!filterDropdown)} onClick={() => setFilterDropdown(!filterDropdown)}
id="filter-dropdown" id="filter-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faFilter} icon={faFilter}
id="filter-dropdown" id="filter-dropdown"
className="w-5 h-5 text-gray-500" className="w-5 h-5 text-gray-500 dark:text-white"
/> />
</div> </div>
@ -75,12 +75,12 @@ export default function Links() {
<div <div
onClick={() => setSortDropdown(!sortDropdown)} onClick={() => setSortDropdown(!sortDropdown)}
id="sort-dropdown" id="sort-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faSort} icon={faSort}
id="sort-dropdown" id="sort-dropdown"
className="w-5 h-5 text-gray-500" className="w-5 h-5 text-gray-500 dark:text-white"
/> />
</div> </div>

View File

@ -28,10 +28,11 @@ export default function Subscribe() {
<CenteredForm <CenteredForm
text={`${ text={`${
process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14 process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS || 14
}-Day free trial, then $ }-Day free trial, then $${
${process.env.NEXT_PUBLIC_PRICING}/month afterwards`} process.env.NEXT_PUBLIC_PRICING
}/month afterwards`}
> >
<div className="p-2 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] w-80 bg-slate-50 rounded-2xl shadow-md border border-sky-100"> <div className="p-2 mx-auto flex flex-col gap-3 justify-between sm:w-[30rem] dark:border-neutral-700 w-80 bg-slate-50 dark:bg-neutral-800 rounded-2xl shadow-md border border-sky-100">
<p className="text-2xl text-center font-bold"> <p className="text-2xl text-center font-bold">
Subscribe to Linkwarden! Subscribe to Linkwarden!
</p> </p>
@ -56,7 +57,7 @@ export default function Subscribe() {
<div <div
onClick={() => signOut()} onClick={() => signOut()}
className="w-fit mx-auto cursor-pointer text-gray-500 font-semibold " className="w-fit mx-auto cursor-pointer text-gray-500 dark:text-gray-400 font-semibold "
> >
Sign Out Sign Out
</div> </div>

View File

@ -38,7 +38,7 @@ export default function Index() {
icon={faHashtag} icon={faHashtag}
className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300" className="sm:w-8 sm:h-8 w-6 h-6 mt-2 text-sky-500 dark:text-sky-300"
/> />
<p className="sm:text-4xl text-3xl capitalize text-black dark:text-white font-bold"> <p className="sm:text-4xl text-3xl capitalize text-black dark:text-white">
{activeTag?.name} {activeTag?.name}
</p> </p>
</div> </div>
@ -48,12 +48,12 @@ export default function Index() {
<div <div
onClick={() => setSortDropdown(!sortDropdown)} onClick={() => setSortDropdown(!sortDropdown)}
id="sort-dropdown" id="sort-dropdown"
className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 duration-100 p-1" className="inline-flex rounded-md cursor-pointer hover:bg-slate-200 hover:dark:bg-neutral-700 duration-100 p-1"
> >
<FontAwesomeIcon <FontAwesomeIcon
icon={faSort} icon={faSort}
id="sort-dropdown" id="sort-dropdown"
className="w-5 h-5 text-gray-500" className="w-5 h-5 text-gray-500 dark:text-white"
/> />
</div> </div>

View File

@ -136,11 +136,6 @@
bottom: 0; bottom: 0;
left: 0; left: 0;
pointer-events: none; pointer-events: none;
background-image: linear-gradient(
to bottom,
rgba(255, 255, 255, 0),
rgba(255, 255, 255, 1) 90%
);
width: 100%; width: 100%;
height: 4rem; height: 4rem;
} }
@ -151,19 +146,71 @@
top: 0; top: 0;
left: 0; left: 0;
pointer-events: none; pointer-events: none;
width: 100%;
height: 4rem;
}
/* For light mode */
.link-banner::after {
background-image: linear-gradient(
to bottom,
rgba(255, 255, 255, 0),
rgba(255, 255, 255, 1) 90%
);
}
.link-banner::before {
background-image: linear-gradient( background-image: linear-gradient(
to top, to top,
rgba(255, 255, 255, 0), rgba(255, 255, 255, 0),
rgba(255, 255, 255, 1) 90% rgba(255, 255, 255, 1) 90%
); );
width: 100%; }
height: 4rem;
/* For dark mode */
.banner-dark-mode .link-banner::after {
background-image: linear-gradient(
to bottom,
rgba(255, 255, 255, 0),
#171717 90%
);
}
.banner-dark-mode .link-banner::before {
background-image: linear-gradient(
to top,
rgba(255, 255, 255, 0),
#171717 90%
);
} }
/* Theme */ /* Theme */
@layer base { @layer base {
body { body {
@apply dark:bg-sky-950 bg-white dark:text-white; @apply dark:bg-neutral-900 bg-white dark:text-white;
}
}
/* react-select */
@layer components {
.react-select-container .react-select__control {
@apply dark:bg-neutral-900 dark:border-neutral-700 dark:hover:border-neutral-500;
}
.react-select-container {
@apply dark:border-neutral-700;
}
.react-select-container .react-select__menu {
@apply dark:bg-neutral-900 dark:border-neutral-700 border;
}
.react-select-container .react-select__option {
@apply dark:hover:bg-neutral-800;
}
.react-select-container .react-select__input-container,
.react-select-container .react-select__single-value {
@apply dark:text-white;
} }
} }