mirror of
https://github.com/linkwarden/linkwarden.git
synced 2026-03-03 00:27:01 +00:00
refactor(web): use separator component
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { ReactNode } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import Modal from "./Modal";
|
||||
import { Separator } from "./ui/separator";
|
||||
|
||||
type Props = {
|
||||
toggleModal: Function;
|
||||
@@ -24,7 +25,7 @@ export default function ConfirmationModal({
|
||||
return (
|
||||
<Modal toggleModal={toggleModal} className={className}>
|
||||
<p className="text-xl font-thin">{title}</p>
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="mb-3 mt-1" />
|
||||
{children}
|
||||
<div className="w-full flex items-center justify-end gap-2 mt-3">
|
||||
<Button
|
||||
|
||||
@@ -24,6 +24,7 @@ import LinkIcon from "./LinkViews/LinkComponents/LinkIcon";
|
||||
import LinkFormats from "./LinkViews/LinkComponents/LinkFormats";
|
||||
import LinkTypeBadge from "./LinkViews/LinkComponents/LinkTypeBadge";
|
||||
import LinkPin from "./LinkViews/LinkComponents/LinkPin";
|
||||
import { Separator } from "./ui/separator";
|
||||
|
||||
export function DashboardLinks({
|
||||
links,
|
||||
@@ -174,7 +175,7 @@ export function Card({ link, editMode }: Props) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<hr className="divider my-0 border-t border-neutral-content h-[1px]" />
|
||||
<Separator />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -191,7 +192,7 @@ export function Card({ link, editMode }: Props) {
|
||||
|
||||
{(show.collection || show.date) && (
|
||||
<div>
|
||||
<hr className="divider mt-0 mb-1 last:hidden border-t border-neutral-content h-[1px]" />
|
||||
<Separator className="mb-1" />
|
||||
|
||||
<div className="flex justify-between items-center text-xs text-neutral px-3 pb-1 gap-2">
|
||||
{show.collection && !isPublicRoute && (
|
||||
|
||||
@@ -9,6 +9,7 @@ import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { Button } from "./ui/button";
|
||||
import { Separator } from "./ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -28,7 +29,8 @@ const HighlightDrawer = ({ onClose }: Props) => {
|
||||
direction="left"
|
||||
>
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold mb-5">{t("notes_highlights")}</h2>
|
||||
<h2 className="text-lg font-semibold">{t("notes_highlights")}</h2>
|
||||
<Separator className="my-5" />
|
||||
{data && data.length > 0 ? (
|
||||
data.map((highlight) => {
|
||||
const formattedDate = new Date(highlight.createdAt).toLocaleString(
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { Separator } from "./ui/separator";
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
@@ -521,7 +522,7 @@ export default function LinkDetails({
|
||||
link={link}
|
||||
downloadable={true}
|
||||
/>
|
||||
<hr className="m-3 border-t border-neutral-content" />
|
||||
<Separator className="my-3" />
|
||||
</>
|
||||
) : undefined}
|
||||
|
||||
@@ -538,7 +539,7 @@ export default function LinkDetails({
|
||||
link={link}
|
||||
downloadable={true}
|
||||
/>
|
||||
<hr className="m-3 border-t border-neutral-content" />
|
||||
<Separator className="my-3" />
|
||||
</>
|
||||
) : undefined}
|
||||
|
||||
@@ -551,7 +552,7 @@ export default function LinkDetails({
|
||||
link={link}
|
||||
downloadable={true}
|
||||
/>
|
||||
<hr className="m-3 border-t border-neutral-content" />
|
||||
<Separator className="my-3" />
|
||||
</>
|
||||
) : undefined}
|
||||
|
||||
@@ -563,7 +564,7 @@ export default function LinkDetails({
|
||||
format={ArchivedFormat.readability}
|
||||
link={link}
|
||||
/>
|
||||
<hr className="m-3 border-t border-neutral-content" />
|
||||
<Separator className="my-3" />
|
||||
</>
|
||||
) : undefined}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import useLocalSettingsStore from "@/store/localSettings";
|
||||
import LinkPin from "./LinkPin";
|
||||
import LinkFormats from "./LinkFormats";
|
||||
import openLink from "@/lib/client/openLink";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
type Props = {
|
||||
link: LinkIncludingShortenedCollectionAndTags;
|
||||
@@ -211,7 +212,7 @@ export default function LinkCard({ link, columns, editMode }: Props) {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<hr className="divider my-0 border-t border-neutral-content h-[1px]" />
|
||||
<Separator />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -228,7 +229,7 @@ export default function LinkCard({ link, columns, editMode }: Props) {
|
||||
|
||||
{(show.collection || show.date) && (
|
||||
<div>
|
||||
<hr className="divider mt-0 mb-1 last:hidden border-t border-neutral-content h-[1px]" />
|
||||
<Separator className="mb-1" />
|
||||
|
||||
<div className="flex justify-between items-center text-xs text-neutral px-3 pb-1 gap-2">
|
||||
{show.collection && !isPublicRoute && (
|
||||
|
||||
@@ -31,6 +31,7 @@ import { useRouter } from "next/router";
|
||||
import LinkFormats from "./LinkFormats";
|
||||
import openLink from "@/lib/client/openLink";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
type Props = {
|
||||
link: LinkIncludingShortenedCollectionAndTags;
|
||||
@@ -200,7 +201,7 @@ export default function LinkMasonry({ link, editMode, columns }: Props) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<hr className="divider my-0 border-t border-neutral-content h-[1px]" />
|
||||
<Separator />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -247,7 +248,7 @@ export default function LinkMasonry({ link, editMode, columns }: Props) {
|
||||
|
||||
{(show.collection || show.date) && (
|
||||
<div>
|
||||
<hr className="divider mt-0 mb-1 last:hidden border-t border-neutral-content h-[1px]" />
|
||||
<Separator className="mb-1" />
|
||||
|
||||
<div className="flex flex-wrap justify-between items-center text-xs text-neutral px-3 pb-1 w-full gap-x-2">
|
||||
{!isPublicRoute && show.collection && (
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useBulkDeleteLinks } from "@linkwarden/router/links";
|
||||
import toast from "react-hot-toast";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -45,7 +46,7 @@ export default function BulkDeleteLinksModal({ onClose }: Props) {
|
||||
: t("delete_links", { count: selectedLinks.length })}
|
||||
</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p>
|
||||
|
||||
@@ -8,6 +8,7 @@ import Modal from "../Modal";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useBulkEditLinks } from "@linkwarden/router/links";
|
||||
import { Button } from "../ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -70,7 +71,8 @@ export default function BulkEditLinksModal({ onClose }: Props) {
|
||||
? t("edit_link")
|
||||
: t("edit_links", { count: selectedLinks.length })}
|
||||
</p>
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="mt-5">
|
||||
<div className="grid sm:grid-cols-2 gap-3">
|
||||
<div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useDeleteCollection } from "@linkwarden/router/collections";
|
||||
import toast from "react-hot-toast";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -63,7 +64,7 @@ export default function DeleteCollectionModal({
|
||||
{permissions === true ? t("delete_collection") : t("leave_collection")}
|
||||
</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
{permissions === true ? (
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useDeleteLink } from "@linkwarden/router/links";
|
||||
import toast from "react-hot-toast";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -51,7 +52,7 @@ export default function DeleteLinkModal({ onClose, activeLink }: Props) {
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin text-red-500">{t("delete_link")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p>{t("link_deletion_confirmation_message")}</p>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useTranslation } from "next-i18next";
|
||||
import toast from "react-hot-toast";
|
||||
import { RssSubscription } from "@linkwarden/prisma/client";
|
||||
import { useDeleteRssSubscription } from "@linkwarden/router/rss";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -45,7 +46,7 @@ export default function DeleteRssSubscriptionModal({
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin text-red-500">{t("delete_link")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p>{t("rss_deletion_confirmation")}</p>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useDeleteUser } from "@linkwarden/router/users";
|
||||
import { useState } from "react";
|
||||
import { useSession } from "next-auth/react";
|
||||
import { useConfig } from "@linkwarden/router/config";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -44,7 +45,7 @@ export default function DeleteUserModal({ onClose, userId }: Props) {
|
||||
{isAdmin ? t("delete_user") : t("remove_user")}
|
||||
</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p>{t("confirm_user_deletion")}</p>
|
||||
|
||||
@@ -9,6 +9,7 @@ import IconPicker from "../IconPicker";
|
||||
import { IconWeight } from "@phosphor-icons/react";
|
||||
import oklchVariableToHex from "@/lib/client/oklchVariableToHex";
|
||||
import { Button } from "../ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -55,7 +56,7 @@ export default function EditCollectionModal({
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin">{t("edit_collection_info")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex flex-col gap-3">
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { User } from "@linkwarden/prisma/client";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -113,7 +114,7 @@ export default function EditCollectionSharingModal({
|
||||
: t("team")}
|
||||
</p>
|
||||
|
||||
<div className="divider mb-3 mt-1" />
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
{permissions === true && !isPublicRoute && (
|
||||
@@ -154,7 +155,7 @@ export default function EditCollectionSharingModal({
|
||||
)}
|
||||
|
||||
{permissions === true && !isPublicRoute && (
|
||||
<div className="divider my-3" />
|
||||
<Separator className="my-3" />
|
||||
)}
|
||||
|
||||
{permissions === true && !isPublicRoute && (
|
||||
@@ -233,7 +234,7 @@ export default function EditCollectionSharingModal({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="divider my-0 last:hidden h-[1px]"></div>
|
||||
<Separator />
|
||||
|
||||
{collection.members
|
||||
.sort((a, b) => (a.userId as number) - (b.userId as number))
|
||||
@@ -261,98 +262,103 @@ export default function EditCollectionSharingModal({
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
key={e.userId}
|
||||
className="relative p-3 bg-base-200 rounded-xl flex gap-2 justify-between border-none"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<ProfilePhoto
|
||||
src={e.user.image ? e.user.image : undefined}
|
||||
name={e.user.name}
|
||||
/>
|
||||
<div className="ml-2">
|
||||
<p className="text-sm font-semibold">{e.user.name}</p>
|
||||
<p className="text-xs text-neutral">
|
||||
@{e.user.username}
|
||||
</p>
|
||||
<>
|
||||
<div
|
||||
key={e.userId}
|
||||
className="relative p-3 bg-base-200 rounded-xl flex gap-2 justify-between border-none"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<ProfilePhoto
|
||||
src={e.user.image ? e.user.image : undefined}
|
||||
name={e.user.name}
|
||||
/>
|
||||
<div className="ml-2">
|
||||
<p className="text-sm font-semibold">
|
||||
{e.user.name}
|
||||
</p>
|
||||
<p className="text-xs text-neutral">
|
||||
@{e.user.username}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{permissions === true && !isPublicRoute ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8">
|
||||
{t(roleKey)} <i className="bi-chevron-down" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent sideOffset={4} align="end">
|
||||
<DropdownMenuRadioGroup
|
||||
value={roleKey}
|
||||
onValueChange={handleRoleChange}
|
||||
>
|
||||
<DropdownMenuRadioItem value="viewer">
|
||||
<div>
|
||||
<p className="font-bold whitespace-nowrap">
|
||||
{t("viewer")}
|
||||
</p>
|
||||
<p className="whitespace-nowrap">
|
||||
{t("viewer_desc")}
|
||||
</p>
|
||||
</div>
|
||||
</DropdownMenuRadioItem>
|
||||
|
||||
<DropdownMenuRadioItem value="contributor">
|
||||
<div>
|
||||
<p className="font-bold whitespace-nowrap">
|
||||
{t("contributor")}
|
||||
</p>
|
||||
<p className="whitespace-nowrap">
|
||||
{t("contributor_desc")}
|
||||
</p>
|
||||
</div>
|
||||
</DropdownMenuRadioItem>
|
||||
|
||||
<DropdownMenuRadioItem value="admin">
|
||||
<div>
|
||||
<p className="font-bold whitespace-nowrap">
|
||||
{t("admin")}
|
||||
</p>
|
||||
<p className="whitespace-nowrap">
|
||||
{t("admin_desc")}
|
||||
</p>
|
||||
</div>
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : (
|
||||
<p className="text-sm text-neutral">{t(roleKey)}</p>
|
||||
)}
|
||||
|
||||
{permissions === true && !isPublicRoute && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="text-neutral hover:text-red-500"
|
||||
onClick={() => {
|
||||
setCollection({
|
||||
...collection,
|
||||
members: collection.members.filter(
|
||||
(member) => member.userId !== e.userId
|
||||
),
|
||||
});
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="bi-x text-xl"
|
||||
title={t("remove_member")}
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
{permissions === true && !isPublicRoute ? (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8">
|
||||
{t(roleKey)} <i className="bi-chevron-down" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent sideOffset={4} align="end">
|
||||
<DropdownMenuRadioGroup
|
||||
value={roleKey}
|
||||
onValueChange={handleRoleChange}
|
||||
>
|
||||
<DropdownMenuRadioItem value="viewer">
|
||||
<div>
|
||||
<p className="font-bold whitespace-nowrap">
|
||||
{t("viewer")}
|
||||
</p>
|
||||
<p className="whitespace-nowrap">
|
||||
{t("viewer_desc")}
|
||||
</p>
|
||||
</div>
|
||||
</DropdownMenuRadioItem>
|
||||
|
||||
<DropdownMenuRadioItem value="contributor">
|
||||
<div>
|
||||
<p className="font-bold whitespace-nowrap">
|
||||
{t("contributor")}
|
||||
</p>
|
||||
<p className="whitespace-nowrap">
|
||||
{t("contributor_desc")}
|
||||
</p>
|
||||
</div>
|
||||
</DropdownMenuRadioItem>
|
||||
|
||||
<DropdownMenuRadioItem value="admin">
|
||||
<div>
|
||||
<p className="font-bold whitespace-nowrap">
|
||||
{t("admin")}
|
||||
</p>
|
||||
<p className="whitespace-nowrap">
|
||||
{t("admin_desc")}
|
||||
</p>
|
||||
</div>
|
||||
</DropdownMenuRadioItem>
|
||||
</DropdownMenuRadioGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
) : (
|
||||
<p className="text-sm text-neutral">{t(roleKey)}</p>
|
||||
)}
|
||||
|
||||
{permissions === true && !isPublicRoute && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="text-neutral hover:text-red-500"
|
||||
onClick={() => {
|
||||
setCollection({
|
||||
...collection,
|
||||
members: collection.members.filter(
|
||||
(member) => member.userId !== e.userId
|
||||
),
|
||||
});
|
||||
}}
|
||||
>
|
||||
<i
|
||||
className="bi-x text-xl"
|
||||
title={t("remove_member")}
|
||||
/>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Separator className="last:hidden" />
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,7 @@ import TextInput from "@/components/TextInput";
|
||||
import Modal from "../Modal";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { Button } from "../ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -24,7 +25,7 @@ export default function EmailChangeVerificationModal({
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin">{t("confirm_password")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-5">
|
||||
<p>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useAddUser } from "@linkwarden/router/users";
|
||||
import Link from "next/link";
|
||||
import { signIn } from "next-auth/react";
|
||||
import { Button } from "../ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -69,7 +70,9 @@ export default function InviteModal({ onClose }: Props) {
|
||||
return (
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin">{t("invite_user")}</p>
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
|
||||
<Separator className="my-3" />
|
||||
|
||||
<p className="mb-3">{t("invite_user_desc")}</p>
|
||||
<form onSubmit={submit}>
|
||||
{emailEnabled ? (
|
||||
|
||||
@@ -10,6 +10,7 @@ import IconPicker from "../IconPicker";
|
||||
import { IconWeight } from "@phosphor-icons/react";
|
||||
import oklchVariableToHex from "@/lib/client/oklchVariableToHex";
|
||||
import { Button } from "../ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -72,7 +73,7 @@ export default function NewCollectionModal({ onClose, parent }: Props) {
|
||||
<p className="text-xl font-thin">{t("create_new_collection")}</p>
|
||||
)}
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex flex-col gap-3">
|
||||
|
||||
@@ -11,6 +11,7 @@ import { useAddLink } from "@linkwarden/router/links";
|
||||
import toast from "react-hot-toast";
|
||||
import { PostLinkSchemaType } from "@linkwarden/lib/schemaValidation";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -95,7 +96,9 @@ export default function NewLinkModal({ onClose }: Props) {
|
||||
return (
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin">{t("create_new_link")}</p>
|
||||
<div className="divider mb-3 mt-1" />
|
||||
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="grid grid-flow-row-dense sm:grid-cols-5 gap-3">
|
||||
<div className="sm:col-span-3 col-span-5">
|
||||
<p className="mb-2">{t("link")}</p>
|
||||
|
||||
@@ -6,6 +6,7 @@ import toast from "react-hot-toast";
|
||||
import TextInput from "../TextInput";
|
||||
import CollectionSelection from "../InputSelect/CollectionSelection";
|
||||
import { Button } from "../ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -57,7 +58,9 @@ export default function NewRssSubscriptionModal({ onClose }: Props) {
|
||||
<Modal toggleModal={onClose}>
|
||||
<>
|
||||
<p className="text-xl font-thin">{t("create_rss_subscription")}</p>
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex sm:flex-row flex-col gap-3 items-center">
|
||||
<div className="w-full">
|
||||
<label>{t("name")}</label>
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
DropdownMenuRadioGroup,
|
||||
DropdownMenuRadioItem,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -87,7 +88,7 @@ export default function NewTokenModal({ onClose }: Props) {
|
||||
<>
|
||||
<p className="text-xl font-thin">{t("create_access_token")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex sm:flex-row flex-col gap-2 items-center">
|
||||
<div className="w-full">
|
||||
|
||||
@@ -5,6 +5,7 @@ import { FormEvent, useState } from "react";
|
||||
import { useTranslation, Trans } from "next-i18next";
|
||||
import { useAddUser } from "@linkwarden/router/users";
|
||||
import { Button } from "../ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -70,7 +71,7 @@ export default function NewUserModal({ onClose }: Props) {
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin">{t("create_new_user")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<form onSubmit={submit}>
|
||||
<div className="grid sm:grid-cols-2 gap-3">
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useTranslation } from "next-i18next";
|
||||
import { AccessToken } from "@linkwarden/prisma/client";
|
||||
import { useRevokeToken } from "@linkwarden/router/tokens";
|
||||
import toast from "react-hot-toast";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -42,7 +43,7 @@ export default function DeleteTokenModal({ onClose, activeToken }: Props) {
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin text-red-500">{t("revoke_token")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p>{t("revoke_confirmation")}</p>
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useState } from "react";
|
||||
import Modal from "../Modal";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -17,7 +18,7 @@ export default function SurveyModal({ onClose, submit }: Props) {
|
||||
<Modal toggleModal={onClose}>
|
||||
<p className="text-xl font-thin">{t("quick_survey")}</p>
|
||||
|
||||
<div className="divider mb-3 mt-1"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-4">
|
||||
<p>{t("how_did_you_discover_linkwarden")}</p>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { useUploadFile } from "@linkwarden/router/links";
|
||||
import { PostLinkSchemaType } from "@linkwarden/lib/schemaValidation";
|
||||
import { useConfig } from "@linkwarden/router/config";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "../ui/separator";
|
||||
|
||||
type Props = {
|
||||
onClose: Function;
|
||||
@@ -99,7 +100,8 @@ export default function UploadFileModal({ onClose }: Props) {
|
||||
<div className="flex gap-2 items-start">
|
||||
<p className="text-xl font-thin">{t("upload_file")}</p>
|
||||
</div>
|
||||
<div className="divider mb-3 mt-1" />
|
||||
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="grid grid-flow-row-dense sm:grid-cols-5 gap-3">
|
||||
<div className="sm:col-span-3 col-span-5">
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import clsx from "clsx";
|
||||
import React from "react";
|
||||
|
||||
type Props = {
|
||||
className?: string;
|
||||
vertical?: boolean;
|
||||
};
|
||||
|
||||
function Divider({ className, vertical = false }: Props) {
|
||||
return vertical ? (
|
||||
<hr className={clsx("border-neutral-content border-l h-full", className)} />
|
||||
) : (
|
||||
<hr className={clsx("border-neutral-content border-t", className)} />
|
||||
);
|
||||
}
|
||||
|
||||
export default Divider;
|
||||
@@ -6,8 +6,8 @@ import { useTranslation } from "next-i18next";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import UserListing from "@/components/UserListing";
|
||||
import { useUsers } from "@linkwarden/router/users";
|
||||
import Divider from "@/components/ui/Divider";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
interface User extends U {
|
||||
subscriptions: {
|
||||
@@ -92,7 +92,7 @@ export default function Admin() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Divider className="my-3" />
|
||||
<Separator className="my-3" />
|
||||
|
||||
{searchQuery && filteredUsers && filteredUsers.length > 0 ? (
|
||||
<UserListing
|
||||
|
||||
@@ -7,6 +7,7 @@ import { FormEvent, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
interface FormData {
|
||||
password: string;
|
||||
@@ -70,7 +71,7 @@ export default function ResetPassword() {
|
||||
{requestSent ? t("password_updated") : t("reset_password")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-0"></div>
|
||||
<Separator />
|
||||
|
||||
{!requestSent ? (
|
||||
<>
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
DropdownMenuSeparator,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function Index() {
|
||||
const { t } = useTranslation();
|
||||
@@ -273,7 +274,7 @@ export default function Index() {
|
||||
|
||||
{activeCollection?.description && <p>{activeCollection.description}</p>}
|
||||
|
||||
<div className="divider my-0" />
|
||||
<Separator />
|
||||
|
||||
{collections.some((e) => e.parentId === activeCollection?.id) && (
|
||||
<>
|
||||
|
||||
@@ -6,6 +6,7 @@ import toast from "react-hot-toast";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function EmailConfirmaion() {
|
||||
const router = useRouter();
|
||||
@@ -42,7 +43,7 @@ export default function EmailConfirmaion() {
|
||||
{t("check_your_email")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
{router.query.email && typeof router.query.email === "string" && (
|
||||
<p className="text-center font-bold mb-3 break-all">
|
||||
|
||||
@@ -6,6 +6,7 @@ import { FormEvent, useState } from "react";
|
||||
import { toast } from "react-hot-toast";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
interface FormData {
|
||||
email: string;
|
||||
@@ -66,7 +67,7 @@ export default function Forgot() {
|
||||
{isEmailSent ? t("email_sent") : t("forgot_password")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-0"></div>
|
||||
<Separator />
|
||||
|
||||
{!isEmailSent ? (
|
||||
<>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { getToken } from "next-auth/jwt";
|
||||
import { prisma } from "@linkwarden/prisma";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
interface FormData {
|
||||
username: string;
|
||||
@@ -91,7 +92,8 @@ export default function Login({
|
||||
<p className="text-3xl text-black dark:text-white text-center font-extralight">
|
||||
{t("enter_credentials")}
|
||||
</p>
|
||||
<hr className="border-1 border-sky-100 dark:border-neutral-700" />
|
||||
|
||||
<Separator />
|
||||
|
||||
{process.env.NEXT_PUBLIC_DEMO === "true" &&
|
||||
process.env.NEXT_PUBLIC_DEMO_USERNAME &&
|
||||
@@ -205,7 +207,11 @@ export default function Login({
|
||||
</Button>
|
||||
|
||||
{availableLogins.buttonAuths.length > 0 && (
|
||||
<div className="divider my-1">{t("or_continue_with")}</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Separator className="my-1 flex-1 w-auto" />
|
||||
<p className="whitespace-nowrap">{t("or_continue_with")}</p>
|
||||
<Separator className="my-1 flex-1 w-auto" />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { toast } from "react-hot-toast";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import { Trans, useTranslation } from "next-i18next";
|
||||
import { useUpdateUser, useUser } from "@linkwarden/router/user";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
interface FormData {
|
||||
password: string;
|
||||
@@ -70,7 +71,7 @@ export default function MemberOnboarding() {
|
||||
{t("invitation_accepted")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-0"></div>
|
||||
<Separator />
|
||||
|
||||
<p
|
||||
style={{
|
||||
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { useUser } from "@linkwarden/router/user";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function PublicCollections() {
|
||||
const { t } = useTranslation();
|
||||
@@ -228,7 +229,7 @@ export default function PublicCollections() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="divider mt-5 mb-0"></div>
|
||||
<Separator className="mt-5" />
|
||||
|
||||
<div className="flex mb-5 mt-10 flex-col gap-5">
|
||||
<LinkListOptions
|
||||
|
||||
@@ -14,6 +14,7 @@ import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
||||
import { i18n } from "next-i18next.config";
|
||||
import { Trans, useTranslation } from "next-i18next";
|
||||
import { useConfig } from "@linkwarden/router/config";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
type FormData = {
|
||||
name: string;
|
||||
@@ -167,7 +168,7 @@ export default function Register({
|
||||
{t("enter_details")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-0"></div>
|
||||
<Separator />
|
||||
|
||||
<div>
|
||||
<p className="text-sm w-fit font-semibold mb-1">
|
||||
@@ -284,7 +285,11 @@ export default function Register({
|
||||
</Button>
|
||||
|
||||
{availableLogins.buttonAuths.length > 0 && (
|
||||
<div className="divider my-1">{t("or_continue_with")}</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Separator className="my-1 flex-1 w-auto" />
|
||||
<p className="whitespace-nowrap">{t("or_continue_with")}</p>
|
||||
<Separator className="my-1 flex-1 w-auto" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{displayLoginExternalButton()}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function AccessTokens() {
|
||||
const [newTokenModal, setNewTokenModal] = useState(false);
|
||||
@@ -33,7 +34,7 @@ export default function AccessTokens() {
|
||||
{t("access_tokens")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p>{t("access_tokens_description")}</p>
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function Account() {
|
||||
const [emailChangeVerificationModal, setEmailChangeVerificationModal] =
|
||||
@@ -149,7 +150,7 @@ export default function Account() {
|
||||
{t("accountSettings")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-5">
|
||||
<div className="grid sm:grid-cols-2 gap-3 auto-rows-auto">
|
||||
@@ -308,7 +309,7 @@ export default function Account() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex gap-3 flex-col">
|
||||
<div>
|
||||
@@ -335,7 +336,7 @@ export default function Account() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<p>
|
||||
{t("delete_account_warning")}
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
DropdownMenuSeparator,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
interface User extends U {
|
||||
subscriptions: {
|
||||
@@ -65,7 +66,7 @@ export default function Billing() {
|
||||
{t("billing_settings")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="w-full mx-auto flex flex-col gap-3 justify-between">
|
||||
<p className="text-md">
|
||||
@@ -94,7 +95,7 @@ export default function Billing() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex items-center justify-between gap-2 mb-3 relative">
|
||||
<div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button";
|
||||
import { useTranslation } from "next-i18next";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import { useUser } from "@linkwarden/router/user";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function Delete() {
|
||||
const [password, setPassword] = useState("");
|
||||
@@ -74,7 +75,7 @@ export default function Delete() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="divider my-0"></div>
|
||||
<Separator />
|
||||
|
||||
<p>{t("delete_warning")}</p>
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useTranslation } from "next-i18next";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import { useUpdateUser, useUser } from "@linkwarden/router/user";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function Password() {
|
||||
const { t } = useTranslation();
|
||||
@@ -56,7 +57,7 @@ export default function Password() {
|
||||
{t("change_password")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<p className="mb-3">{t("password_change_instructions")}</p>
|
||||
<div className="w-full flex flex-col gap-2 justify-between">
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function Preference() {
|
||||
const { t } = useTranslation();
|
||||
@@ -190,7 +191,7 @@ export default function Preference() {
|
||||
<SettingsLayout>
|
||||
<p className="capitalize text-3xl font-thin inline">{t("preference")}</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-5">
|
||||
<div>
|
||||
@@ -214,13 +215,14 @@ export default function Preference() {
|
||||
<div
|
||||
key={theme}
|
||||
className={`w-full text-center outline-solid outline-neutral-content outline h-20 duration-100 rounded-xl flex items-center justify-center cursor-pointer select-none ${bgColor} ${
|
||||
localStorage.getItem("theme") === theme
|
||||
account.theme === theme
|
||||
? `outline-primary ${activeColor}`
|
||||
: textColor
|
||||
}`}
|
||||
onClick={() =>
|
||||
updateUserPreference.mutate({ theme: theme as any })
|
||||
}
|
||||
onClick={() => {
|
||||
updateUserPreference.mutate({ theme: theme as any });
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
}}
|
||||
>
|
||||
<i className={`${icon} text-3xl`}></i>
|
||||
<p className="ml-2 text-xl">{t(theme)}</p>
|
||||
@@ -260,7 +262,7 @@ export default function Preference() {
|
||||
{t("ai_settings")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<p>{t("ai_tagging_method")}</p>
|
||||
|
||||
@@ -381,7 +383,9 @@ export default function Preference() {
|
||||
<p className="capitalize text-3xl font-thin inline">
|
||||
{t("archive_settings")}
|
||||
</p>
|
||||
<div className="divider my-3"></div>
|
||||
|
||||
<Separator className="my-3" />
|
||||
|
||||
<p>{t("formats_to_archive")}</p>
|
||||
<div className="p-3">
|
||||
<Checkbox
|
||||
@@ -485,7 +489,9 @@ export default function Preference() {
|
||||
<p className="capitalize text-3xl font-thin inline">
|
||||
{t("link_settings")}
|
||||
</p>
|
||||
<div className="divider my-3"></div>
|
||||
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="mb-3">
|
||||
<Checkbox
|
||||
label={t("prevent_duplicate_links")}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { RssSubscription } from "@linkwarden/prisma/client";
|
||||
import NewRssSubscriptionModal from "@/components/ModalContent/NewRssSubscriptionModal";
|
||||
import { useConfig } from "@linkwarden/router/config";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function RssSubscriptions() {
|
||||
const { t } = useTranslation();
|
||||
@@ -31,7 +32,8 @@ export default function RssSubscriptions() {
|
||||
{t("rss_subscriptions")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<p>
|
||||
{t("rss_subscriptions_desc", {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { LinkArchiveActionSchemaType } from "@linkwarden/lib/schemaValidation";
|
||||
import toast from "react-hot-toast";
|
||||
import { useArchiveAction } from "@linkwarden/router/links";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function Worker() {
|
||||
const { t } = useTranslation();
|
||||
@@ -54,7 +55,7 @@ export default function Worker() {
|
||||
<SettingsLayout>
|
||||
<p className="capitalize text-3xl font-thin inline">{t("worker")}</p>
|
||||
|
||||
<div className="divider my-3"></div>
|
||||
<Separator className="my-3" />
|
||||
|
||||
<div className="w-full flex flex-col gap-6 justify-between">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center gap-3">
|
||||
|
||||
@@ -8,6 +8,7 @@ import { Button } from "@/components/ui/button";
|
||||
import getServerSideProps from "@/lib/client/getServerSideProps";
|
||||
import { Trans, useTranslation } from "next-i18next";
|
||||
import { useUser } from "@linkwarden/router/user";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
|
||||
export default function Subscribe() {
|
||||
const { t } = useTranslation();
|
||||
@@ -53,7 +54,7 @@ export default function Subscribe() {
|
||||
{t("subscribe_title")}
|
||||
</p>
|
||||
|
||||
<div className="divider my-0"></div>
|
||||
<Separator />
|
||||
|
||||
<div>
|
||||
<p>
|
||||
|
||||
Reference in New Issue
Block a user