mirror of https://github.com/usememos/memos.git
feat: variant colors (#4816)
This commit is contained in:
parent
b164c15976
commit
91be2f68d1
|
|
@ -11,7 +11,7 @@
|
||||||
<!-- memos.metadata.head -->
|
<!-- memos.metadata.head -->
|
||||||
<title>Memos</title>
|
<title>Memos</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="text-base w-full min-h-svh bg-zinc-50 dark:bg-zinc-900">
|
<body class="text-base w-full min-h-svh">
|
||||||
<div id="root" class="relative w-full min-h-full"></div>
|
<div id="root" class="relative w-full min-h-full"></div>
|
||||||
<script type="module" src="/src/main.tsx"></script>
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
<!-- memos.metadata.body -->
|
<!-- memos.metadata.body -->
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
const getCellOpacity = (ratio: number): string => {
|
const getCellOpacity = (ratio: number): string => {
|
||||||
if (ratio === 0) return "";
|
if (ratio === 0) return "";
|
||||||
if (ratio > 0.75) return "bg-green-700/90 text-gray-50 dark:bg-green-400/80";
|
if (ratio > 0.75) return "bg-primary/90 text-primary-foreground";
|
||||||
if (ratio > 0.5) return "bg-green-700/70 text-gray-100 dark:bg-green-400/60";
|
if (ratio > 0.5) return "bg-primary/70 text-primary-foreground";
|
||||||
if (ratio > 0.25) return "bg-green-700/70 text-gray-100 dark:bg-green-400/40";
|
if (ratio > 0.25) return "bg-primary/50 text-primary-foreground";
|
||||||
return "bg-green-700/50 text-gray-100 dark:bg-green-400/20";
|
return "bg-primary/30 text-primary-foreground";
|
||||||
};
|
};
|
||||||
|
|
||||||
const CalendarCell = memo(
|
const CalendarCell = memo(
|
||||||
|
|
@ -37,10 +37,10 @@ const CalendarCell = memo(
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-6 h-6 text-xs lg:text-[13px] flex justify-center items-center cursor-default",
|
"w-6 h-6 text-xs lg:text-[13px] flex justify-center items-center cursor-default",
|
||||||
"rounded-lg border-2 text-gray-400 transition-all duration-200",
|
"rounded-lg border-2 text-muted-foreground transition-all duration-200",
|
||||||
dayInfo.isCurrentMonth && getCellOpacity(count / maxCount),
|
dayInfo.isCurrentMonth && getCellOpacity(count / maxCount),
|
||||||
dayInfo.isCurrentMonth && isToday && "border-zinc-400",
|
dayInfo.isCurrentMonth && isToday && "border-border",
|
||||||
dayInfo.isCurrentMonth && isSelected && "font-medium border-zinc-400",
|
dayInfo.isCurrentMonth && isSelected && "font-medium border-border",
|
||||||
dayInfo.isCurrentMonth && !isToday && !isSelected && "border-transparent",
|
dayInfo.isCurrentMonth && !isToday && !isSelected && "border-transparent",
|
||||||
count > 0 && "cursor-pointer hover:scale-110",
|
count > 0 && "cursor-pointer hover:scale-110",
|
||||||
)}
|
)}
|
||||||
|
|
@ -52,7 +52,7 @@ const CalendarCell = memo(
|
||||||
|
|
||||||
if (!dayInfo.isCurrentMonth) {
|
if (!dayInfo.isCurrentMonth) {
|
||||||
return (
|
return (
|
||||||
<div className={cn("w-6 h-6 text-xs lg:text-[13px] flex justify-center items-center cursor-default opacity-60 text-gray-400")}>
|
<div className={cn("w-6 h-6 text-xs lg:text-[13px] flex justify-center items-center cursor-default opacity-60 text-muted-foreground")}>
|
||||||
{dayInfo.day}
|
{dayInfo.day}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ const BrandBanner = observer((props: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("relative w-full h-auto shrink-0", props.className)}>
|
<div className={cn("relative w-full h-auto shrink-0", props.className)}>
|
||||||
<div className={cn("w-auto flex flex-row justify-start items-center text-gray-800 dark:text-gray-400", collapsed ? "px-1" : "px-3")}>
|
<div className={cn("w-auto flex flex-row justify-start items-center text-foreground", collapsed ? "px-1" : "px-3")}>
|
||||||
<UserAvatar className="shrink-0" avatarUrl={avatarUrl} />
|
<UserAvatar className="shrink-0" avatarUrl={avatarUrl} />
|
||||||
{!collapsed && <span className="ml-2 text-lg font-medium text-slate-800 dark:text-gray-300 shrink truncate">{title}</span>}
|
{!collapsed && <span className="ml-2 text-lg font-medium text-foreground shrink truncate">{title}</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ const ChangeMemberPasswordDialog: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p>
|
<p>
|
||||||
{t("setting.account-section.change-password")} ({user.displayName})
|
{t("setting.account-section.change-password")} ({user.displayName})
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center w-full mb-4 gap-2">
|
<div className="flex flex-row justify-between items-center w-full mb-4 gap-2">
|
||||||
<p>{t("setting.access-token-section.create-dialog.create-access-token")}</p>
|
<p>{t("setting.access-token-section.create-dialog.create-access-token")}</p>
|
||||||
<Button variant="ghost" onClick={() => destroy()}>
|
<Button variant="ghost" onClick={() => destroy()}>
|
||||||
|
|
@ -98,7 +98,7 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
|
||||||
<div className="flex flex-col justify-start items-start w-80!">
|
<div className="flex flex-col justify-start items-start w-80!">
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
<span className="mb-2">
|
<span className="mb-2">
|
||||||
{t("setting.access-token-section.create-dialog.description")} <span className="text-red-600">*</span>
|
{t("setting.access-token-section.create-dialog.description")} <span className="text-destructive">*</span>
|
||||||
</span>
|
</span>
|
||||||
<div className="relative w-full">
|
<div className="relative w-full">
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -112,7 +112,7 @@ const CreateAccessTokenDialog: React.FC<Props> = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
<span className="mb-2">
|
<span className="mb-2">
|
||||||
{t("setting.access-token-section.create-dialog.expiration")} <span className="text-red-600">*</span>
|
{t("setting.access-token-section.create-dialog.expiration")} <span className="text-destructive">*</span>
|
||||||
</span>
|
</span>
|
||||||
<div className="w-full flex flex-row justify-start items-center text-base">
|
<div className="w-full flex flex-row justify-start items-center text-base">
|
||||||
<RadioGroup value={state.expiration.toString()} onValueChange={handleRoleInputChange} className="flex flex-row gap-4">
|
<RadioGroup value={state.expiration.toString()} onValueChange={handleRoleInputChange} className="flex flex-row gap-4">
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p>{t(isCreating ? "setting.sso-section.create-sso" : "setting.sso-section.update-sso")}</p>
|
<p>{t(isCreating ? "setting.sso-section.create-sso" : "setting.sso-section.update-sso")}</p>
|
||||||
<Button variant="ghost" onClick={handleCloseBtnClick}>
|
<Button variant="ghost" onClick={handleCloseBtnClick}>
|
||||||
|
|
@ -285,7 +285,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
)}
|
)}
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("common.name")}
|
{t("common.name")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
@ -314,13 +314,13 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
{type === "OAUTH2" && (
|
{type === "OAUTH2" && (
|
||||||
<>
|
<>
|
||||||
{isCreating && (
|
{isCreating && (
|
||||||
<p className="border border-zinc-100 dark:border-zinc-700 rounded-md p-2 text-sm w-full mb-2 break-all">
|
<p className="border border-border rounded-md p-2 text-sm w-full mb-2 break-all">
|
||||||
{t("setting.sso-section.redirect-url")}: {absolutifyLink("/auth/callback")}
|
{t("setting.sso-section.redirect-url")}: {absolutifyLink("/auth/callback")}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("setting.sso-section.client-id")}
|
{t("setting.sso-section.client-id")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
@ -330,7 +330,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
/>
|
/>
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("setting.sso-section.client-secret")}
|
{t("setting.sso-section.client-secret")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
@ -340,7 +340,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
/>
|
/>
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("setting.sso-section.authorization-endpoint")}
|
{t("setting.sso-section.authorization-endpoint")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
@ -350,7 +350,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
/>
|
/>
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("setting.sso-section.token-endpoint")}
|
{t("setting.sso-section.token-endpoint")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
@ -360,7 +360,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
/>
|
/>
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("setting.sso-section.user-endpoint")}
|
{t("setting.sso-section.user-endpoint")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
@ -370,7 +370,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
/>
|
/>
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("setting.sso-section.scopes")}
|
{t("setting.sso-section.scopes")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
@ -381,7 +381,7 @@ const CreateIdentityProviderDialog: React.FC<Props> = (props: Props) => {
|
||||||
<Separator className="my-2" />
|
<Separator className="my-2" />
|
||||||
<p className="mb-1 text-sm font-medium">
|
<p className="mb-1 text-sm font-medium">
|
||||||
{t("setting.sso-section.identifier")}
|
{t("setting.sso-section.identifier")}
|
||||||
<span className="text-red-600">*</span>
|
<span className="text-destructive">*</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="mb-2 w-full"
|
className="mb-2 w-full"
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p className="title-text">{`${isCreating ? t("common.create") : t("common.edit")} ${t("common.shortcuts")}`}</p>
|
<p className="title-text">{`${isCreating ? t("common.create") : t("common.edit")} ${t("common.shortcuts")}`}</p>
|
||||||
<Button variant="ghost" onClick={() => destroy()}>
|
<Button variant="ghost" onClick={() => destroy()}>
|
||||||
|
|
@ -98,7 +98,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||||
<ul className="list-disc list-inside text-sm pl-2 mt-1">
|
<ul className="list-disc list-inside text-sm pl-2 mt-1">
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
className="text-sm text-blue-600 hover:underline"
|
className="text-sm text-primary hover:underline"
|
||||||
href="https://www.usememos.com/docs/getting-started/shortcuts"
|
href="https://www.usememos.com/docs/getting-started/shortcuts"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
@ -107,7 +107,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
className="text-sm text-blue-600 hover:underline"
|
className="text-sm text-primary hover:underline"
|
||||||
href="https://www.usememos.com/docs/getting-started/shortcuts#how-to-write-a-filter"
|
href="https://www.usememos.com/docs/getting-started/shortcuts#how-to-write-a-filter"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ const CreateUserDialog: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p className="title-text">{`${isCreating ? t("common.create") : t("common.edit")} ${t("common.user")}`}</p>
|
<p className="title-text">{`${isCreating ? t("common.create") : t("common.edit")} ${t("common.user")}`}</p>
|
||||||
<Button variant="ghost" onClick={() => destroy()}>
|
<Button variant="ghost" onClick={() => destroy()}>
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p className="title-text">
|
<p className="title-text">
|
||||||
{isCreating ? t("setting.webhook-section.create-dialog.create-webhook") : t("setting.webhook-section.create-dialog.edit-webhook")}
|
{isCreating ? t("setting.webhook-section.create-dialog.create-webhook") : t("setting.webhook-section.create-dialog.edit-webhook")}
|
||||||
|
|
@ -116,7 +116,7 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
|
||||||
<div className="flex flex-col justify-start items-start w-80!">
|
<div className="flex flex-col justify-start items-start w-80!">
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
<span className="mb-2">
|
<span className="mb-2">
|
||||||
{t("setting.webhook-section.create-dialog.title")} <span className="text-red-600">*</span>
|
{t("setting.webhook-section.create-dialog.title")} <span className="text-destructive">*</span>
|
||||||
</span>
|
</span>
|
||||||
<div className="relative w-full">
|
<div className="relative w-full">
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -130,7 +130,7 @@ const CreateWebhookDialog: React.FC<Props> = (props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-start mb-3">
|
<div className="w-full flex flex-col justify-start items-start mb-3">
|
||||||
<span className="mb-2">
|
<span className="mb-2">
|
||||||
{t("setting.webhook-section.create-dialog.payload-url")} <span className="text-red-600">*</span>
|
{t("setting.webhook-section.create-dialog.payload-url")} <span className="text-destructive">*</span>
|
||||||
</span>
|
</span>
|
||||||
<div className="relative w-full">
|
<div className="relative w-full">
|
||||||
<Input
|
<Input
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const DateTimeInput: React.FC<Props> = ({ value, onChange }) => {
|
||||||
type="text"
|
type="text"
|
||||||
className={cn(
|
className={cn(
|
||||||
"px-1 bg-transparent rounded text-xs transition-all",
|
"px-1 bg-transparent rounded text-xs transition-all",
|
||||||
"border-transparent outline-none focus:border-gray-300 dark:focus:border-zinc-700",
|
"border-transparent outline-none focus:border-border",
|
||||||
"border",
|
"border",
|
||||||
)}
|
)}
|
||||||
defaultValue={formatDate(value)}
|
defaultValue={formatDate(value)}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ const BaseDialog = observer((props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed top-0 left-0 flex flex-col justify-start items-center w-full h-full pt-16 pb-8 px-4 z-1000 overflow-x-hidden overflow-y-scroll transition-all hide-scrollbar bg-black/60",
|
"fixed top-0 left-0 flex flex-col justify-start items-center w-full h-full pt-16 pb-8 px-4 z-1000 overflow-x-hidden overflow-y-scroll transition-all hide-scrollbar bg-foreground/60",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
onMouseDown={handleSpaceClicked}
|
onMouseDown={handleSpaceClicked}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { BirdIcon } from "lucide-react";
|
||||||
const Empty = () => {
|
const Empty = () => {
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto">
|
<div className="mx-auto">
|
||||||
<BirdIcon strokeWidth={0.5} absoluteStrokeWidth={true} className="w-24 h-auto text-gray-500 dark:text-gray-400" />
|
<BirdIcon strokeWidth={0.5} absoluteStrokeWidth={true} className="w-24 h-auto text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ const HomeSidebarDrawer = () => {
|
||||||
<Sheet open={open} onOpenChange={setOpen}>
|
<Sheet open={open} onOpenChange={setOpen}>
|
||||||
<SheetTrigger asChild>
|
<SheetTrigger asChild>
|
||||||
<Button variant="ghost" className="bg-transparent! px-2">
|
<Button variant="ghost" className="bg-transparent! px-2">
|
||||||
<MenuIcon className="w-6 h-auto dark:text-gray-400" />
|
<MenuIcon className="w-6 h-auto text-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
<SheetContent side="right" className="w-full sm:w-80 bg-zinc-100 dark:bg-zinc-900">
|
<SheetContent side="right" className="w-full sm:w-80 bg-secondary">
|
||||||
<HomeSidebar className="px-4 py-4" />
|
<HomeSidebar className="px-4 py-4" />
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const ShortcutsSection = observer(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col justify-start items-start mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar">
|
<div className="w-full flex flex-col justify-start items-start mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar">
|
||||||
<div className="flex flex-row justify-between items-center w-full gap-1 mb-1 text-sm leading-6 text-gray-400 select-none">
|
<div className="flex flex-row justify-between items-center w-full gap-1 mb-1 text-sm leading-6 text-muted-foreground select-none">
|
||||||
<span>{t("common.shortcuts")}</span>
|
<span>{t("common.shortcuts")}</span>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
|
|
@ -61,10 +61,10 @@ const ShortcutsSection = observer(() => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={shortcutId}
|
key={shortcutId}
|
||||||
className="shrink-0 w-full text-sm rounded-md leading-6 flex flex-row justify-between items-center select-none gap-2 text-gray-600 dark:text-gray-400 dark:border-zinc-800"
|
className="shrink-0 w-full text-sm rounded-md leading-6 flex flex-row justify-between items-center select-none gap-2 text-muted-foreground"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={cn("truncate cursor-pointer dark:opacity-80", selected && "text-primary font-medium")}
|
className={cn("truncate cursor-pointer opacity-80", selected && "text-primary font-medium")}
|
||||||
onClick={() => (selected ? memoFilterStore.setShortcut(undefined) : memoFilterStore.setShortcut(shortcutId))}
|
onClick={() => (selected ? memoFilterStore.setShortcut(undefined) : memoFilterStore.setShortcut(shortcutId))}
|
||||||
>
|
>
|
||||||
{emoji && <span className="text-base mr-1">{emoji}</span>}
|
{emoji && <span className="text-base mr-1">{emoji}</span>}
|
||||||
|
|
@ -78,14 +78,14 @@ const ShortcutsSection = observer(() => {
|
||||||
<div className="flex flex-col text-sm gap-0.5">
|
<div className="flex flex-col text-sm gap-0.5">
|
||||||
<button
|
<button
|
||||||
onClick={() => showCreateShortcutDialog({ shortcut })}
|
onClick={() => showCreateShortcutDialog({ shortcut })}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<Edit3Icon className="w-4 h-auto" />
|
<Edit3Icon className="w-4 h-auto" />
|
||||||
{t("common.edit")}
|
{t("common.edit")}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDeleteShortcut(shortcut)}
|
onClick={() => handleDeleteShortcut(shortcut)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-destructive hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-4 h-auto" />
|
<TrashIcon className="w-4 h-auto" />
|
||||||
{t("common.delete")}
|
{t("common.delete")}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ const TagsSection = observer((props: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col justify-start items-start w-full mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar">
|
<div className="flex flex-col justify-start items-start w-full mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar">
|
||||||
<div className="flex flex-row justify-between items-center w-full gap-1 mb-1 text-sm leading-6 text-gray-400 select-none">
|
<div className="flex flex-row justify-between items-center w-full gap-1 mb-1 text-sm leading-6 text-muted-foreground select-none">
|
||||||
<span>{t("common.tags")}</span>
|
<span>{t("common.tags")}</span>
|
||||||
{tags.length > 0 && (
|
{tags.length > 0 && (
|
||||||
<Popover>
|
<Popover>
|
||||||
|
|
@ -57,7 +57,7 @@ const TagsSection = observer((props: Props) => {
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent align="end" alignOffset={-12}>
|
<PopoverContent align="end" alignOffset={-12}>
|
||||||
<div className="w-auto flex flex-row justify-between items-center gap-2 p-1">
|
<div className="w-auto flex flex-row justify-between items-center gap-2 p-1">
|
||||||
<span className="text-sm shrink-0 dark:text-zinc-400">{t("common.tree-mode")}</span>
|
<span className="text-sm shrink-0">{t("common.tree-mode")}</span>
|
||||||
<Switch checked={treeMode} onCheckedChange={(checked) => setTreeMode(checked)} />
|
<Switch checked={treeMode} onCheckedChange={(checked) => setTreeMode(checked)} />
|
||||||
</div>
|
</div>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
|
|
@ -72,7 +72,7 @@ const TagsSection = observer((props: Props) => {
|
||||||
{tags.map(([tag, amount]) => (
|
{tags.map(([tag, amount]) => (
|
||||||
<div
|
<div
|
||||||
key={tag}
|
key={tag}
|
||||||
className="shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-gray-600 dark:text-gray-400 dark:border-zinc-800"
|
className="shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-muted-foreground"
|
||||||
>
|
>
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
|
|
@ -85,14 +85,14 @@ const TagsSection = observer((props: Props) => {
|
||||||
<div className="flex flex-col text-sm gap-0.5">
|
<div className="flex flex-col text-sm gap-0.5">
|
||||||
<button
|
<button
|
||||||
onClick={() => showRenameTagDialog({ tag: tag })}
|
onClick={() => showRenameTagDialog({ tag: tag })}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<Edit3Icon className="w-4 h-auto" />
|
<Edit3Icon className="w-4 h-auto" />
|
||||||
{t("common.rename")}
|
{t("common.rename")}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDeleteTag(tag)}
|
onClick={() => handleDeleteTag(tag)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-destructive hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-4 h-auto" />
|
<TrashIcon className="w-4 h-auto" />
|
||||||
{t("common.delete")}
|
{t("common.delete")}
|
||||||
|
|
@ -104,7 +104,7 @@ const TagsSection = observer((props: Props) => {
|
||||||
className={cn("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}
|
className={cn("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}
|
||||||
onClick={() => handleTagClick(tag)}
|
onClick={() => handleTagClick(tag)}
|
||||||
>
|
>
|
||||||
<span className="truncate dark:opacity-80">{tag}</span>
|
<span className="truncate opacity-80">{tag}</span>
|
||||||
{amount > 1 && <span className="opacity-60 shrink-0">({amount})</span>}
|
{amount > 1 && <span className="opacity-60 shrink-0">({amount})</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -113,7 +113,7 @@ const TagsSection = observer((props: Props) => {
|
||||||
)
|
)
|
||||||
) : (
|
) : (
|
||||||
!props.readonly && (
|
!props.readonly && (
|
||||||
<div className="p-2 border border-dashed border-zinc-200 dark:border-zinc-800 rounded-md flex flex-row justify-start items-start gap-1 text-gray-400 dark:text-gray-500">
|
<div className="p-2 border border-dashed rounded-md flex flex-row justify-start items-start gap-1 text-muted-foreground">
|
||||||
<TagsIcon />
|
<TagsIcon />
|
||||||
<p className="mt-0.5 text-sm leading-snug italic">{t("tag.create-tags-guide")}</p>
|
<p className="mt-0.5 text-sm leading-snug italic">{t("tag.create-tags-guide")}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
|
||||||
className={cn(
|
className={cn(
|
||||||
"shrink-0 mt-2 p-2 rounded-full border",
|
"shrink-0 mt-2 p-2 rounded-full border",
|
||||||
inbox.status === Inbox_Status.UNREAD
|
inbox.status === Inbox_Status.UNREAD
|
||||||
? "border-blue-600 text-blue-600 bg-blue-50 dark:bg-zinc-800"
|
? "border-primary text-primary bg-primary/10"
|
||||||
: "border-gray-500 text-gray-500 bg-gray-50 dark:bg-zinc-800",
|
: "border-muted-foreground text-muted-foreground bg-secondary",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
|
|
@ -92,21 +92,21 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 dark:border-zinc-700 hover:bg-gray-100 dark:hover:bg-zinc-700",
|
"border w-full p-2 px-3 rounded-lg flex flex-col justify-start items-start gap-1 border-border hover:bg-secondary",
|
||||||
inbox.status !== Inbox_Status.UNREAD && "opacity-60",
|
inbox.status !== Inbox_Status.UNREAD && "opacity-60",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{initialized ? (
|
{initialized ? (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-sm text-gray-500">{inbox.createTime?.toLocaleString()}</span>
|
<span className="text-sm text-muted-foreground">{inbox.createTime?.toLocaleString()}</span>
|
||||||
<div>
|
<div>
|
||||||
{inbox.status === Inbox_Status.UNREAD && (
|
{inbox.status === Inbox_Status.UNREAD && (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger>
|
||||||
<InboxIcon
|
<InboxIcon
|
||||||
className="w-4 h-auto cursor-pointer text-gray-400 hover:text-blue-600"
|
className="w-4 h-auto cursor-pointer text-muted-foreground hover:text-primary"
|
||||||
onClick={() => handleArchiveMessage()}
|
onClick={() => handleArchiveMessage()}
|
||||||
/>
|
/>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
@ -119,7 +119,7 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p
|
<p
|
||||||
className="text-base leading-tight cursor-pointer text-gray-500 dark:text-gray-400 hover:underline hover:text-blue-600"
|
className="text-base leading-tight cursor-pointer text-muted-foreground hover:underline hover:text-primary"
|
||||||
onClick={handleNavigateToMemo}
|
onClick={handleNavigateToMemo}
|
||||||
>
|
>
|
||||||
{t("inbox.memo-comment", {
|
{t("inbox.memo-comment", {
|
||||||
|
|
@ -131,7 +131,7 @@ const MemoCommentMessage = observer(({ inbox }: Props) => {
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full flex flex-row justify-center items-center my-2">
|
<div className="w-full flex flex-row justify-center items-center my-2">
|
||||||
<LoaderIcon className="animate-spin text-zinc-500" />
|
<LoaderIcon className="animate-spin text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const LearnMore: React.FC<Props> = (props: Props) => {
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<a className={`text-gray-500 dark:text-gray-400 hover:text-blue-600 ${className}`} href={url} target="_blank">
|
<a className={`text-muted-foreground hover:text-primary ${className}`} href={url} target="_blank">
|
||||||
<ExternalLinkIcon className="w-4 h-auto" />
|
<ExternalLinkIcon className="w-4 h-auto" />
|
||||||
</a>
|
</a>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<span className={cn("flex justify-center items-center rounded-full hover:opacity-70 cursor-pointer", props.className)}>
|
<span className={cn("flex justify-center items-center rounded-full hover:opacity-70 cursor-pointer", props.className)}>
|
||||||
<MoreVerticalIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
<MoreVerticalIcon className="w-4 h-4 mx-auto text-muted-foreground" />
|
||||||
</span>
|
</span>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent align="end" sideOffset={2}>
|
<PopoverContent align="end" sideOffset={2}>
|
||||||
|
|
@ -176,7 +176,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
{!isComment && (
|
{!isComment && (
|
||||||
<button
|
<button
|
||||||
onClick={handleTogglePinMemoBtnClick}
|
onClick={handleTogglePinMemoBtnClick}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
{memo.pinned ? <BookmarkMinusIcon className="w-4 h-auto" /> : <BookmarkPlusIcon className="w-4 h-auto" />}
|
{memo.pinned ? <BookmarkMinusIcon className="w-4 h-auto" /> : <BookmarkPlusIcon className="w-4 h-auto" />}
|
||||||
{memo.pinned ? t("common.unpin") : t("common.pin")}
|
{memo.pinned ? t("common.unpin") : t("common.pin")}
|
||||||
|
|
@ -184,7 +184,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={handleEditMemoClick}
|
onClick={handleEditMemoClick}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<Edit3Icon className="w-4 h-auto" />
|
<Edit3Icon className="w-4 h-auto" />
|
||||||
{t("common.edit")}
|
{t("common.edit")}
|
||||||
|
|
@ -192,10 +192,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!isArchived && (
|
{!isArchived && (
|
||||||
<button
|
<button onClick={handleCopyLink} className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded">
|
||||||
onClick={handleCopyLink}
|
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
|
||||||
>
|
|
||||||
<CopyIcon className="w-4 h-auto" />
|
<CopyIcon className="w-4 h-auto" />
|
||||||
{t("memo.copy-link")}
|
{t("memo.copy-link")}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -205,7 +202,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
{!isArchived && !isComment && hasCompletedTaskList && (
|
{!isArchived && !isComment && hasCompletedTaskList && (
|
||||||
<button
|
<button
|
||||||
onClick={handleRemoveCompletedTaskListItemsClick}
|
onClick={handleRemoveCompletedTaskListItemsClick}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left text-amber-600 dark:text-amber-400 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-primary hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<SquareCheckIcon className="w-4 h-auto" />
|
<SquareCheckIcon className="w-4 h-auto" />
|
||||||
{t("memo.remove-completed-task-list-items")}
|
{t("memo.remove-completed-task-list-items")}
|
||||||
|
|
@ -214,7 +211,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
{!isComment && (
|
{!isComment && (
|
||||||
<button
|
<button
|
||||||
onClick={handleToggleMemoStatusClick}
|
onClick={handleToggleMemoStatusClick}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left text-amber-600 dark:text-amber-400 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-primary hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
{isArchived ? <ArchiveRestoreIcon className="w-4 h-auto" /> : <ArchiveIcon className="w-4 h-auto" />}
|
{isArchived ? <ArchiveRestoreIcon className="w-4 h-auto" /> : <ArchiveIcon className="w-4 h-auto" />}
|
||||||
{isArchived ? t("common.restore") : t("common.archive")}
|
{isArchived ? t("common.restore") : t("common.archive")}
|
||||||
|
|
@ -222,7 +219,7 @@ const MemoActionMenu = observer((props: Props) => {
|
||||||
)}
|
)}
|
||||||
<button
|
<button
|
||||||
onClick={handleDeleteMemoClick}
|
onClick={handleDeleteMemoClick}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-destructive hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<TrashIcon className="w-4 h-auto" />
|
<TrashIcon className="w-4 h-auto" />
|
||||||
{t("common.delete")}
|
{t("common.delete")}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const MemoAttachment: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`w-auto flex flex-row justify-start items-center text-gray-500 dark:text-gray-400 hover:opacity-80 ${className}`}>
|
<div className={`w-auto flex flex-row justify-start items-center text-muted-foreground hover:opacity-80 ${className}`}>
|
||||||
{attachment.type.startsWith("audio") ? (
|
{attachment.type.startsWith("audio") ? (
|
||||||
<audio src={attachmentUrl} controls></audio>
|
<audio src={attachmentUrl} controls></audio>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const MemoAttachmentListView = ({ attachments = [] }: { attachments: Attachment[
|
||||||
return (
|
return (
|
||||||
<img
|
<img
|
||||||
className={cn(
|
className={cn(
|
||||||
"cursor-pointer h-full w-auto rounded-lg border border-zinc-200 dark:border-zinc-800 object-contain hover:opacity-80",
|
"cursor-pointer h-full w-auto rounded-lg border border-border object-contain hover:opacity-80",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
src={attachment.externalLink ? attachmentUrl : attachmentUrl + "?thumbnail=true"}
|
src={attachment.externalLink ? attachmentUrl : attachmentUrl + "?thumbnail=true"}
|
||||||
|
|
@ -48,7 +48,7 @@ const MemoAttachmentListView = ({ attachments = [] }: { attachments: Attachment[
|
||||||
return (
|
return (
|
||||||
<video
|
<video
|
||||||
className={cn(
|
className={cn(
|
||||||
"cursor-pointer h-full w-auto rounded-lg border border-zinc-200 dark:border-zinc-800 object-contain bg-zinc-100 dark:bg-zinc-800",
|
"cursor-pointer h-full w-auto rounded-lg border border-border object-contain bg-secondary",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
preload="metadata"
|
preload="metadata"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ interface Props extends BaseProps {
|
||||||
|
|
||||||
const Blockquote: React.FC<Props> = ({ children }: Props) => {
|
const Blockquote: React.FC<Props> = ({ children }: Props) => {
|
||||||
return (
|
return (
|
||||||
<blockquote className="p-2 border-s-4 rounded border-gray-300 bg-gray-50 dark:border-gray-500 dark:bg-zinc-700">
|
<blockquote className="p-2 border-s-4 rounded border-muted bg-muted">
|
||||||
{children.map((child, index) => (
|
{children.map((child, index) => (
|
||||||
<Renderer key={`${child.type}-${index}`} index={String(index)} node={child} />
|
<Renderer key={`${child.type}-${index}`} index={String(index)} node={child} />
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Code: React.FC<Props> = ({ content }: Props) => {
|
const Code: React.FC<Props> = ({ content }: Props) => {
|
||||||
return <code className="inline break-all px-1 font-mono text-sm rounded opacity-80 bg-gray-100 dark:bg-zinc-700">{content}</code>;
|
return <code className="inline break-all px-1 font-mono text-sm rounded opacity-80 bg-muted">{content}</code>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Code;
|
export default Code;
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,14 @@ const CodeBlock: React.FC<Props> = ({ language, content }: Props) => {
|
||||||
}, [content]);
|
}, [content]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full my-1 bg-amber-100 border-l-4 border-amber-400 rounded hover:shadow dark:bg-zinc-600 dark:border-zinc-400 relative">
|
<div className="w-full my-1 bg-accent/10 border-l-4 border-accent rounded hover:shadow relative">
|
||||||
<div className="w-full px-2 py-1 flex flex-row justify-between items-center text-amber-500 dark:text-zinc-400">
|
<div className="w-full px-2 py-1 flex flex-row justify-between items-center text-accent-foreground">
|
||||||
<span className="text-sm font-mono">{formatedLanguage}</span>
|
<span className="text-sm font-mono">{formatedLanguage}</span>
|
||||||
<CopyIcon className="w-4 h-auto cursor-pointer hover:opacity-80" onClick={handleCopyButtonClick} />
|
<CopyIcon className="w-4 h-auto cursor-pointer hover:opacity-80" onClick={handleCopyButtonClick} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="overflow-auto">
|
<div className="overflow-auto">
|
||||||
<pre className={cn("no-wrap overflow-auto", "w-full p-2 bg-amber-50 dark:bg-zinc-700 relative")}>
|
<pre className={cn("no-wrap overflow-auto", "w-full p-2 bg-accent/5 relative")}>
|
||||||
<code
|
<code
|
||||||
className={cn(`language-${formatedLanguage}`, "block text-sm leading-5")}
|
className={cn(`language-${formatedLanguage}`, "block text-sm leading-5")}
|
||||||
dangerouslySetInnerHTML={{ __html: highlightedCode }}
|
dangerouslySetInnerHTML={{ __html: highlightedCode }}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ const EmbeddedMemo = observer(({ resourceId: uid, params: paramsStr }: Props) =>
|
||||||
// Add the memo to the set of embedded memos. This is used to prevent infinite loops when a memo embeds itself.
|
// Add the memo to the set of embedded memos. This is used to prevent infinite loops when a memo embeds itself.
|
||||||
context.embeddedMemos.add(memoName);
|
context.embeddedMemos.add(memoName);
|
||||||
const contentNode = useSnippet ? (
|
const contentNode = useSnippet ? (
|
||||||
<div className={cn("text-gray-800 dark:text-gray-400", inlineMode ? "" : "line-clamp-3")}>{memo.snippet}</div>
|
<div className={cn("text-muted-foreground", inlineMode ? "" : "line-clamp-3")}>{memo.snippet}</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<MemoContent
|
<MemoContent
|
||||||
|
|
@ -67,8 +67,8 @@ const EmbeddedMemo = observer(({ resourceId: uid, params: paramsStr }: Props) =>
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col justify-start items-start w-full px-3 py-2 bg-zinc-50 dark:bg-zinc-900 rounded-lg border border-zinc-200 dark:border-zinc-700 hover:shadow">
|
<div className="relative flex flex-col justify-start items-start w-full px-3 py-2 bg-secondary rounded-lg border border-border hover:shadow">
|
||||||
<div className="w-full mb-1 flex flex-row justify-between items-center text-gray-400 dark:text-gray-500">
|
<div className="w-full mb-1 flex flex-row justify-between items-center text-muted-foreground">
|
||||||
<div className="text-sm leading-5 select-none">
|
<div className="text-sm leading-5 select-none">
|
||||||
<relative-time datetime={memo.displayTime?.toISOString()} format="datetime"></relative-time>
|
<relative-time datetime={memo.displayTime?.toISOString()} format="datetime"></relative-time>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Error = ({ message }: Props) => {
|
const Error = ({ message }: Props) => {
|
||||||
return <p className="font-mono text-sm text-red-600 dark:text-red-700">{message}</p>;
|
return <p className="font-mono text-sm text-destructive">{message}</p>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Error;
|
export default Error;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ const Link: React.FC<Props> = ({ content, url }: Props) => {
|
||||||
<Tooltip open={showTooltip}>
|
<Tooltip open={showTooltip}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<a
|
<a
|
||||||
className="underline text-blue-600 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-300"
|
className="underline text-primary hover:text-primary/80"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={url}
|
href={url}
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
|
@ -62,7 +62,7 @@ const Link: React.FC<Props> = ({ content, url }: Props) => {
|
||||||
<div className="w-full flex flex-col">
|
<div className="w-full flex flex-col">
|
||||||
<div className="w-full flex flex-row justify-start items-center gap-1">
|
<div className="w-full flex flex-row justify-start items-center gap-1">
|
||||||
<img className="w-5 h-5 rounded" src={getFaviconWithGoogleS2(url)} alt={linkMetadata?.title} />
|
<img className="w-5 h-5 rounded" src={getFaviconWithGoogleS2(url)} alt={linkMetadata?.title} />
|
||||||
<h3 className="text-base truncate dark:opacity-90">{linkMetadata?.title}</h3>
|
<h3 className="text-base truncate">{linkMetadata?.title}</h3>
|
||||||
</div>
|
</div>
|
||||||
{linkMetadata.description && (
|
{linkMetadata.description && (
|
||||||
<p className="mt-1 w-full text-sm leading-snug opacity-80 line-clamp-3">{linkMetadata.description}</p>
|
<p className="mt-1 w-full text-sm leading-snug opacity-80 line-clamp-3">{linkMetadata.description}</p>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ interface Props {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Error = ({ message }: Props) => {
|
const Error = ({ message }: Props) => {
|
||||||
return <p className="font-mono text-sm text-red-600 dark:text-red-700">{message}</p>;
|
return <p className="font-mono text-sm text-destructive">{message}</p>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Error;
|
export default Error;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const ReferencedMemo = observer(({ resourceId: uid, params: paramsStr }: Props)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className="text-blue-600 whitespace-nowrap dark:text-blue-400 cursor-pointer underline break-all hover:opacity-80 decoration-1"
|
className="text-primary whitespace-nowrap cursor-pointer underline break-all hover:opacity-80 decoration-1"
|
||||||
onClick={handleGotoMemoDetailPage}
|
onClick={handleGotoMemoDetailPage}
|
||||||
>
|
>
|
||||||
{displayContent}
|
{displayContent}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const Spoiler: React.FC<Props> = ({ content }: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className={cn("inline cursor-pointer select-none", isRevealed ? "" : "bg-gray-200 dark:bg-zinc-700")}
|
className={cn("inline cursor-pointer select-none", isRevealed ? "" : "bg-muted")}
|
||||||
onClick={() => setIsRevealed(!isRevealed)}
|
onClick={() => setIsRevealed(!isRevealed)}
|
||||||
>
|
>
|
||||||
<span className={cn(isRevealed ? "opacity-100" : "opacity-0")}>{content}</span>
|
<span className={cn(isRevealed ? "opacity-100" : "opacity-0")}>{content}</span>
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@ interface Props {
|
||||||
|
|
||||||
const Table = ({ header, rows }: Props) => {
|
const Table = ({ header, rows }: Props) => {
|
||||||
return (
|
return (
|
||||||
<table className="w-auto max-w-full border border-zinc-200 dark:border-zinc-600 divide-y divide-zinc-200 dark:divide-zinc-600">
|
<table className="w-auto max-w-full border border-border divide-y divide-border">
|
||||||
<thead className="text-sm font-medium leading-5 text-left text-gray-900 dark:text-gray-400">
|
<thead className="text-sm font-medium leading-5 text-left text-foreground">
|
||||||
<tr className="divide-x divide-zinc-200 dark:divide-zinc-600">
|
<tr className="divide-x divide-border">
|
||||||
{header.map((h, i) => (
|
{header.map((h, i) => (
|
||||||
<th key={i} className="py-1 px-2">
|
<th key={i} className="py-1 px-2">
|
||||||
<Renderer key={`${h.type}-${i}`} index={String(i)} node={h} />
|
<Renderer key={`${h.type}-${i}`} index={String(i)} node={h} />
|
||||||
|
|
@ -19,9 +19,9 @@ const Table = ({ header, rows }: Props) => {
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-zinc-200 dark:divide-zinc-600 text-sm leading-5 text-left text-gray-900 dark:text-gray-400">
|
<tbody className="divide-y divide-border text-sm leading-5 text-left text-foreground">
|
||||||
{rows.map((row, i) => (
|
{rows.map((row, i) => (
|
||||||
<tr key={i} className="divide-x divide-zinc-200 dark:divide-zinc-600">
|
<tr key={i} className="divide-x divide-border">
|
||||||
{row.cells.map((r, j) => (
|
{row.cells.map((r, j) => (
|
||||||
<td key={j} className="py-1 px-2">
|
<td key={j} className="py-1 px-2">
|
||||||
<Renderer key={`${r.type}-${i}-${j}`} index={String(j)} node={r} />
|
<Renderer key={`${r.type}-${i}-${j}`} index={String(j)} node={r} />
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ const Tag = observer(({ content }: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className={cn("inline-block w-auto text-blue-600 dark:text-blue-400", context.disableFilter ? "" : "cursor-pointer hover:opacity-80")}
|
className={cn("inline-block w-auto text-primary", context.disableFilter ? "" : "cursor-pointer hover:opacity-80")}
|
||||||
onClick={handleTagClick}
|
onClick={handleTagClick}
|
||||||
>
|
>
|
||||||
#{content}
|
#{content}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ const MemoContent = observer((props: Props) => {
|
||||||
parentPage: props.parentPage,
|
parentPage: props.parentPage,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={`w-full flex flex-col justify-start items-start text-gray-800 dark:text-gray-400 ${className || ""}`}>
|
<div className={`w-full flex flex-col justify-start items-start text-foreground ${className || ""}`}>
|
||||||
<div
|
<div
|
||||||
ref={memoContentContainerRef}
|
ref={memoContentContainerRef}
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|
@ -104,13 +104,13 @@ const MemoContent = observer((props: Props) => {
|
||||||
return <Renderer key={`${node.type}-${index}`} index={String(index)} node={node} />;
|
return <Renderer key={`${node.type}-${index}`} index={String(index)} node={node} />;
|
||||||
})}
|
})}
|
||||||
{showCompactMode == "ALL" && (
|
{showCompactMode == "ALL" && (
|
||||||
<div className="absolute bottom-0 left-0 w-full h-12 bg-linear-to-b from-transparent dark:to-zinc-800 to-white pointer-events-none"></div>
|
<div className="absolute bottom-0 left-0 w-full h-12 bg-linear-to-b from-transparent to-background pointer-events-none"></div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{showCompactMode != undefined && (
|
{showCompactMode != undefined && (
|
||||||
<div className="w-full mt-1">
|
<div className="w-full mt-1">
|
||||||
<span
|
<span
|
||||||
className="w-auto flex flex-row justify-start items-center cursor-pointer text-sm text-blue-600 dark:text-blue-400 hover:opacity-80"
|
className="w-auto flex flex-row justify-start items-center cursor-pointer text-sm text-primary hover:opacity-80"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setShowCompactMode(compactStates[showCompactMode].nextState as ContentCompactView);
|
setShowCompactMode(compactStates[showCompactMode].nextState as ContentCompactView);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||||
>
|
>
|
||||||
<div className="flex flex-col justify-start items-start w-full px-1 gap-2 h-auto shrink-0 flex-nowrap hide-scrollbar">
|
<div className="flex flex-col justify-start items-start w-full px-1 gap-2 h-auto shrink-0 flex-nowrap hide-scrollbar">
|
||||||
{shouldShowRelationGraph && (
|
{shouldShowRelationGraph && (
|
||||||
<div className="relative w-full h-36 border border-zinc-200 rounded-lg bg-zinc-50 dark:bg-zinc-900 dark:border-zinc-800">
|
<div className="relative w-full h-36 border border-border rounded-lg bg-muted">
|
||||||
<MemoRelationForceGraph className="w-full h-full" memo={memo} parentPage={parentPage} />
|
<MemoRelationForceGraph className="w-full h-full" memo={memo} parentPage={parentPage} />
|
||||||
<div className="absolute top-1 left-2 text-xs opacity-60 font-mono gap-1 flex flex-row items-center">
|
<div className="absolute top-1 left-2 text-xs opacity-60 font-mono gap-1 flex flex-row items-center">
|
||||||
<span>{t("common.relations")}</span>
|
<span>{t("common.relations")}</span>
|
||||||
|
|
@ -32,27 +32,27 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="w-full flex flex-col">
|
<div className="w-full flex flex-col">
|
||||||
<p className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-gray-400 dark:text-gray-500 select-none">
|
<p className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-muted-foreground select-none">
|
||||||
<span>{t("common.created-at")}</span>
|
<span>{t("common.created-at")}</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-400">{memo.createTime?.toLocaleString()}</p>
|
<p className="text-sm text-muted-foreground">{memo.createTime?.toLocaleString()}</p>
|
||||||
</div>
|
</div>
|
||||||
{!isEqual(memo.createTime, memo.updateTime) && (
|
{!isEqual(memo.createTime, memo.updateTime) && (
|
||||||
<div className="w-full flex flex-col">
|
<div className="w-full flex flex-col">
|
||||||
<p className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-gray-400 dark:text-gray-500 select-none">
|
<p className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-muted-foreground select-none">
|
||||||
<span>{t("common.last-updated-at")}</span>
|
<span>{t("common.last-updated-at")}</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gray-500 dark:text-gray-400">{memo.updateTime?.toLocaleString()}</p>
|
<p className="text-sm text-muted-foreground">{memo.updateTime?.toLocaleString()}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{hasSpecialProperty && (
|
{hasSpecialProperty && (
|
||||||
<div className="w-full flex flex-col">
|
<div className="w-full flex flex-col">
|
||||||
<p className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-gray-400 dark:text-gray-500 select-none">
|
<p className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-muted-foreground select-none">
|
||||||
<span>{t("common.properties")}</span>
|
<span>{t("common.properties")}</span>
|
||||||
</p>
|
</p>
|
||||||
<div className="w-full flex flex-row justify-start items-center gap-x-2 gap-y-1 flex-wrap text-gray-500 dark:text-gray-400">
|
<div className="w-full flex flex-row justify-start items-center gap-x-2 gap-y-1 flex-wrap text-muted-foreground">
|
||||||
{property.hasLink && (
|
{property.hasLink && (
|
||||||
<div className="w-auto border border-zinc-200 dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
<div className="w-auto border border-border pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
||||||
<div className="w-auto flex justify-start items-center mr-1">
|
<div className="w-auto flex justify-start items-center mr-1">
|
||||||
<LinkIcon className="w-4 h-auto mr-1" />
|
<LinkIcon className="w-4 h-auto mr-1" />
|
||||||
<span className="block text-sm">{t("memo.links")}</span>
|
<span className="block text-sm">{t("memo.links")}</span>
|
||||||
|
|
@ -60,7 +60,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{property.hasTaskList && (
|
{property.hasTaskList && (
|
||||||
<div className="w-auto border border-zinc-200 dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
<div className="w-auto border border-border pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
||||||
<div className="w-auto flex justify-start items-center mr-1">
|
<div className="w-auto flex justify-start items-center mr-1">
|
||||||
<CheckCircleIcon className="w-4 h-auto mr-1" />
|
<CheckCircleIcon className="w-4 h-auto mr-1" />
|
||||||
<span className="block text-sm">{t("memo.to-do")}</span>
|
<span className="block text-sm">{t("memo.to-do")}</span>
|
||||||
|
|
@ -68,7 +68,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{property.hasCode && (
|
{property.hasCode && (
|
||||||
<div className="w-auto border border-zinc-200 dark:border-zinc-800 pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
<div className="w-auto border border-border pl-1 pr-1.5 rounded-md flex justify-between items-center">
|
||||||
<div className="w-auto flex justify-start items-center mr-1">
|
<div className="w-auto flex justify-start items-center mr-1">
|
||||||
<Code2Icon className="w-4 h-auto mr-1" />
|
<Code2Icon className="w-4 h-auto mr-1" />
|
||||||
<span className="block text-sm">{t("memo.code")}</span>
|
<span className="block text-sm">{t("memo.code")}</span>
|
||||||
|
|
@ -80,7 +80,7 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||||
)}
|
)}
|
||||||
{memo.tags.length > 0 && (
|
{memo.tags.length > 0 && (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-gray-400 dark:text-gray-500 select-none">
|
<div className="flex flex-row justify-start items-center w-full gap-1 mb-1 text-sm leading-6 text-muted-foreground select-none">
|
||||||
<span>{t("common.tags")}</span>
|
<span>{t("common.tags")}</span>
|
||||||
<span className="shrink-0">({memo.tags.length})</span>
|
<span className="shrink-0">({memo.tags.length})</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -88,11 +88,11 @@ const MemoDetailSidebar = ({ memo, className, parentPage }: Props) => {
|
||||||
{memo.tags.map((tag) => (
|
{memo.tags.map((tag) => (
|
||||||
<div
|
<div
|
||||||
key={tag}
|
key={tag}
|
||||||
className="shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-gray-600 dark:text-gray-400 dark:border-zinc-800"
|
className="shrink-0 w-auto max-w-full text-sm rounded-md leading-6 flex flex-row justify-start items-center select-none hover:opacity-80 text-muted-foreground"
|
||||||
>
|
>
|
||||||
<HashIcon className="group-hover:hidden w-4 h-auto shrink-0 opacity-40" />
|
<HashIcon className="group-hover:hidden w-4 h-auto shrink-0 opacity-40" />
|
||||||
<div className={cn("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}>
|
<div className={cn("inline-flex flex-nowrap ml-0.5 gap-0.5 cursor-pointer max-w-[calc(100%-16px)]")}>
|
||||||
<span className="truncate dark:opacity-80">{tag}</span>
|
<span className="truncate opacity-80">{tag}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,10 @@ const MemoDetailSidebarDrawer = ({ memo, parentPage }: Props) => {
|
||||||
<Sheet open={open} onOpenChange={setOpen}>
|
<Sheet open={open} onOpenChange={setOpen}>
|
||||||
<SheetTrigger asChild>
|
<SheetTrigger asChild>
|
||||||
<Button variant="ghost" className="bg-transparent! px-2">
|
<Button variant="ghost" className="bg-transparent! px-2">
|
||||||
<GanttChartIcon className="w-5 h-auto dark:text-gray-400" />
|
<GanttChartIcon className="w-5 h-auto text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
<SheetContent side="right" className="w-full sm:w-80 px-4 bg-zinc-100 dark:bg-zinc-900">
|
<SheetContent side="right" className="w-full sm:w-80 px-4 bg-secondary">
|
||||||
<MemoDetailSidebar className="py-4" memo={memo} parentPage={parentPage} />
|
<MemoDetailSidebar className="py-4" memo={memo} parentPage={parentPage} />
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,13 @@ const MemoDisplaySettingMenu = observer(({ className }: Props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger
|
<PopoverTrigger className={cn(className, isApplying ? "text-primary bg-primary/10 rounded" : "opacity-40")}>
|
||||||
className={cn(className, isApplying ? "text-teal-600 bg-teal-100 dark:text-teal-500 dark:bg-teal-900 rounded" : "opacity-40")}
|
|
||||||
>
|
|
||||||
<Settings2Icon className="w-4 h-auto shrink-0" />
|
<Settings2Icon className="w-4 h-auto shrink-0" />
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent align="end" alignOffset={-12} sideOffset={14}>
|
<PopoverContent align="end" alignOffset={-12} sideOffset={14}>
|
||||||
<div className="flex flex-col gap-2 p-1">
|
<div className="flex flex-col gap-2 p-1">
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-sm shrink-0 mr-3 dark:text-zinc-400">{t("memo.direction")}</span>
|
<span className="text-sm shrink-0 mr-3 text-foreground">{t("memo.direction")}</span>
|
||||||
<Select
|
<Select
|
||||||
value={viewStore.state.orderByTimeAsc.toString()}
|
value={viewStore.state.orderByTimeAsc.toString()}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
|
|
@ -43,7 +41,7 @@ const MemoDisplaySettingMenu = observer(({ className }: Props) => {
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-sm shrink-0 mr-3 dark:text-zinc-400">{t("common.layout")}</span>
|
<span className="text-sm shrink-0 mr-3 text-foreground">{t("common.layout")}</span>
|
||||||
<Select
|
<Select
|
||||||
value={viewStore.state.layout}
|
value={viewStore.state.layout}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
|
|
|
||||||
|
|
@ -144,11 +144,11 @@ const AddMemoRelationPopover = (props: Props) => {
|
||||||
{selectedMemos.map((memo) => (
|
{selectedMemos.map((memo) => (
|
||||||
<Badge key={memo.name} variant="outline" className="max-w-full flex items-center gap-1 p-2">
|
<Badge key={memo.name} variant="outline" className="max-w-full flex items-center gap-1 p-2">
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<p className="text-xs text-gray-400 select-none">{memo.displayTime?.toLocaleString()}</p>
|
<p className="text-xs text-muted-foreground select-none">{memo.displayTime?.toLocaleString()}</p>
|
||||||
<span className="text-sm leading-5 truncate block">{memo.content}</span>
|
<span className="text-sm leading-5 truncate block">{memo.content}</span>
|
||||||
</div>
|
</div>
|
||||||
<X
|
<X
|
||||||
className="w-3 h-3 cursor-pointer hover:text-red-500 flex-shrink-0"
|
className="w-3 h-3 cursor-pointer hover:text-destructive flex-shrink-0"
|
||||||
onClick={() => setSelectedMemos((memos) => memos.filter((m) => m.name !== memo.name))}
|
onClick={() => setSelectedMemos((memos) => memos.filter((m) => m.name !== memo.name))}
|
||||||
/>
|
/>
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
@ -166,7 +166,7 @@ const AddMemoRelationPopover = (props: Props) => {
|
||||||
/>
|
/>
|
||||||
<div className="max-h-[200px] overflow-y-auto">
|
<div className="max-h-[200px] overflow-y-auto">
|
||||||
{filteredMemos.length === 0 ? (
|
{filteredMemos.length === 0 ? (
|
||||||
<div className="py-6 text-center text-sm text-gray-500">{isFetching ? "Loading..." : t("reference.no-memos-found")}</div>
|
<div className="py-6 text-center text-sm text-muted-foreground">{isFetching ? "Loading..." : t("reference.no-memos-found")}</div>
|
||||||
) : (
|
) : (
|
||||||
filteredMemos.map((memo) => (
|
filteredMemos.map((memo) => (
|
||||||
<div
|
<div
|
||||||
|
|
@ -177,7 +177,7 @@ const AddMemoRelationPopover = (props: Props) => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="w-full flex flex-col justify-start items-start">
|
<div className="w-full flex flex-col justify-start items-start">
|
||||||
<p className="text-xs text-gray-400 select-none">{memo.displayTime?.toLocaleString()}</p>
|
<p className="text-xs text-muted-foreground select-none">{memo.displayTime?.toLocaleString()}</p>
|
||||||
<p className="mt-0.5 text-sm leading-5 line-clamp-2">
|
<p className="mt-0.5 text-sm leading-5 line-clamp-2">
|
||||||
{searchText ? getHighlightedContent(memo.content) : memo.snippet}
|
{searchText ? getHighlightedContent(memo.content) : memo.snippet}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -70,21 +70,21 @@ const MarkdownMenu = (props: Props) => {
|
||||||
<div className="flex flex-col text-sm gap-0.5">
|
<div className="flex flex-col text-sm gap-0.5">
|
||||||
<button
|
<button
|
||||||
onClick={handleCodeBlockClick}
|
onClick={handleCodeBlockClick}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-secondary outline-none rounded"
|
||||||
>
|
>
|
||||||
<Code2Icon className="w-4 h-auto" />
|
<Code2Icon className="w-4 h-auto" />
|
||||||
<span>{t("markdown.code-block")}</span>
|
<span>{t("markdown.code-block")}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={handleCheckboxClick}
|
onClick={handleCheckboxClick}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-secondary outline-none rounded"
|
||||||
>
|
>
|
||||||
<CheckSquareIcon className="w-4 h-auto" />
|
<CheckSquareIcon className="w-4 h-auto" />
|
||||||
<span>{t("markdown.checkbox")}</span>
|
<span>{t("markdown.checkbox")}</span>
|
||||||
</button>
|
</button>
|
||||||
<div className="pl-2">
|
<div className="pl-2">
|
||||||
<a
|
<a
|
||||||
className="text-xs text-blue-600 hover:underline"
|
className="text-xs text-primary hover:underline"
|
||||||
href="https://www.usememos.com/docs/getting-started/content-syntax"
|
href="https://www.usememos.com/docs/getting-started/content-syntax"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const TagSelector = observer((props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={tag}
|
key={tag}
|
||||||
className="inline-flex w-auto max-w-full cursor-pointer text-base leading-6 text-gray-500 dark:text-gray-400 hover:opacity-80"
|
className="inline-flex w-auto max-w-full cursor-pointer text-base leading-6 text-muted-foreground hover:opacity-80"
|
||||||
onClick={() => handleTagClick(tag)}
|
onClick={() => handleTagClick(tag)}
|
||||||
>
|
>
|
||||||
<OverflowTip>#{tag}</OverflowTip>
|
<OverflowTip>#{tag}</OverflowTip>
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,14 @@ const VisibilitySelector = (props: Props) => {
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button
|
<button
|
||||||
className={cn(
|
className={cn(
|
||||||
`flex items-center justify-center gap-1 px-0.5 text-xs rounded hover:bg-gray-100 dark:hover:bg-zinc-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1 transition-colors`,
|
`flex items-center justify-center gap-1 px-0.5 text-xs rounded hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 transition-colors`,
|
||||||
props.className,
|
props.className,
|
||||||
)}
|
)}
|
||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<VisibilityIcon className="w-3 h-3" visibility={value} />
|
<VisibilityIcon className="w-3 h-3" visibility={value} />
|
||||||
<span className="dark:text-zinc-300">{currentOption?.label}</span>
|
<span>{currentOption?.label}</span>
|
||||||
<ChevronDownIcon className="w-3 h-3 opacity-60 dark:text-zinc-300" />
|
<ChevronDownIcon className="w-3 h-3 opacity-60" />
|
||||||
</button>
|
</button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="p-1!" align="end" sideOffset={2} alignOffset={-4}>
|
<PopoverContent className="p-1!" align="end" sideOffset={2} alignOffset={-4}>
|
||||||
|
|
@ -60,8 +60,8 @@ const VisibilitySelector = (props: Props) => {
|
||||||
key={option.value}
|
key={option.value}
|
||||||
onClick={() => handleSelect(option.value)}
|
onClick={() => handleSelect(option.value)}
|
||||||
className={cn(
|
className={cn(
|
||||||
`flex items-center gap-1 px-1 py-1 text-xs text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-1 rounded transition-colors`,
|
`flex items-center gap-1 px-1 py-1 text-xs text-left hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1 rounded transition-colors`,
|
||||||
option.value === value ? "bg-gray-50 dark:bg-zinc-800" : "",
|
option.value === value ? "bg-muted" : "",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<VisibilityIcon className="w-3 h-3" visibility={option.value} />
|
<VisibilityIcon className="w-3 h-3" visibility={option.value} />
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const AttachmentListView = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={attachment.name}
|
key={attachment.name}
|
||||||
className="max-w-full w-auto flex flex-row justify-start items-center flex-nowrap gap-x-1 bg-zinc-100 dark:bg-zinc-900 px-2 py-1 rounded hover:shadow-sm text-gray-500 dark:text-gray-400"
|
className="max-w-full w-auto flex flex-row justify-start items-center flex-nowrap gap-x-1 bg-secondary px-2 py-1 rounded hover:shadow-sm text-muted-foreground"
|
||||||
>
|
>
|
||||||
<SortableItem id={attachment.name} className="flex flex-row justify-start items-center gap-x-1">
|
<SortableItem id={attachment.name} className="flex flex-row justify-start items-center gap-x-1">
|
||||||
<AttachmentIcon attachment={attachment} className="w-4! h-4! opacity-100!" />
|
<AttachmentIcon attachment={attachment} className="w-4! h-4! opacity-100!" />
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,7 @@ const TagSuggestions = observer(({ editorRef, editorActions }: Props) => {
|
||||||
if (!isVisibleRef.current || !position) return null;
|
if (!isVisibleRef.current || !position) return null;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="z-20 p-1 mt-1 -ml-2 absolute max-w-48 gap-px rounded font-mono flex flex-col justify-start items-start overflow-auto shadow bg-zinc-100 dark:bg-zinc-700"
|
className="z-20 p-1 mt-1 -ml-2 absolute max-w-48 gap-px rounded font-mono flex flex-col justify-start items-start overflow-auto shadow bg-popover"
|
||||||
style={{ left: position.left, top: position.top + position.height }}
|
style={{ left: position.left, top: position.top + position.height }}
|
||||||
>
|
>
|
||||||
{suggestionsRef.current.map((tag, i) => (
|
{suggestionsRef.current.map((tag, i) => (
|
||||||
|
|
@ -116,8 +116,8 @@ const TagSuggestions = observer(({ editorRef, editorActions }: Props) => {
|
||||||
key={tag}
|
key={tag}
|
||||||
onMouseDown={() => autocomplete(tag)}
|
onMouseDown={() => autocomplete(tag)}
|
||||||
className={cn(
|
className={cn(
|
||||||
"rounded p-1 px-2 w-full truncate text-sm dark:text-gray-300 cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800",
|
"rounded p-1 px-2 w-full truncate text-sm cursor-pointer hover:bg-accent hover:text-accent-foreground",
|
||||||
i === selected ? "bg-zinc-300 dark:bg-zinc-600" : "",
|
i === selected ? "bg-accent text-accent-foreground" : "",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<OverflowTip>#{tag}</OverflowTip>
|
<OverflowTip>#{tag}</OverflowTip>
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,7 @@ const Editor = forwardRef(function Editor(props: Props, ref: React.ForwardedRef<
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn("flex flex-col justify-start items-start relative w-full h-auto max-h-[50vh] bg-inherit dark:text-gray-300", className)}
|
className={cn("flex flex-col justify-start items-start relative w-full h-auto max-h-[50vh] bg-inherit", className)}
|
||||||
>
|
>
|
||||||
<textarea
|
<textarea
|
||||||
className="w-full h-full my-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent outline-none placeholder:opacity-70 whitespace-pre-wrap break-words"
|
className="w-full h-full my-1 text-base resize-none overflow-x-hidden overflow-y-auto bg-transparent outline-none placeholder:opacity-70 whitespace-pre-wrap break-words"
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ const RelationListView = observer((props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={memo.name}
|
key={memo.name}
|
||||||
className="w-auto max-w-xs overflow-hidden flex flex-row justify-start items-center bg-zinc-100 dark:bg-zinc-900 hover:opacity-80 rounded-md text-sm p-1 px-2 text-gray-500 dark:text-gray-400 cursor-pointer hover:line-through"
|
className="w-auto max-w-xs overflow-hidden flex flex-row justify-start items-center bg-secondary hover:opacity-80 rounded-md text-sm p-1 px-2 text-muted-foreground cursor-pointer hover:line-through"
|
||||||
onClick={() => handleDeleteRelation(memo)}
|
onClick={() => handleDeleteRelation(memo)}
|
||||||
>
|
>
|
||||||
<LinkIcon className="w-4 h-auto shrink-0 opacity-80" />
|
<LinkIcon className="w-4 h-auto shrink-0 opacity-80" />
|
||||||
|
|
|
||||||
|
|
@ -484,10 +484,8 @@ const MemoEditor = observer((props: Props) => {
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"group relative w-full flex flex-col justify-start items-start bg-white dark:bg-zinc-800 px-4 pt-3 pb-2 rounded-lg border",
|
"group relative w-full flex flex-col justify-start items-start bg-background px-4 pt-3 pb-2 rounded-lg border",
|
||||||
state.isDraggingFile
|
state.isDraggingFile ? "border-dashed border-muted-foreground cursor-copy" : "border-border cursor-auto",
|
||||||
? "border-dashed border-gray-400 dark:border-primary-400 cursor-copy"
|
|
||||||
: "border-gray-200 dark:border-zinc-700 cursor-auto",
|
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
|
|
@ -503,7 +501,7 @@ const MemoEditor = observer((props: Props) => {
|
||||||
<AttachmentListView attachmentList={state.attachmentList} setAttachmentList={handleSetAttachmentList} />
|
<AttachmentListView attachmentList={state.attachmentList} setAttachmentList={handleSetAttachmentList} />
|
||||||
<RelationListView relationList={referenceRelations} setRelationList={handleSetRelationList} />
|
<RelationListView relationList={referenceRelations} setRelationList={handleSetRelationList} />
|
||||||
<div className="relative w-full flex flex-row justify-between items-center py-1" onFocus={(e) => e.stopPropagation()}>
|
<div className="relative w-full flex flex-row justify-between items-center py-1" onFocus={(e) => e.stopPropagation()}>
|
||||||
<div className="flex flex-row justify-start items-center opacity-80 dark:opacity-60 -space-x-2">
|
<div className="flex flex-row justify-start items-center opacity-80 -space-x-2">
|
||||||
<TagSelector editorRef={editorRef} />
|
<TagSelector editorRef={editorRef} />
|
||||||
<MarkdownMenu editorRef={editorRef} />
|
<MarkdownMenu editorRef={editorRef} />
|
||||||
<UploadAttachmentButton isUploading={state.isUploadingAttachment} />
|
<UploadAttachmentButton isUploading={state.isUploadingAttachment} />
|
||||||
|
|
@ -550,7 +548,7 @@ const MemoEditor = observer((props: Props) => {
|
||||||
|
|
||||||
{/* Show memo metadata if memoName is provided */}
|
{/* Show memo metadata if memoName is provided */}
|
||||||
{memoName && (
|
{memoName && (
|
||||||
<div className="w-full -mt-1 mb-4 text-xs leading-5 px-4 opacity-60 font-mono text-gray-500 dark:text-zinc-500">
|
<div className="w-full -mt-1 mb-4 text-xs leading-5 px-4 opacity-60 font-mono text-muted-foreground">
|
||||||
<div className="grid grid-cols-[auto_1fr] gap-x-4 gap-y-0.5 items-center">
|
<div className="grid grid-cols-[auto_1fr] gap-x-4 gap-y-0.5 items-center">
|
||||||
{!isEqual(createTime, updateTime) && updateTime && (
|
{!isEqual(createTime, updateTime) && updateTime && (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,12 @@ const MemoFilters = observer(() => {
|
||||||
{filters.map((filter: MemoFilter) => (
|
{filters.map((filter: MemoFilter) => (
|
||||||
<div
|
<div
|
||||||
key={getMemoFilterKey(filter)}
|
key={getMemoFilterKey(filter)}
|
||||||
className="w-auto leading-7 h-7 shrink-0 flex flex-row items-center gap-1 bg-white dark:bg-zinc-800 border border-zinc-200 dark:border-zinc-700 pl-1.5 pr-1 rounded-md hover:line-through cursor-pointer"
|
className="w-auto leading-7 h-7 shrink-0 flex flex-row items-center gap-1 bg-background border pl-1.5 pr-1 rounded-md hover:line-through cursor-pointer"
|
||||||
onClick={() => memoFilterStore.removeFilter((f: MemoFilter) => isEqual(f, filter))}
|
onClick={() => memoFilterStore.removeFilter((f: MemoFilter) => isEqual(f, filter))}
|
||||||
>
|
>
|
||||||
<FactorIcon className="w-4 h-auto text-gray-500 dark:text-gray-400 opacity-60" factor={filter.factor} />
|
<FactorIcon className="w-4 h-auto text-muted-foreground opacity-60" factor={filter.factor} />
|
||||||
<span className="text-gray-500 dark:text-gray-400 text-sm max-w-32 truncate">{getFilterDisplayText(filter)}</span>
|
<span className="text-muted-foreground text-sm max-w-32 truncate">{getFilterDisplayText(filter)}</span>
|
||||||
<button className="text-gray-500 dark:text-gray-300 opacity-60 hover:opacity-100">
|
<button className="text-muted-foreground opacity-60 hover:opacity-100">
|
||||||
<XIcon className="w-4 h-auto" />
|
<XIcon className="w-4 h-auto" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const MemoLocationView: React.FC<Props> = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
|
<Popover open={popoverOpen} onOpenChange={setPopoverOpen}>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<p className="w-full flex flex-row gap-0.5 items-center text-gray-500">
|
<p className="w-full flex flex-row gap-0.5 items-center text-muted-foreground">
|
||||||
<MapPinIcon className="w-4 h-auto shrink-0" />
|
<MapPinIcon className="w-4 h-auto shrink-0" />
|
||||||
<span className="text-sm font-normal text-ellipsis whitespace-nowrap overflow-hidden">
|
<span className="text-sm font-normal text-ellipsis whitespace-nowrap overflow-hidden">
|
||||||
{location.placeholder ? location.placeholder : `[${location.latitude}, ${location.longitude}]`}
|
{location.placeholder ? location.placeholder : `[${location.latitude}, ${location.longitude}]`}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ const MemoRelationForceGraph = ({ className, memo, parentPage }: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={containerRef} className={cn("dark:opacity-80", className)}>
|
<div ref={containerRef} className={cn("opacity-80", className)}>
|
||||||
<ForceGraph2D
|
<ForceGraph2D
|
||||||
ref={graphRef}
|
ref={graphRef}
|
||||||
width={graphSize.width}
|
width={graphSize.width}
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,13 @@ const MemoRelationListView = (props: Props) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex flex-col justify-start items-start w-full px-2 pt-2 pb-1.5 bg-zinc-50 dark:bg-zinc-900 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
<div className="relative flex flex-col justify-start items-start w-full px-2 pt-2 pb-1.5 bg-secondary rounded-lg border border-border">
|
||||||
<div className="w-full flex flex-row justify-start items-center mb-1 gap-3 opacity-60">
|
<div className="w-full flex flex-row justify-start items-center mb-1 gap-3 opacity-60">
|
||||||
{referencingMemoList.length > 0 && (
|
{referencingMemoList.length > 0 && (
|
||||||
<button
|
<button
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500",
|
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-muted-foreground",
|
||||||
selectedTab === "referencing" && "text-gray-800 dark:text-gray-400",
|
selectedTab === "referencing" && "text-foreground",
|
||||||
)}
|
)}
|
||||||
onClick={() => setSelectedTab("referencing")}
|
onClick={() => setSelectedTab("referencing")}
|
||||||
>
|
>
|
||||||
|
|
@ -48,8 +48,8 @@ const MemoRelationListView = (props: Props) => {
|
||||||
{referencedMemoList.length > 0 && (
|
{referencedMemoList.length > 0 && (
|
||||||
<button
|
<button
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-gray-500",
|
"w-auto flex flex-row justify-start items-center text-xs gap-0.5 text-muted-foreground",
|
||||||
selectedTab === "referenced" && "text-gray-800 dark:text-gray-400",
|
selectedTab === "referenced" && "text-foreground",
|
||||||
)}
|
)}
|
||||||
onClick={() => setSelectedTab("referenced")}
|
onClick={() => setSelectedTab("referenced")}
|
||||||
>
|
>
|
||||||
|
|
@ -65,14 +65,14 @@ const MemoRelationListView = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
key={memo.name}
|
key={memo.name}
|
||||||
className="w-auto max-w-full flex flex-row justify-start items-center text-sm leading-5 text-gray-600 dark:text-gray-400 dark:border-zinc-700 dark:bg-zinc-900 hover:underline"
|
className="w-auto max-w-full flex flex-row justify-start items-center text-sm leading-5 text-muted-foreground hover:underline"
|
||||||
to={`/${memo.name}`}
|
to={`/${memo.name}`}
|
||||||
viewTransition
|
viewTransition
|
||||||
state={{
|
state={{
|
||||||
from: parentPage,
|
from: parentPage,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="text-xs opacity-60 leading-4 border border-zinc-200 font-mono px-1 rounded-full mr-1 dark:border-zinc-700">
|
<span className="text-xs opacity-60 leading-4 border border-border font-mono px-1 rounded-full mr-1">
|
||||||
{extractMemoIdFromName(memo.name).slice(0, 6)}
|
{extractMemoIdFromName(memo.name).slice(0, 6)}
|
||||||
</span>
|
</span>
|
||||||
<span className="truncate">{memo.snippet}</span>
|
<span className="truncate">{memo.snippet}</span>
|
||||||
|
|
@ -87,14 +87,14 @@ const MemoRelationListView = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
key={memo.name}
|
key={memo.name}
|
||||||
className="w-auto max-w-full flex flex-row justify-start items-center text-sm leading-5 text-gray-600 dark:text-gray-400 dark:border-zinc-700 dark:bg-zinc-900 hover:underline"
|
className="w-auto max-w-full flex flex-row justify-start items-center text-sm leading-5 text-muted-foreground hover:underline"
|
||||||
to={`/${memo.name}`}
|
to={`/${memo.name}`}
|
||||||
viewTransition
|
viewTransition
|
||||||
state={{
|
state={{
|
||||||
from: parentPage,
|
from: parentPage,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="text-xs opacity-60 leading-4 border border-zinc-200 font-mono px-1 rounded-full mr-1 dark:border-zinc-700">
|
<span className="text-xs opacity-60 leading-4 border border-border font-mono px-1 rounded-full mr-1">
|
||||||
{extractMemoIdFromName(memo.name).slice(0, 6)}
|
{extractMemoIdFromName(memo.name).slice(0, 6)}
|
||||||
</span>
|
</span>
|
||||||
<span className="truncate">{memo.snippet}</span>
|
<span className="truncate">{memo.snippet}</span>
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"group relative flex flex-col justify-start items-start w-full px-4 py-3 mb-2 gap-2 bg-white dark:bg-zinc-800 rounded-lg border border-white dark:border-zinc-800 hover:border-gray-200 dark:hover:border-zinc-700",
|
"group relative flex flex-col justify-start items-start w-full px-4 py-3 mb-2 gap-2 bg-card rounded-lg border border-card hover:border-border",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -144,14 +144,14 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
</Link>
|
</Link>
|
||||||
<div className="w-full flex flex-col justify-center items-start">
|
<div className="w-full flex flex-col justify-center items-start">
|
||||||
<Link
|
<Link
|
||||||
className="w-full block leading-tight hover:opacity-80 truncate text-gray-600 dark:text-gray-400"
|
className="w-full block leading-tight hover:opacity-80 truncate text-muted-foreground"
|
||||||
to={`/u/${encodeURIComponent(creator.username)}`}
|
to={`/u/${encodeURIComponent(creator.username)}`}
|
||||||
viewTransition
|
viewTransition
|
||||||
>
|
>
|
||||||
{creator.displayName || creator.username}
|
{creator.displayName || creator.username}
|
||||||
</Link>
|
</Link>
|
||||||
<div
|
<div
|
||||||
className="w-auto -mt-0.5 text-xs leading-tight text-gray-400 dark:text-gray-500 select-none cursor-pointer"
|
className="w-auto -mt-0.5 text-xs leading-tight text-muted-foreground select-none cursor-pointer"
|
||||||
onClick={handleGotoMemoDetailPage}
|
onClick={handleGotoMemoDetailPage}
|
||||||
>
|
>
|
||||||
{displayTime}
|
{displayTime}
|
||||||
|
|
@ -160,7 +160,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
className="w-full text-sm leading-tight text-gray-400 dark:text-gray-500 select-none cursor-pointer"
|
className="w-full text-sm leading-tight text-muted-foreground select-none cursor-pointer"
|
||||||
onClick={handleGotoMemoDetailPage}
|
onClick={handleGotoMemoDetailPage}
|
||||||
>
|
>
|
||||||
{displayTime}
|
{displayTime}
|
||||||
|
|
@ -193,8 +193,8 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
from: parentPage,
|
from: parentPage,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<MessageCircleMoreIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
<MessageCircleMoreIcon className="w-4 h-4 mx-auto text-muted-foreground" />
|
||||||
{commentAmount > 0 && <span className="text-xs text-gray-500 dark:text-gray-400">{commentAmount}</span>}
|
{commentAmount > 0 && <span className="text-xs text-muted-foreground">{commentAmount}</span>}
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
{props.showPinned && memo.pinned && (
|
{props.showPinned && memo.pinned && (
|
||||||
|
|
@ -202,7 +202,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="cursor-pointer">
|
<span className="cursor-pointer">
|
||||||
<BookmarkIcon className="w-4 h-auto text-amber-500" onClick={onPinIconClick} />
|
<BookmarkIcon className="w-4 h-auto text-primary" onClick={onPinIconClick} />
|
||||||
</span>
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
|
|
@ -213,7 +213,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
)}
|
)}
|
||||||
{nsfw && showNSFWContent && (
|
{nsfw && showNSFWContent && (
|
||||||
<span className="cursor-pointer">
|
<span className="cursor-pointer">
|
||||||
<EyeOffIcon className="w-4 h-auto text-amber-500" onClick={() => setShowNSFWContent(false)} />
|
<EyeOffIcon className="w-4 h-auto text-primary" onClick={() => setShowNSFWContent(false)} />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<MemoActionMenu className="-ml-1" memo={memo} readonly={readonly} onEdit={() => setShowEditor(true)} />
|
<MemoActionMenu className="-ml-1" memo={memo} readonly={readonly} onEdit={() => setShowEditor(true)} />
|
||||||
|
|
@ -244,7 +244,7 @@ const MemoView: React.FC<Props> = observer((props: Props) => {
|
||||||
<>
|
<>
|
||||||
<div className="absolute inset-0 bg-transparent" />
|
<div className="absolute inset-0 bg-transparent" />
|
||||||
<button
|
<button
|
||||||
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 py-2 px-4 text-sm text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-zinc-800"
|
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 py-2 px-4 text-sm text-muted-foreground hover:text-foreground border border-border rounded-lg bg-card"
|
||||||
onClick={() => setShowNSFWContent(true)}
|
onClick={() => setShowNSFWContent(true)}
|
||||||
>
|
>
|
||||||
{t("memo.click-to-show-nsfw-content")}
|
{t("memo.click-to-show-nsfw-content")}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const MobileHeader = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"sticky top-0 pt-3 pb-2 sm:pt-2 px-4 sm:px-6 sm:mb-1 bg-zinc-50 dark:bg-zinc-900 bg-opacity-80 backdrop-blur-lg flex md:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-1",
|
"sticky top-0 pt-3 pb-2 sm:pt-2 px-4 sm:px-6 sm:mb-1 bg-background bg-opacity-80 backdrop-blur-lg flex md:hidden flex-row justify-between items-center w-full h-auto flex-nowrap shrink-0 z-1",
|
||||||
offsetTop > 0 && "shadow-md",
|
offsetTop > 0 && "shadow-md",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -78,9 +78,9 @@ const Navigation = observer((props: Props) => {
|
||||||
<NavLink
|
<NavLink
|
||||||
className={({ isActive }) =>
|
className={({ isActive }) =>
|
||||||
cn(
|
cn(
|
||||||
"px-2 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-400 hover:bg-white hover:border-zinc-200 dark:hover:border-zinc-700 dark:hover:bg-zinc-800",
|
"px-2 py-2 rounded-2xl border flex flex-row items-center text-lg text-foreground hover:bg-secondary hover:border-border",
|
||||||
collapsed ? "" : "w-full px-4",
|
collapsed ? "" : "w-full px-4",
|
||||||
isActive ? "bg-white drop-shadow-sm dark:bg-zinc-900 border-zinc-200 dark:border-zinc-700" : "border-transparent",
|
isActive ? "bg-secondary drop-shadow-sm border-border" : "border-transparent",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
key={navLink.id}
|
key={navLink.id}
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@ const NavigationDrawer = observer(() => {
|
||||||
<SheetTrigger asChild>
|
<SheetTrigger asChild>
|
||||||
<Button variant="ghost" className="px-2">
|
<Button variant="ghost" className="px-2">
|
||||||
<UserAvatar className="shrink-0 w-6 h-6 rounded-md" avatarUrl={avatarUrl} />
|
<UserAvatar className="shrink-0 w-6 h-6 rounded-md" avatarUrl={avatarUrl} />
|
||||||
<span className="font-bold text-lg leading-10 ml-2 text-ellipsis shrink-0 cursor-pointer overflow-hidden text-gray-700 dark:text-gray-300">
|
<span className="font-bold text-lg leading-10 ml-2 text-ellipsis shrink-0 cursor-pointer overflow-hidden text-foreground">
|
||||||
{title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
</SheetTrigger>
|
</SheetTrigger>
|
||||||
<SheetContent side="left" className="w-full sm:w-80 overflow-auto px-2 bg-zinc-100 dark:bg-zinc-900">
|
<SheetContent side="left" className="w-full sm:w-80 overflow-auto px-2 bg-secondary">
|
||||||
<Navigation />
|
<Navigation />
|
||||||
</SheetContent>
|
</SheetContent>
|
||||||
</Sheet>
|
</Sheet>
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ const PagedMemoList = observer((props: Props) => {
|
||||||
{/* Loading indicator */}
|
{/* Loading indicator */}
|
||||||
{isRequesting && (
|
{isRequesting && (
|
||||||
<div className="w-full flex flex-row justify-center items-center my-4">
|
<div className="w-full flex flex-row justify-center items-center my-4">
|
||||||
<LoaderIcon className="animate-spin text-zinc-500" />
|
<LoaderIcon className="animate-spin text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
@ -158,7 +158,7 @@ const PagedMemoList = observer((props: Props) => {
|
||||||
{!nextPageToken && sortedMemoList.length === 0 ? (
|
{!nextPageToken && sortedMemoList.length === 0 ? (
|
||||||
<div className="w-full mt-12 mb-8 flex flex-col justify-center items-center italic">
|
<div className="w-full mt-12 mb-8 flex flex-col justify-center items-center italic">
|
||||||
<Empty />
|
<Empty />
|
||||||
<p className="mt-2 text-gray-600 dark:text-gray-400">{t("message.no-data")}</p>
|
<p className="mt-2 text-muted-foreground">{t("message.no-data")}</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full opacity-70 flex flex-row justify-center items-center my-4">
|
<div className="w-full opacity-70 flex flex-row justify-center items-center my-4">
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,9 @@ const PasswordSignInForm = observer(() => {
|
||||||
<form className="w-full mt-2" onSubmit={handleFormSubmit}>
|
<form className="w-full mt-2" onSubmit={handleFormSubmit}>
|
||||||
<div className="flex flex-col justify-start items-start w-full gap-4">
|
<div className="flex flex-col justify-start items-start w-full gap-4">
|
||||||
<div className="w-full flex flex-col justify-start items-start">
|
<div className="w-full flex flex-col justify-start items-start">
|
||||||
<span className="leading-8 text-gray-600">{t("common.username")}</span>
|
<span className="leading-8 text-muted-foreground">{t("common.username")}</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-full bg-white dark:bg-black h-10"
|
className="w-full bg-background h-10"
|
||||||
type="text"
|
type="text"
|
||||||
readOnly={actionBtnLoadingState.isLoading}
|
readOnly={actionBtnLoadingState.isLoading}
|
||||||
placeholder={t("common.username")}
|
placeholder={t("common.username")}
|
||||||
|
|
@ -76,9 +76,9 @@ const PasswordSignInForm = observer(() => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-start">
|
<div className="w-full flex flex-col justify-start items-start">
|
||||||
<span className="leading-8 text-gray-600">{t("common.password")}</span>
|
<span className="leading-8 text-muted-foreground">{t("common.password")}</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-full bg-white dark:bg-black h-10"
|
className="w-full bg-background h-10"
|
||||||
type="password"
|
type="password"
|
||||||
readOnly={actionBtnLoadingState.isLoading}
|
readOnly={actionBtnLoadingState.isLoading}
|
||||||
placeholder={t("common.password")}
|
placeholder={t("common.password")}
|
||||||
|
|
|
||||||
|
|
@ -59,11 +59,11 @@ const ReactionSelector = observer((props: Props) => {
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<span
|
<span
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-7 w-7 flex justify-center items-center rounded-full border border-zinc-200 dark:border-zinc-700 hover:opacity-70 cursor-pointer",
|
"h-7 w-7 flex justify-center items-center rounded-full border hover:opacity-70 cursor-pointer",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<SmilePlusIcon className="w-4 h-4 mx-auto text-gray-500 dark:text-gray-400" />
|
<SmilePlusIcon className="w-4 h-4 mx-auto text-muted-foreground" />
|
||||||
</span>
|
</span>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent align="start" sideOffset={2}>
|
<PopoverContent align="start" sideOffset={2}>
|
||||||
|
|
@ -74,8 +74,8 @@ const ReactionSelector = observer((props: Props) => {
|
||||||
<span
|
<span
|
||||||
key={reactionType}
|
key={reactionType}
|
||||||
className={cn(
|
className={cn(
|
||||||
"inline-flex w-auto text-base cursor-pointer rounded px-1 text-gray-500 dark:text-gray-400 hover:opacity-80",
|
"inline-flex w-auto text-base cursor-pointer rounded px-1 text-muted-foreground hover:opacity-80",
|
||||||
hasReacted(reactionType) && "bg-blue-100 dark:bg-zinc-800",
|
hasReacted(reactionType) && "bg-primary/10",
|
||||||
)}
|
)}
|
||||||
onClick={() => handleReactionClick(reactionType)}
|
onClick={() => handleReactionClick(reactionType)}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -70,10 +70,10 @@ const ReactionView = observer((props: Props) => {
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-7 border border-zinc-200 px-2 py-0.5 rounded-full flex flex-row justify-center items-center gap-1 dark:border-zinc-700",
|
"h-7 border px-2 py-0.5 rounded-full flex flex-row justify-center items-center gap-1",
|
||||||
"text-sm text-gray-600 dark:text-gray-400",
|
"text-sm text-muted-foreground",
|
||||||
currentUser && !readonly && "cursor-pointer",
|
currentUser && !readonly && "cursor-pointer",
|
||||||
hasReaction && "bg-blue-100 border-blue-200 dark:bg-zinc-900",
|
hasReaction && "bg-primary/10 border-primary",
|
||||||
)}
|
)}
|
||||||
onClick={handleReactionClick}
|
onClick={handleReactionClick}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p className="title-text">{t("tag.rename-tag")}</p>
|
<p className="title-text">{t("tag.rename-tag")}</p>
|
||||||
<Button variant="ghost" onClick={() => destroy()}>
|
<Button variant="ghost" onClick={() => destroy()}>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ interface Props {
|
||||||
const RequiredBadge: React.FC<Props> = (props: Props) => {
|
const RequiredBadge: React.FC<Props> = (props: Props) => {
|
||||||
const { className } = props;
|
const { className } = props;
|
||||||
|
|
||||||
return <span className={`mx-0.5 text-red-500 font-bold ${className ?? ""}`}>*</span>;
|
return <span className={`mx-0.5 text-destructive font-bold ${className ?? ""}`}>*</span>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RequiredBadge;
|
export default RequiredBadge;
|
||||||
|
|
|
||||||
|
|
@ -33,17 +33,15 @@ const SearchBar = observer(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative w-full h-auto flex flex-row justify-start items-center">
|
<div className="relative w-full h-auto flex flex-row justify-start items-center">
|
||||||
<SearchIcon className="absolute left-2 w-4 h-auto opacity-40 dark:text-zinc-300" />
|
<SearchIcon className="absolute left-2 w-4 h-auto opacity-40 text-muted-foreground" />
|
||||||
<input
|
<input
|
||||||
className={cn(
|
className={cn("w-full text-muted-foreground leading-6 bg-secondary border border-border text-sm rounded-xl p-1 pl-8 outline-0")}
|
||||||
"w-full text-gray-500 leading-6 dark:text-zinc-300 bg-zinc-50 dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800 text-sm rounded-xl p-1 pl-8 outline-0",
|
|
||||||
)}
|
|
||||||
placeholder={t("memo.search-placeholder")}
|
placeholder={t("memo.search-placeholder")}
|
||||||
value={queryText}
|
value={queryText}
|
||||||
onChange={onTextChange}
|
onChange={onTextChange}
|
||||||
onKeyDown={onKeyDown}
|
onKeyDown={onKeyDown}
|
||||||
/>
|
/>
|
||||||
<MemoDisplaySettingMenu className="absolute right-2 top-2 dark:text-zinc-300" />
|
<MemoDisplaySettingMenu className="absolute right-2 top-2 text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,11 @@ const AccessTokenSection = () => {
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="sm:flex sm:items-center sm:justify-between">
|
<div className="sm:flex sm:items-center sm:justify-between">
|
||||||
<div className="sm:flex-auto space-y-1">
|
<div className="sm:flex-auto space-y-1">
|
||||||
<p className="flex flex-row justify-start items-center font-medium text-gray-700 dark:text-gray-400">
|
<p className="flex flex-row justify-start items-center font-medium text-muted-foreground">
|
||||||
{t("setting.access-token-section.title")}
|
{t("setting.access-token-section.title")}
|
||||||
<LearnMore className="ml-2" url="https://usememos.com/docs/security/access-tokens" />
|
<LearnMore className="ml-2" url="https://usememos.com/docs/security/access-tokens" />
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gray-700 dark:text-gray-500">{t("setting.access-token-section.description")}</p>
|
<p className="text-sm text-muted-foreground">{t("setting.access-token-section.description")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 sm:mt-0">
|
<div className="mt-4 sm:mt-0">
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -73,20 +73,20 @@ const AccessTokenSection = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full mt-2 flow-root">
|
<div className="w-full mt-2 flow-root">
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<div className="inline-block min-w-full border border-zinc-200 rounded-lg align-middle dark:border-zinc-600">
|
<div className="inline-block min-w-full border border-border rounded-lg align-middle">
|
||||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-600">
|
<table className="min-w-full divide-y divide-border">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-foreground">
|
||||||
{t("setting.access-token-section.token")}
|
{t("setting.access-token-section.token")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="py-2 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="py-2 pl-4 pr-3 text-left text-sm font-semibold text-foreground">
|
||||||
{t("common.description")}
|
{t("common.description")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-foreground">
|
||||||
{t("setting.access-token-section.create-dialog.created-at")}
|
{t("setting.access-token-section.create-dialog.created-at")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-foreground">
|
||||||
{t("setting.access-token-section.create-dialog.expires-at")}
|
{t("setting.access-token-section.create-dialog.expires-at")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
||||||
|
|
@ -94,22 +94,22 @@ const AccessTokenSection = () => {
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-200 dark:divide-zinc-700">
|
<tbody className="divide-y divide-border">
|
||||||
{userAccessTokens.map((userAccessToken) => (
|
{userAccessTokens.map((userAccessToken) => (
|
||||||
<tr key={userAccessToken.accessToken}>
|
<tr key={userAccessToken.accessToken}>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400 flex flex-row justify-start items-center gap-x-1">
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-foreground flex flex-row justify-start items-center gap-x-1">
|
||||||
<span className="font-mono">{getFormatedAccessToken(userAccessToken.accessToken)}</span>
|
<span className="font-mono">{getFormatedAccessToken(userAccessToken.accessToken)}</span>
|
||||||
<Button variant="ghost" onClick={() => copyAccessToken(userAccessToken.accessToken)}>
|
<Button variant="ghost" onClick={() => copyAccessToken(userAccessToken.accessToken)}>
|
||||||
<ClipboardIcon className="w-4 h-auto text-gray-400" />
|
<ClipboardIcon className="w-4 h-auto text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
<td className="whitespace-nowrap py-2 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-400">
|
<td className="whitespace-nowrap py-2 pl-4 pr-3 text-sm text-foreground">
|
||||||
{userAccessToken.description}
|
{userAccessToken.description}
|
||||||
</td>
|
</td>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-muted-foreground">
|
||||||
{userAccessToken.issuedAt?.toLocaleString()}
|
{userAccessToken.issuedAt?.toLocaleString()}
|
||||||
</td>
|
</td>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-muted-foreground">
|
||||||
{userAccessToken.expiresAt?.toLocaleString() ?? t("setting.access-token-section.create-dialog.duration-never")}
|
{userAccessToken.expiresAt?.toLocaleString() ?? t("setting.access-token-section.create-dialog.duration-never")}
|
||||||
</td>
|
</td>
|
||||||
<td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm">
|
<td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm">
|
||||||
|
|
@ -119,7 +119,7 @@ const AccessTokenSection = () => {
|
||||||
handleDeleteAccessToken(userAccessToken);
|
handleDeleteAccessToken(userAccessToken);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TrashIcon className="text-red-600 w-4 h-auto" />
|
<TrashIcon className="text-destructive w-4 h-auto" />
|
||||||
</Button>
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
||||||
|
|
@ -145,8 +145,8 @@ const MemberSection = observer(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("setting.member-section.create-a-member")}</p>
|
<p className="font-medium text-muted-foreground">{t("setting.member-section.create-a-member")}</p>
|
||||||
<div className="w-auto flex flex-col justify-start items-start gap-2 border border-zinc-200 rounded-md py-2 px-3 dark:border-zinc-700">
|
<div className="w-auto flex flex-col justify-start items-start gap-2 border border-border rounded-md py-2 px-3">
|
||||||
<div className="flex flex-col justify-start items-start gap-1">
|
<div className="flex flex-col justify-start items-start gap-1">
|
||||||
<span>{t("common.username")}</span>
|
<span>{t("common.username")}</span>
|
||||||
<Input
|
<Input
|
||||||
|
|
@ -192,10 +192,10 @@ const MemberSection = observer(() => {
|
||||||
<div className="title-text">{t("setting.member-list")}</div>
|
<div className="title-text">{t("setting.member-list")}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full overflow-x-auto">
|
<div className="w-full overflow-x-auto">
|
||||||
<div className="inline-block min-w-full align-middle border border-zinc-200 rounded-lg dark:border-zinc-600">
|
<div className="inline-block min-w-full align-middle border border-border rounded-lg">
|
||||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-600">
|
<table className="min-w-full divide-y divide-border">
|
||||||
<thead>
|
<thead>
|
||||||
<tr className="text-sm font-semibold text-left text-gray-900 dark:text-gray-400">
|
<tr className="text-sm font-semibold text-left text-foreground">
|
||||||
<th scope="col" className="px-3 py-2">
|
<th scope="col" className="px-3 py-2">
|
||||||
{t("common.username")}
|
{t("common.username")}
|
||||||
</th>
|
</th>
|
||||||
|
|
@ -211,23 +211,23 @@ const MemberSection = observer(() => {
|
||||||
<th scope="col" className="relative py-2 pl-3 pr-4"></th>
|
<th scope="col" className="relative py-2 pl-3 pr-4"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-200 dark:divide-zinc-600">
|
<tbody className="divide-y divide-border">
|
||||||
{sortedUsers.map((user) => (
|
{sortedUsers.map((user) => (
|
||||||
<tr key={user.name}>
|
<tr key={user.name}>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-muted-foreground">
|
||||||
{user.username}
|
{user.username}
|
||||||
<span className="ml-1 italic">{user.state === State.ARCHIVED && "(Archived)"}</span>
|
<span className="ml-1 italic">{user.state === State.ARCHIVED && "(Archived)"}</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{stringifyUserRole(user.role)}</td>
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-muted-foreground">{stringifyUserRole(user.role)}</td>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.displayName}</td>
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-muted-foreground">{user.displayName}</td>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.email}</td>
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-muted-foreground">{user.email}</td>
|
||||||
<td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium flex justify-end">
|
<td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium flex justify-end">
|
||||||
{currentUser?.name === user.name ? (
|
{currentUser?.name === user.name ? (
|
||||||
<span>{t("common.yourself")}</span>
|
<span>{t("common.yourself")}</span>
|
||||||
) : (
|
) : (
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="flex items-center justify-center p-1 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded">
|
<button className="flex items-center justify-center p-1 hover:bg-muted rounded">
|
||||||
<MoreVerticalIcon className="w-4 h-auto" />
|
<MoreVerticalIcon className="w-4 h-auto" />
|
||||||
</button>
|
</button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
|
|
@ -235,14 +235,14 @@ const MemberSection = observer(() => {
|
||||||
<div className="flex flex-col gap-0.5 text-sm">
|
<div className="flex flex-col gap-0.5 text-sm">
|
||||||
<button
|
<button
|
||||||
onClick={() => showCreateUserDialog(user, () => fetchUsers())}
|
onClick={() => showCreateUserDialog(user, () => fetchUsers())}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
{t("common.update")}
|
{t("common.update")}
|
||||||
</button>
|
</button>
|
||||||
{user.state === State.NORMAL ? (
|
{user.state === State.NORMAL ? (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleArchiveUserClick(user)}
|
onClick={() => handleArchiveUserClick(user)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
{t("setting.member-section.archive-member")}
|
{t("setting.member-section.archive-member")}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -250,13 +250,13 @@ const MemberSection = observer(() => {
|
||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleRestoreUserClick(user)}
|
onClick={() => handleRestoreUserClick(user)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
{t("common.restore")}
|
{t("common.restore")}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDeleteUserClick(user)}
|
onClick={() => handleDeleteUserClick(user)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-destructive hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
{t("setting.member-section.delete-member")}
|
{t("setting.member-section.delete-member")}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ const MemoRelatedSettings = observer(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("setting.memo-related-settings.title")}</p>
|
<p className="font-medium text-muted-foreground">{t("setting.memo-related-settings.title")}</p>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>{t("setting.system-section.disable-public-memos")}</span>
|
<span>{t("setting.system-section.disable-public-memos")}</span>
|
||||||
<Switch
|
<Switch
|
||||||
|
|
@ -127,7 +127,7 @@ const MemoRelatedSettings = observer(() => {
|
||||||
<Badge key={reactionType} variant="outline" className="h-8 flex items-center gap-1">
|
<Badge key={reactionType} variant="outline" className="h-8 flex items-center gap-1">
|
||||||
{reactionType}
|
{reactionType}
|
||||||
<X
|
<X
|
||||||
className="w-3 h-3 cursor-pointer hover:text-red-500"
|
className="w-3 h-3 cursor-pointer hover:text-destructive"
|
||||||
onClick={() => updatePartialSetting({ reactions: memoRelatedSetting.reactions.filter((r) => r !== reactionType) })}
|
onClick={() => updatePartialSetting({ reactions: memoRelatedSetting.reactions.filter((r) => r !== reactionType) })}
|
||||||
/>
|
/>
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
@ -141,7 +141,7 @@ const MemoRelatedSettings = observer(() => {
|
||||||
onChange={(event) => setEditingReaction(event.target.value.trim())}
|
onChange={(event) => setEditingReaction(event.target.value.trim())}
|
||||||
/>
|
/>
|
||||||
<CheckIcon
|
<CheckIcon
|
||||||
className="w-5 h-5 text-gray-500 dark:text-gray-400 cursor-pointer hover:text-teal-600"
|
className="w-5 h-5 text-muted-foreground cursor-pointer hover:text-primary"
|
||||||
onClick={() => upsertReaction()}
|
onClick={() => upsertReaction()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -161,7 +161,7 @@ const MemoRelatedSettings = observer(() => {
|
||||||
<Badge key={nsfwTag} variant="outline" className="h-8 flex items-center gap-1">
|
<Badge key={nsfwTag} variant="outline" className="h-8 flex items-center gap-1">
|
||||||
{nsfwTag}
|
{nsfwTag}
|
||||||
<X
|
<X
|
||||||
className="w-3 h-3 cursor-pointer hover:text-red-500"
|
className="w-3 h-3 cursor-pointer hover:text-destructive"
|
||||||
onClick={() => updatePartialSetting({ nsfwTags: memoRelatedSetting.nsfwTags.filter((r) => r !== nsfwTag) })}
|
onClick={() => updatePartialSetting({ nsfwTags: memoRelatedSetting.nsfwTags.filter((r) => r !== nsfwTag) })}
|
||||||
/>
|
/>
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
@ -175,7 +175,7 @@ const MemoRelatedSettings = observer(() => {
|
||||||
onChange={(event) => setEditingNsfwTag(event.target.value.trim())}
|
onChange={(event) => setEditingNsfwTag(event.target.value.trim())}
|
||||||
/>
|
/>
|
||||||
<CheckIcon
|
<CheckIcon
|
||||||
className="w-5 h-5 text-gray-500 dark:text-gray-400 cursor-pointer hover:text-teal-600"
|
className="w-5 h-5 text-muted-foreground cursor-pointer hover:text-primary"
|
||||||
onClick={() => upsertNsfwTags()}
|
onClick={() => upsertNsfwTags()}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@ const MyAccountSection = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full gap-2 pt-2 pb-4">
|
<div className="w-full gap-2 pt-2 pb-4">
|
||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("setting.account-section.title")}</p>
|
<p className="font-medium text-muted-foreground">{t("setting.account-section.title")}</p>
|
||||||
<div className="w-full mt-2 flex flex-row justify-start items-center">
|
<div className="w-full mt-2 flex flex-row justify-start items-center">
|
||||||
<UserAvatar className="mr-2 shrink-0 w-10 h-10" avatarUrl={user.avatarUrl} />
|
<UserAvatar className="mr-2 shrink-0 w-10 h-10" avatarUrl={user.avatarUrl} />
|
||||||
<div className="max-w-[calc(100%-3rem)] flex flex-col justify-center items-start">
|
<div className="max-w-[calc(100%-3rem)] flex flex-col justify-center items-start">
|
||||||
<p className="w-full">
|
<p className="w-full">
|
||||||
<span className="text-xl leading-tight font-medium">{user.displayName}</span>
|
<span className="text-xl leading-tight font-medium">{user.displayName}</span>
|
||||||
<span className="ml-1 text-base leading-tight text-gray-500 dark:text-gray-400">({user.username})</span>
|
<span className="ml-1 text-base leading-tight text-muted-foreground">({user.username})</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="w-4/5 leading-tight text-sm truncate">{user.description}</p>
|
<p className="w-4/5 leading-tight text-sm truncate">{user.description}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -40,7 +40,7 @@ const MyAccountSection = () => {
|
||||||
<PopoverContent align="start" className="text-sm p-1">
|
<PopoverContent align="start" className="text-sm p-1">
|
||||||
<button
|
<button
|
||||||
onClick={() => showChangeMemberPasswordDialog(user)}
|
onClick={() => showChangeMemberPasswordDialog(user)}
|
||||||
className="w-full flex items-center gap-2 px-2 py-1 text-left text-sm hover:bg-gray-100 rounded-md"
|
className="w-full flex items-center gap-2 px-2 py-1 text-left text-sm hover:bg-muted rounded-md"
|
||||||
>
|
>
|
||||||
{t("setting.account-section.change-password")}
|
{t("setting.account-section.change-password")}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ const PreferencesSection = observer(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("common.basic")}</p>
|
<p className="font-medium text-muted-foreground">{t("common.basic")}</p>
|
||||||
|
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>{t("common.language")}</span>
|
<span>{t("common.language")}</span>
|
||||||
|
|
@ -41,7 +41,7 @@ const PreferencesSection = observer(() => {
|
||||||
<AppearanceSelect value={setting.appearance as Appearance} onChange={handleAppearanceSelectChange} />
|
<AppearanceSelect value={setting.appearance as Appearance} onChange={handleAppearanceSelectChange} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("setting.preference")}</p>
|
<p className="font-medium text-muted-foreground">{t("setting.preference")}</p>
|
||||||
|
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="truncate">{t("setting.preference-section.default-memo-visibility")}</span>
|
<span className="truncate">{t("setting.preference-section.default-memo-visibility")}</span>
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ const SSOSection = () => {
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<div className="w-full flex flex-row justify-between items-center gap-1">
|
<div className="w-full flex flex-row justify-between items-center gap-1">
|
||||||
<div className="flex flex-row items-center gap-1">
|
<div className="flex flex-row items-center gap-1">
|
||||||
<span className="font-mono text-gray-400">{t("setting.sso-section.sso-list")}</span>
|
<span className="font-mono text-muted-foreground">{t("setting.sso-section.sso-list")}</span>
|
||||||
<LearnMore url="https://www.usememos.com/docs/advanced-settings/sso" />
|
<LearnMore url="https://www.usememos.com/docs/advanced-settings/sso" />
|
||||||
</div>
|
</div>
|
||||||
<Button color="primary" onClick={() => showCreateIdentityProviderDialog(undefined, fetchIdentityProviderList)}>
|
<Button color="primary" onClick={() => showCreateIdentityProviderDialog(undefined, fetchIdentityProviderList)}>
|
||||||
|
|
@ -52,7 +52,7 @@ const SSOSection = () => {
|
||||||
{identityProviderList.map((identityProvider) => (
|
{identityProviderList.map((identityProvider) => (
|
||||||
<div
|
<div
|
||||||
key={identityProvider.name}
|
key={identityProvider.name}
|
||||||
className="py-2 w-full border-b last:border-b dark:border-zinc-700 flex flex-row items-center justify-between"
|
className="py-2 w-full border-b last:border-b border-border flex flex-row items-center justify-between"
|
||||||
>
|
>
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<p className="ml-2">
|
<p className="ml-2">
|
||||||
|
|
@ -63,7 +63,7 @@ const SSOSection = () => {
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<button className="flex items-center justify-center p-1 hover:bg-gray-100 dark:hover:bg-zinc-700 rounded">
|
<button className="flex items-center justify-center p-1 hover:bg-secondary rounded">
|
||||||
<MoreVerticalIcon className="w-4 h-auto" />
|
<MoreVerticalIcon className="w-4 h-auto" />
|
||||||
</button>
|
</button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
|
|
@ -71,13 +71,13 @@ const SSOSection = () => {
|
||||||
<div className="flex flex-col gap-0.5 text-sm">
|
<div className="flex flex-col gap-0.5 text-sm">
|
||||||
<button
|
<button
|
||||||
onClick={() => showCreateIdentityProviderDialog(identityProvider, fetchIdentityProviderList)}
|
onClick={() => showCreateIdentityProviderDialog(identityProvider, fetchIdentityProviderList)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-secondary outline-none rounded"
|
||||||
>
|
>
|
||||||
{t("common.edit")}
|
{t("common.edit")}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDeleteIdentityProvider(identityProvider)}
|
onClick={() => handleDeleteIdentityProvider(identityProvider)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left text-red-600 dark:text-red-400 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-destructive hover:bg-secondary outline-none rounded"
|
||||||
>
|
>
|
||||||
{t("common.delete")}
|
{t("common.delete")}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -88,7 +88,7 @@ const SSOSection = () => {
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{identityProviderList.length === 0 && (
|
{identityProviderList.length === 0 && (
|
||||||
<div className="w-full mt-2 text-sm dark:border-zinc-700 opacity-60 flex flex-row items-center justify-between">
|
<div className="w-full mt-2 text-sm border-border opacity-60 flex flex-row items-center justify-between">
|
||||||
<p className="">{t("setting.sso-section.no-sso-found")}</p>
|
<p className="">{t("setting.sso-section.no-sso-found")}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
@ -97,11 +97,7 @@ const SSOSection = () => {
|
||||||
<p className="text-sm">{t("common.learn-more")}:</p>
|
<p className="text-sm">{t("common.learn-more")}:</p>
|
||||||
<ul className="list-disc list-inside text-sm ml-4">
|
<ul className="list-disc list-inside text-sm ml-4">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link className="text-sm text-primary hover:underline" to="https://www.usememos.com/docs/advanced-settings/sso" target="_blank">
|
||||||
className="text-sm text-blue-600 hover:underline"
|
|
||||||
to="https://www.usememos.com/docs/advanced-settings/sso"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
{t("setting.sso-section.single-sign-on")}
|
{t("setting.sso-section.single-sign-on")}
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const SectionMenuItem: React.FC<SettingMenuItemProps> = ({ text, icon: IconCompo
|
||||||
<div
|
<div
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={`w-auto max-w-full px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg select-none hover:opacity-80 ${
|
className={`w-auto max-w-full px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg select-none hover:opacity-80 ${
|
||||||
isSelected ? "bg-zinc-100 shadow dark:bg-zinc-900" : ""
|
isSelected ? "bg-secondary shadow" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<IconComponent className="w-4 h-auto mr-2 opacity-80 shrink-0" />
|
<IconComponent className="w-4 h-auto mr-2 opacity-80 shrink-0" />
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ const StorageSection = observer(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<div className="font-medium text-gray-700 dark:text-gray-500">{t("setting.storage-section.current-storage")}</div>
|
<div className="font-medium text-muted-foreground">{t("setting.storage-section.current-storage")}</div>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
value={workspaceStorageSetting.storageType.toString()}
|
value={workspaceStorageSetting.storageType.toString()}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
|
|
@ -157,7 +157,7 @@ const StorageSection = observer(() => {
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">{t("setting.system-section.max-upload-size")}</span>
|
<span className="text-muted-foreground mr-1">{t("setting.system-section.max-upload-size")}</span>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger>
|
<TooltipTrigger>
|
||||||
|
|
@ -173,7 +173,7 @@ const StorageSection = observer(() => {
|
||||||
</div>
|
</div>
|
||||||
{workspaceStorageSetting.storageType !== WorkspaceStorageSetting_StorageType.DATABASE && (
|
{workspaceStorageSetting.storageType !== WorkspaceStorageSetting_StorageType.DATABASE && (
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">{t("setting.storage-section.filepath-template")}</span>
|
<span className="text-muted-foreground mr-1">{t("setting.storage-section.filepath-template")}</span>
|
||||||
<Input
|
<Input
|
||||||
value={workspaceStorageSetting.filepathTemplate}
|
value={workspaceStorageSetting.filepathTemplate}
|
||||||
placeholder="assets/{timestamp}_{filename}"
|
placeholder="assets/{timestamp}_{filename}"
|
||||||
|
|
@ -184,11 +184,11 @@ const StorageSection = observer(() => {
|
||||||
{workspaceStorageSetting.storageType === WorkspaceStorageSetting_StorageType.S3 && (
|
{workspaceStorageSetting.storageType === WorkspaceStorageSetting_StorageType.S3 && (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">Access key id</span>
|
<span className="text-muted-foreground mr-1">Access key id</span>
|
||||||
<Input value={workspaceStorageSetting.s3Config?.accessKeyId} placeholder="" onChange={handleS3ConfigAccessKeyIdChanged} />
|
<Input value={workspaceStorageSetting.s3Config?.accessKeyId} placeholder="" onChange={handleS3ConfigAccessKeyIdChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">Access key secret</span>
|
<span className="text-muted-foreground mr-1">Access key secret</span>
|
||||||
<Input
|
<Input
|
||||||
value={workspaceStorageSetting.s3Config?.accessKeySecret}
|
value={workspaceStorageSetting.s3Config?.accessKeySecret}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
|
|
@ -196,19 +196,19 @@ const StorageSection = observer(() => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">Endpoint</span>
|
<span className="text-muted-foreground mr-1">Endpoint</span>
|
||||||
<Input value={workspaceStorageSetting.s3Config?.endpoint} placeholder="" onChange={handleS3ConfigEndpointChanged} />
|
<Input value={workspaceStorageSetting.s3Config?.endpoint} placeholder="" onChange={handleS3ConfigEndpointChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">Region</span>
|
<span className="text-muted-foreground mr-1">Region</span>
|
||||||
<Input value={workspaceStorageSetting.s3Config?.region} placeholder="" onChange={handleS3ConfigRegionChanged} />
|
<Input value={workspaceStorageSetting.s3Config?.region} placeholder="" onChange={handleS3ConfigRegionChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">Bucket</span>
|
<span className="text-muted-foreground mr-1">Bucket</span>
|
||||||
<Input value={workspaceStorageSetting.s3Config?.bucket} placeholder="" onChange={handleS3ConfigBucketChanged} />
|
<Input value={workspaceStorageSetting.s3Config?.bucket} placeholder="" onChange={handleS3ConfigBucketChanged} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span className="text-gray-700 dark:text-gray-500 mr-1">Use Path Style</span>
|
<span className="text-muted-foreground mr-1">Use Path Style</span>
|
||||||
<Switch
|
<Switch
|
||||||
checked={workspaceStorageSetting.s3Config?.usePathStyle}
|
checked={workspaceStorageSetting.s3Config?.usePathStyle}
|
||||||
onCheckedChange={(checked) => handleS3ConfigUsePathStyleChanged({ target: { checked } } as any)}
|
onCheckedChange={(checked) => handleS3ConfigUsePathStyleChanged({ target: { checked } } as any)}
|
||||||
|
|
@ -227,7 +227,7 @@ const StorageSection = observer(() => {
|
||||||
<ul className="text-sm list-disc ml-4 space-y-1">
|
<ul className="text-sm list-disc ml-4 space-y-1">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
className="text-sm text-blue-600 hover:underline"
|
className="text-sm text-primary hover:underline"
|
||||||
to="https://www.usememos.com/docs/advanced-settings/local-storage"
|
to="https://www.usememos.com/docs/advanced-settings/local-storage"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
@ -236,7 +236,7 @@ const StorageSection = observer(() => {
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
className="text-sm text-blue-600 hover:underline"
|
className="text-sm text-primary hover:underline"
|
||||||
to="https://www.usememos.com/blog/choosing-a-storage-for-your-resource"
|
to="https://www.usememos.com/blog/choosing-a-storage-for-your-resource"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,12 @@ const UserSessionsSection = () => {
|
||||||
const getDeviceIcon = (deviceType: string) => {
|
const getDeviceIcon = (deviceType: string) => {
|
||||||
switch (deviceType?.toLowerCase()) {
|
switch (deviceType?.toLowerCase()) {
|
||||||
case "mobile":
|
case "mobile":
|
||||||
return <SmartphoneIcon className="w-4 h-4 text-gray-500" />;
|
return <SmartphoneIcon className="w-4 h-4 text-muted-foreground" />;
|
||||||
case "tablet":
|
case "tablet":
|
||||||
return <TabletIcon className="w-4 h-4 text-gray-500" />;
|
return <TabletIcon className="w-4 h-4 text-muted-foreground" />;
|
||||||
case "desktop":
|
case "desktop":
|
||||||
default:
|
default:
|
||||||
return <MonitorIcon className="w-4 h-4 text-gray-500" />;
|
return <MonitorIcon className="w-4 h-4 text-muted-foreground" />;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -72,23 +72,23 @@ const UserSessionsSection = () => {
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<div className="sm:flex sm:items-center sm:justify-between">
|
<div className="sm:flex sm:items-center sm:justify-between">
|
||||||
<div className="sm:flex-auto space-y-1">
|
<div className="sm:flex-auto space-y-1">
|
||||||
<p className="flex flex-row justify-start items-center font-medium text-gray-700 dark:text-gray-400">
|
<p className="flex flex-row justify-start items-center font-medium text-muted-foreground">
|
||||||
{t("setting.user-sessions-section.title")}
|
{t("setting.user-sessions-section.title")}
|
||||||
<LearnMore className="ml-2" url="https://usememos.com/docs/security/sessions" />
|
<LearnMore className="ml-2" url="https://usememos.com/docs/security/sessions" />
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-gray-700 dark:text-gray-500">{t("setting.user-sessions-section.description")}</p>
|
<p className="text-sm text-muted-foreground">{t("setting.user-sessions-section.description")}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full mt-2 flow-root">
|
<div className="w-full mt-2 flow-root">
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<div className="inline-block min-w-full border border-zinc-200 rounded-lg align-middle dark:border-zinc-600">
|
<div className="inline-block min-w-full border border-border rounded-lg align-middle">
|
||||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-600">
|
<table className="min-w-full divide-y divide-border">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-foreground">
|
||||||
{t("setting.user-sessions-section.device")}
|
{t("setting.user-sessions-section.device")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-foreground">
|
||||||
{t("setting.user-sessions-section.last-active")}
|
{t("setting.user-sessions-section.last-active")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
||||||
|
|
@ -96,27 +96,27 @@ const UserSessionsSection = () => {
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-200 dark:divide-zinc-700">
|
<tbody className="divide-y divide-border">
|
||||||
{userSessions.map((userSession) => (
|
{userSessions.map((userSession) => (
|
||||||
<tr key={userSession.sessionId}>
|
<tr key={userSession.sessionId}>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400">
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-foreground">
|
||||||
<div className="flex items-center space-x-3">
|
<div className="flex items-center space-x-3">
|
||||||
{getDeviceIcon(userSession.clientInfo?.deviceType || "")}
|
{getDeviceIcon(userSession.clientInfo?.deviceType || "")}
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="font-medium">
|
<span className="font-medium">
|
||||||
{formatDeviceInfo(userSession.clientInfo)}
|
{formatDeviceInfo(userSession.clientInfo)}
|
||||||
{isCurrentSession(userSession) && (
|
{isCurrentSession(userSession) && (
|
||||||
<span className="ml-2 inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100">
|
<span className="ml-2 inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-primary/20 text-primary">
|
||||||
<WifiIcon className="w-3 h-3 mr-1" />
|
<WifiIcon className="w-3 h-3 mr-1" />
|
||||||
{t("setting.user-sessions-section.current")}
|
{t("setting.user-sessions-section.current")}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs text-gray-500 font-mono">{getFormattedSessionId(userSession.sessionId)}</span>
|
<span className="text-xs text-muted-foreground font-mono">{getFormattedSessionId(userSession.sessionId)}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-muted-foreground">
|
||||||
<div className="flex items-center space-x-1">
|
<div className="flex items-center space-x-1">
|
||||||
<ClockIcon className="w-4 h-4" />
|
<ClockIcon className="w-4 h-4" />
|
||||||
<span>{userSession.lastAccessedTime?.toLocaleString()}</span>
|
<span>{userSession.lastAccessedTime?.toLocaleString()}</span>
|
||||||
|
|
@ -135,7 +135,7 @@ const UserSessionsSection = () => {
|
||||||
: t("setting.user-sessions-section.revoke-session")
|
: t("setting.user-sessions-section.revoke-session")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<TrashIcon className={`w-4 h-auto ${isCurrentSession(userSession) ? "text-gray-400" : "text-red-600"}`} />
|
<TrashIcon className={`w-4 h-auto ${isCurrentSession(userSession) ? "text-muted-foreground" : "text-destructive"}`} />
|
||||||
</Button>
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -143,7 +143,7 @@ const UserSessionsSection = () => {
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{userSessions.length === 0 && (
|
{userSessions.length === 0 && (
|
||||||
<div className="text-center py-8 text-gray-500 dark:text-gray-400">{t("setting.user-sessions-section.no-sessions")}</div>
|
<div className="text-center py-8 text-muted-foreground">{t("setting.user-sessions-section.no-sessions")}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const WebhookSection = () => {
|
||||||
<div className="w-full flex flex-col justify-start items-start">
|
<div className="w-full flex flex-col justify-start items-start">
|
||||||
<div className="w-full flex justify-between items-center">
|
<div className="w-full flex justify-between items-center">
|
||||||
<div className="flex-auto space-y-1">
|
<div className="flex-auto space-y-1">
|
||||||
<p className="flex flex-row justify-start items-center font-medium text-gray-700 dark:text-gray-400">
|
<p className="flex flex-row justify-start items-center font-medium text-muted-foreground">
|
||||||
{t("setting.webhook-section.title")}
|
{t("setting.webhook-section.title")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -61,14 +61,14 @@ const WebhookSection = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full mt-2 flow-root">
|
<div className="w-full mt-2 flow-root">
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<div className="inline-block min-w-full border border-zinc-200 rounded-lg align-middle dark:border-zinc-600">
|
<div className="inline-block min-w-full border border-border rounded-lg align-middle">
|
||||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-600">
|
<table className="min-w-full divide-y divide-border">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-foreground">
|
||||||
{t("common.name")}
|
{t("common.name")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-foreground">
|
||||||
{t("setting.webhook-section.url")}
|
{t("setting.webhook-section.url")}
|
||||||
</th>
|
</th>
|
||||||
<th scope="col" className="relative px-3 py-2 pr-4">
|
<th scope="col" className="relative px-3 py-2 pr-4">
|
||||||
|
|
@ -76,11 +76,11 @@ const WebhookSection = () => {
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-200 dark:divide-gray-500">
|
<tbody className="divide-y divide-border">
|
||||||
{webhooks.map((webhook) => (
|
{webhooks.map((webhook) => (
|
||||||
<tr key={webhook.name}>
|
<tr key={webhook.name}>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400">{webhook.displayName}</td>
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-foreground">{webhook.displayName}</td>
|
||||||
<td className="max-w-[200px] px-3 py-2 text-sm text-gray-900 dark:text-gray-400 truncate" title={webhook.url}>
|
<td className="max-w-[200px] px-3 py-2 text-sm text-foreground truncate" title={webhook.url}>
|
||||||
{webhook.url}
|
{webhook.url}
|
||||||
</td>
|
</td>
|
||||||
<td className="relative whitespace-nowrap px-3 py-2 text-right text-sm">
|
<td className="relative whitespace-nowrap px-3 py-2 text-right text-sm">
|
||||||
|
|
@ -90,7 +90,7 @@ const WebhookSection = () => {
|
||||||
handleDeleteWebhook(webhook);
|
handleDeleteWebhook(webhook);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TrashIcon className="text-red-600 w-4 h-auto" />
|
<TrashIcon className="text-destructive w-4 h-auto" />
|
||||||
</Button>
|
</Button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -98,7 +98,7 @@ const WebhookSection = () => {
|
||||||
|
|
||||||
{webhooks.length === 0 && (
|
{webhooks.length === 0 && (
|
||||||
<tr>
|
<tr>
|
||||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-900 dark:text-gray-400" colSpan={3}>
|
<td className="whitespace-nowrap px-3 py-2 text-sm text-foreground" colSpan={3}>
|
||||||
{t("setting.webhook-section.no-webhooks-found")}
|
{t("setting.webhook-section.no-webhooks-found")}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -110,7 +110,7 @@ const WebhookSection = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full mt-2">
|
<div className="w-full mt-2">
|
||||||
<Link
|
<Link
|
||||||
className="text-gray-500 text-sm inline-flex flex-row justify-start items-center hover:underline hover:text-blue-600"
|
className="text-muted-foreground text-sm inline-flex flex-row justify-start items-center hover:underline hover:text-primary"
|
||||||
to="https://usememos.com/docs/advanced-settings/webhook"
|
to="https://usememos.com/docs/advanced-settings/webhook"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ const WorkspaceSection = observer(() => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("common.basic")}</p>
|
<p className="font-medium text-foreground">{t("common.basic")}</p>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
{t("setting.system-section.server-name")}:{" "}
|
{t("setting.system-section.server-name")}:{" "}
|
||||||
|
|
@ -79,7 +79,7 @@ const WorkspaceSection = observer(() => {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Separator />
|
<Separator />
|
||||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("setting.system-section.title")}</p>
|
<p className="font-medium text-foreground">{t("setting.system-section.title")}</p>
|
||||||
<div className="w-full flex flex-row justify-between items-center">
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
<span>{t("setting.system-section.additional-style")}</span>
|
<span>{t("setting.system-section.additional-style")}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -102,7 +102,7 @@ const WorkspaceSection = observer(() => {
|
||||||
/>
|
/>
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<Link
|
<Link
|
||||||
className="text-gray-500 text-sm flex flex-row justify-start items-center hover:underline hover:text-blue-600"
|
className="text-muted-foreground text-sm flex flex-row justify-start items-center hover:underline hover:text-primary"
|
||||||
to="https://usememos.com/docs/advanced-settings/custom-style-and-script"
|
to="https://usememos.com/docs/advanced-settings/custom-style-and-script"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export const MonthNavigator = ({ visibleMonth, onMonthChange }: MonthNavigatorPr
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full mb-1 flex flex-row justify-between items-center gap-1">
|
<div className="w-full mb-1 flex flex-row justify-between items-center gap-1">
|
||||||
<span className="relative text-sm text-gray-500 dark:text-gray-400">
|
<span className="relative text-sm text-muted-foreground">
|
||||||
{currentMonth.toLocaleString(i18n.language, { year: "numeric", month: "long" })}
|
{currentMonth.toLocaleString(i18n.language, { year: "numeric", month: "long" })}
|
||||||
</span>
|
</span>
|
||||||
<div className="flex justify-end items-center shrink-0 gap-1">
|
<div className="flex justify-end items-center shrink-0 gap-1">
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ export const StatCard = ({ icon, label, count, onClick, tooltip, className }: St
|
||||||
const content = (
|
const content = (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-auto border border-zinc-200 dark:border-zinc-800 pl-1.5 pr-2 py-0.5 rounded-md flex justify-between items-center",
|
"w-auto border pl-1.5 pr-2 py-0.5 rounded-md flex justify-between items-center",
|
||||||
"cursor-pointer hover:bg-gray-50 dark:hover:bg-zinc-800/50 transition-colors",
|
"cursor-pointer hover:bg-muted transition-colors",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const StatisticsView = observer(() => {
|
||||||
const hasPinnedMemos = currentUser && (userStore.state.currentUserStats?.pinnedMemos || []).length > 0;
|
const hasPinnedMemos = currentUser && (userStore.state.currentUserStats?.pinnedMemos || []).length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="group w-full mt-2 space-y-1 text-zinc-600 dark:text-gray-400 animate-fade-in">
|
<div className="group w-full mt-2 space-y-1 text-muted-foreground animate-fade-in">
|
||||||
<MonthNavigator visibleMonth={visibleMonthString} onMonthChange={setVisibleMonthString} />
|
<MonthNavigator visibleMonth={visibleMonthString} onMonthChange={setVisibleMonthString} />
|
||||||
|
|
||||||
<div className="w-full animate-scale-in">
|
<div className="w-full animate-scale-in">
|
||||||
|
|
|
||||||
|
|
@ -111,12 +111,12 @@ const TagItemContainer = observer((props: TagItemContainerProps) => {
|
||||||
<>
|
<>
|
||||||
<div className="relative flex flex-row justify-between items-center w-full leading-6 py-0 mt-px rounded-lg text-sm select-none shrink-0">
|
<div className="relative flex flex-row justify-between items-center w-full leading-6 py-0 mt-px rounded-lg text-sm select-none shrink-0">
|
||||||
<div
|
<div
|
||||||
className={`flex flex-row justify-start items-center truncate shrink leading-5 mr-1 text-gray-600 dark:text-gray-400 ${
|
className={`flex flex-row justify-start items-center truncate shrink leading-5 mr-1 text-muted-foreground ${
|
||||||
isActive && "text-blue-600!"
|
isActive && "text-primary!"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="shrink-0">
|
<div className="shrink-0">
|
||||||
<HashIcon className="w-4 h-auto shrink-0 mr-1 text-gray-400 dark:text-gray-500" />
|
<HashIcon className="w-4 h-auto shrink-0 mr-1 text-muted-foreground" />
|
||||||
</div>
|
</div>
|
||||||
<span className="truncate cursor-pointer hover:opacity-80" onClick={handleTagClick}>
|
<span className="truncate cursor-pointer hover:opacity-80" onClick={handleTagClick}>
|
||||||
{tag.key} {tag.amount > 1 && `(${tag.amount})`}
|
{tag.key} {tag.amount > 1 && `(${tag.amount})`}
|
||||||
|
|
@ -128,14 +128,14 @@ const TagItemContainer = observer((props: TagItemContainerProps) => {
|
||||||
className={`flex flex-row justify-center items-center w-6 h-6 shrink-0 transition-all rotate-0 ${showSubTags && "rotate-90"}`}
|
className={`flex flex-row justify-center items-center w-6 h-6 shrink-0 transition-all rotate-0 ${showSubTags && "rotate-90"}`}
|
||||||
onClick={handleToggleBtnClick}
|
onClick={handleToggleBtnClick}
|
||||||
>
|
>
|
||||||
<ChevronRightIcon className="w-5 h-5 cursor-pointer text-gray-400 dark:text-gray-500" />
|
<ChevronRightIcon className="w-5 h-5 cursor-pointer text-muted-foreground" />
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{hasSubTags ? (
|
{hasSubTags ? (
|
||||||
<div
|
<div
|
||||||
className={`w-[calc(100%-0.5rem)] flex flex-col justify-start items-start h-auto ml-2 pl-2 border-l-2 border-l-gray-200 dark:border-l-zinc-800 ${
|
className={`w-[calc(100%-0.5rem)] flex flex-col justify-start items-start h-auto ml-2 pl-2 border-l-2 border-l-border ${
|
||||||
!showSubTags && "hidden!"
|
!showSubTags && "hidden!"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p className="title-text">{t("setting.account-section.update-information")}</p>
|
<p className="title-text">{t("setting.account-section.update-information")}</p>
|
||||||
<Button variant="ghost" onClick={handleCloseBtnClick}>
|
<Button variant="ghost" onClick={handleCloseBtnClick}>
|
||||||
|
|
@ -168,7 +168,7 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm">
|
<p className="text-sm">
|
||||||
{t("common.username")}
|
{t("common.username")}
|
||||||
<span className="text-sm text-gray-400 ml-1">({t("setting.account-section.username-note")})</span>
|
<span className="text-sm text-muted-foreground ml-1">({t("setting.account-section.username-note")})</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
|
@ -178,7 +178,7 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
|
||||||
/>
|
/>
|
||||||
<p className="text-sm">
|
<p className="text-sm">
|
||||||
{t("common.nickname")}
|
{t("common.nickname")}
|
||||||
<span className="text-sm text-gray-400 ml-1">({t("setting.account-section.nickname-note")})</span>
|
<span className="text-sm text-muted-foreground ml-1">({t("setting.account-section.nickname-note")})</span>
|
||||||
</p>
|
</p>
|
||||||
<Input
|
<Input
|
||||||
className="w-full"
|
className="w-full"
|
||||||
|
|
@ -188,7 +188,7 @@ const UpdateAccountDialog = ({ destroy }: Props) => {
|
||||||
/>
|
/>
|
||||||
<p className="text-sm">
|
<p className="text-sm">
|
||||||
{t("common.email")}
|
{t("common.email")}
|
||||||
<span className="text-sm text-gray-400 ml-1">({t("setting.account-section.email-note")})</span>
|
<span className="text-sm text-muted-foreground ml-1">({t("setting.account-section.email-note")})</span>
|
||||||
</p>
|
</p>
|
||||||
<Input className="w-full" type="email" value={state.email} onChange={handleEmailChanged} />
|
<Input className="w-full" type="email" value={state.email} onChange={handleEmailChanged} />
|
||||||
<p className="text-sm">{t("common.description")}</p>
|
<p className="text-sm">{t("common.description")}</p>
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ const UpdateCustomizedProfileDialog = ({ destroy }: Props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-full shadow flex flex-col justify-start items-start bg-white dark:bg-zinc-800 dark:text-gray-300 p-4 rounded-lg">
|
<div className="max-w-full shadow flex flex-col justify-start items-start bg-card text-card-foreground p-4 rounded-lg">
|
||||||
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
<div className="flex flex-row justify-between items-center mb-4 gap-2 w-full">
|
||||||
<p className="title-text">{t("setting.system-section.customize-server.title")}</p>
|
<p className="title-text">{t("setting.system-section.customize-server.title")}</p>
|
||||||
<Button variant="ghost" onClick={handleCloseButtonClick}>
|
<Button variant="ghost" onClick={handleCloseButtonClick}>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const UserAvatar = (props: Props) => {
|
||||||
return (
|
return (
|
||||||
<div className={cn(`w-8 h-8 overflow-clip rounded-xl`, className)}>
|
<div className={cn(`w-8 h-8 overflow-clip rounded-xl`, className)}>
|
||||||
<img
|
<img
|
||||||
className="w-full h-auto shadow min-w-full min-h-full object-cover dark:opacity-80"
|
className="w-full h-auto shadow min-w-full min-h-full object-cover opacity-80"
|
||||||
src={avatarUrl || "/full-logo.webp"}
|
src={avatarUrl || "/full-logo.webp"}
|
||||||
decoding="async"
|
decoding="async"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,7 @@ const UserBanner = (props: Props) => {
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild disabled={!currentUser}>
|
<PopoverTrigger asChild disabled={!currentUser}>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn("w-auto flex flex-row justify-start items-center cursor-pointer text-foreground", collapsed ? "px-1" : "px-3")}
|
||||||
"w-auto flex flex-row justify-start items-center cursor-pointer text-gray-800 dark:text-gray-400",
|
|
||||||
collapsed ? "px-1" : "px-3",
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
{currentUser.avatarUrl ? (
|
{currentUser.avatarUrl ? (
|
||||||
<UserAvatar className="shrink-0" avatarUrl={currentUser.avatarUrl} />
|
<UserAvatar className="shrink-0" avatarUrl={currentUser.avatarUrl} />
|
||||||
|
|
@ -39,7 +36,7 @@ const UserBanner = (props: Props) => {
|
||||||
<User2Icon className="w-6 mx-auto h-auto opacity-60" />
|
<User2Icon className="w-6 mx-auto h-auto opacity-60" />
|
||||||
)}
|
)}
|
||||||
{!collapsed && (
|
{!collapsed && (
|
||||||
<span className="ml-2 text-lg font-medium text-slate-800 dark:text-gray-300 grow truncate">
|
<span className="ml-2 text-lg font-medium text-foreground grow truncate">
|
||||||
{currentUser.displayName || currentUser.username}
|
{currentUser.displayName || currentUser.username}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
@ -49,35 +46,35 @@ const UserBanner = (props: Props) => {
|
||||||
<div className="flex flex-col text-sm gap-0.5">
|
<div className="flex flex-col text-sm gap-0.5">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigateTo(`/u/${encodeURIComponent(currentUser.username)}`)}
|
onClick={() => navigateTo(`/u/${encodeURIComponent(currentUser.username)}`)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<SquareUserIcon className="w-4 h-auto opacity-60" />
|
<SquareUserIcon className="w-4 h-auto opacity-60" />
|
||||||
<span className="truncate">{t("common.profile")}</span>
|
<span className="truncate">{t("common.profile")}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => navigateTo(Routes.ARCHIVED)}
|
onClick={() => navigateTo(Routes.ARCHIVED)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<ArchiveIcon className="w-4 h-auto opacity-60" />
|
<ArchiveIcon className="w-4 h-auto opacity-60" />
|
||||||
<span className="truncate">{t("common.archived")}</span>
|
<span className="truncate">{t("common.archived")}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => navigateTo(Routes.INBOX)}
|
onClick={() => navigateTo(Routes.INBOX)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<BellIcon className="w-4 h-auto opacity-60" />
|
<BellIcon className="w-4 h-auto opacity-60" />
|
||||||
<span className="truncate">{t("common.inbox")}</span>
|
<span className="truncate">{t("common.inbox")}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => navigateTo(Routes.SETTING)}
|
onClick={() => navigateTo(Routes.SETTING)}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<SettingsIcon className="w-4 h-auto opacity-60" />
|
<SettingsIcon className="w-4 h-auto opacity-60" />
|
||||||
<span className="truncate">{t("common.settings")}</span>
|
<span className="truncate">{t("common.settings")}</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={handleSignOut}
|
onClick={handleSignOut}
|
||||||
className="flex items-center gap-2 px-2 py-1 text-left dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-700 outline-none rounded"
|
className="flex items-center gap-2 px-2 py-1 text-left text-foreground hover:bg-muted outline-none rounded"
|
||||||
>
|
>
|
||||||
<LogOutIcon className="w-4 h-auto opacity-60" />
|
<LogOutIcon className="w-4 h-auto opacity-60" />
|
||||||
<span className="truncate">{t("common.sign-out")}</span>
|
<span className="truncate">{t("common.sign-out")}</span>
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const VisibilityIcon = (props: Props) => {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <VIcon className={cn("w-4 h-auto text-gray-500 dark:text-gray-400", className)} />;
|
return <VIcon className={cn("w-4 h-auto text-muted-foreground", className)} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VisibilityIcon;
|
export default VisibilityIcon;
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const badgeVariants = cva(
|
||||||
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
default: "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
||||||
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
secondary: "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
|
||||||
destructive:
|
destructive:
|
||||||
"border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
"border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||||
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
outline: "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const buttonVariants = cva(
|
||||||
variant: {
|
variant: {
|
||||||
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||||
destructive:
|
destructive:
|
||||||
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||||
outline:
|
outline:
|
||||||
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
||||||
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ function DialogOverlay({ className, ...props }: React.ComponentProps<typeof Dial
|
||||||
<DialogPrimitive.Overlay
|
<DialogPrimitive.Overlay
|
||||||
data-slot="dialog-overlay"
|
data-slot="dialog-overlay"
|
||||||
className={cn(
|
className={cn(
|
||||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-foreground/50",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ function SheetOverlay({ className, ...props }: React.ComponentProps<typeof Sheet
|
||||||
<SheetPrimitive.Overlay
|
<SheetPrimitive.Overlay
|
||||||
data-slot="sheet-overlay"
|
data-slot="sheet-overlay"
|
||||||
className={cn(
|
className={cn(
|
||||||
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-foreground/50",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const HomeLayout = observer(() => {
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed top-0 left-16 shrink-0 h-svh transition-all",
|
"fixed top-0 left-16 shrink-0 h-svh transition-all",
|
||||||
"border-r border-gray-200 dark:border-zinc-800",
|
"border-r border",
|
||||||
lg ? "w-72" : "w-56",
|
lg ? "w-72" : "w-56",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ const RootLayout = observer(() => {
|
||||||
{sm && (
|
{sm && (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"group flex flex-col justify-start items-start fixed top-0 left-0 select-none border-r border-zinc-200 dark:border-zinc-800 h-full bg-zinc-100 dark:bg-zinc-800 dark:bg-opacity-40",
|
"group flex flex-col justify-start items-start fixed top-0 left-0 select-none border-r border h-full bg-secondary",
|
||||||
"w-16 px-2",
|
"w-16 px-2",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import "leaflet/dist/leaflet.css";
|
||||||
const Main = observer(() => (
|
const Main = observer(() => (
|
||||||
<>
|
<>
|
||||||
<RouterProvider router={router} />
|
<RouterProvider router={router} />
|
||||||
<Toaster position="top-right" toastOptions={{ className: "dark:bg-zinc-700 dark:text-gray-300" }} />
|
<Toaster position="top-right" />
|
||||||
</>
|
</>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ const AdminSignIn = observer(() => {
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-black opacity-80 dark:text-gray-200">
|
<p className="ml-2 text-5xl text-foreground opacity-80">
|
||||||
{workspaceGeneralSetting.customProfile?.title || "Memos"}
|
{workspaceGeneralSetting.customProfile?.title || "Memos"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="w-full text-xl font-medium dark:text-gray-500">Sign in with admin accounts</p>
|
<p className="w-full text-xl font-medium text-muted-foreground">Sign in with admin accounts</p>
|
||||||
<PasswordSignInForm />
|
<PasswordSignInForm />
|
||||||
</div>
|
</div>
|
||||||
<AuthFooter />
|
<AuthFooter />
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ const Attachments = observer(() => {
|
||||||
<section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-center sm:pt-3 md:pt-6 pb-8">
|
<section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-center sm:pt-3 md:pt-6 pb-8">
|
||||||
{!md && <MobileHeader />}
|
{!md && <MobileHeader />}
|
||||||
<div className="w-full px-4 sm:px-6">
|
<div className="w-full px-4 sm:px-6">
|
||||||
<div className="w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-800 text-black dark:text-gray-300">
|
<div className="w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-background text-foreground">
|
||||||
<div className="relative w-full flex flex-row justify-between items-center">
|
<div className="relative w-full flex flex-row justify-between items-center">
|
||||||
<p className="py-1 flex flex-row justify-start items-center select-none opacity-80">
|
<p className="py-1 flex flex-row justify-start items-center select-none opacity-80">
|
||||||
<PaperclipIcon className="w-6 h-auto mr-1 opacity-80" />
|
<PaperclipIcon className="w-6 h-auto mr-1 opacity-80" />
|
||||||
|
|
@ -78,7 +78,7 @@ const Attachments = observer(() => {
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div>
|
||||||
<div className="relative max-w-32">
|
<div className="relative max-w-32">
|
||||||
<SearchIcon className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-500" />
|
<SearchIcon className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-muted-foreground" />
|
||||||
<Input
|
<Input
|
||||||
className="pl-9"
|
className="pl-9"
|
||||||
placeholder={t("common.search")}
|
placeholder={t("common.search")}
|
||||||
|
|
@ -98,7 +98,7 @@ const Attachments = observer(() => {
|
||||||
{filteredAttachments.length === 0 ? (
|
{filteredAttachments.length === 0 ? (
|
||||||
<div className="w-full mt-8 mb-8 flex flex-col justify-center items-center italic">
|
<div className="w-full mt-8 mb-8 flex flex-col justify-center items-center italic">
|
||||||
<Empty />
|
<Empty />
|
||||||
<p className="mt-4 text-gray-600 dark:text-gray-400">{t("message.no-data")}</p>
|
<p className="mt-4 text-muted-foreground">{t("message.no-data")}</p>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={"w-full h-auto px-2 flex flex-col justify-start items-start gap-y-8"}>
|
<div className={"w-full h-auto px-2 flex flex-col justify-start items-start gap-y-8"}>
|
||||||
|
|
@ -115,11 +115,11 @@ const Attachments = observer(() => {
|
||||||
{attachments.map((attachment) => {
|
{attachments.map((attachment) => {
|
||||||
return (
|
return (
|
||||||
<div key={attachment.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
|
<div key={attachment.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
|
||||||
<div className="w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border border-zinc-200 dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80">
|
<div className="w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border border-border overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80">
|
||||||
<AttachmentIcon attachment={attachment} strokeWidth={0.5} />
|
<AttachmentIcon attachment={attachment} strokeWidth={0.5} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full max-w-full flex flex-row justify-between items-center mt-1 px-1">
|
<div className="w-full max-w-full flex flex-row justify-between items-center mt-1 px-1">
|
||||||
<p className="text-xs shrink text-gray-400 truncate">{attachment.filename}</p>
|
<p className="text-xs shrink text-muted-foreground truncate">{attachment.filename}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -136,8 +136,8 @@ const Attachments = observer(() => {
|
||||||
<div className="w-16 sm:w-24 sm:pl-4 flex flex-col justify-start items-start"></div>
|
<div className="w-16 sm:w-24 sm:pl-4 flex flex-col justify-start items-start"></div>
|
||||||
<div className="w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap">
|
<div className="w-full max-w-[calc(100%-4rem)] sm:max-w-[calc(100%-6rem)] flex flex-row justify-start items-start gap-4 flex-wrap">
|
||||||
<div className="w-full flex flex-row justify-start items-center gap-2">
|
<div className="w-full flex flex-row justify-start items-center gap-2">
|
||||||
<span className="text-gray-600 dark:text-gray-400">{t("resource.unused-resources")}</span>
|
<span className="text-muted-foreground">{t("resource.unused-resources")}</span>
|
||||||
<span className="text-gray-500 dark:text-gray-500 opacity-80">({unusedAttachments.length})</span>
|
<span className="text-muted-foreground opacity-80">({unusedAttachments.length})</span>
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
|
|
@ -154,11 +154,11 @@ const Attachments = observer(() => {
|
||||||
{unusedAttachments.map((attachment) => {
|
{unusedAttachments.map((attachment) => {
|
||||||
return (
|
return (
|
||||||
<div key={attachment.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
|
<div key={attachment.name} className="w-24 sm:w-32 h-auto flex flex-col justify-start items-start">
|
||||||
<div className="w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border border-zinc-200 dark:border-zinc-900 overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80">
|
<div className="w-24 h-24 flex justify-center items-center sm:w-32 sm:h-32 border border-border overflow-clip rounded-xl cursor-pointer hover:shadow hover:opacity-80">
|
||||||
<AttachmentIcon attachment={attachment} strokeWidth={0.5} />
|
<AttachmentIcon attachment={attachment} strokeWidth={0.5} />
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full max-w-full flex flex-row justify-between items-center mt-1 px-1">
|
<div className="w-full max-w-full flex flex-row justify-between items-center mt-1 px-1">
|
||||||
<p className="text-xs shrink text-gray-400 truncate">{attachment.filename}</p>
|
<p className="text-xs shrink text-muted-foreground truncate">{attachment.filename}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ const AuthCallback = observer(() => {
|
||||||
return (
|
return (
|
||||||
<div className="p-4 py-24 w-full h-full flex justify-center items-center">
|
<div className="p-4 py-24 w-full h-full flex justify-center items-center">
|
||||||
{state.loading ? (
|
{state.loading ? (
|
||||||
<LoaderIcon className="animate-spin dark:text-gray-200" />
|
<LoaderIcon className="animate-spin text-foreground" />
|
||||||
) : (
|
) : (
|
||||||
<div className="max-w-lg font-mono whitespace-pre-wrap opacity-80">{state.errorMessage}</div>
|
<div className="max-w-lg font-mono whitespace-pre-wrap opacity-80">{state.errorMessage}</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ import MemoCommentMessage from "@/components/Inbox/MemoCommentMessage";
|
||||||
import MobileHeader from "@/components/MobileHeader";
|
import MobileHeader from "@/components/MobileHeader";
|
||||||
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
import useResponsiveWidth from "@/hooks/useResponsiveWidth";
|
||||||
import { userStore } from "@/store/v2";
|
import { userStore } from "@/store/v2";
|
||||||
import { Inbox_Status, Inbox_Type } from "@/types/proto/api/v1/inbox_service";
|
import { Inbox, Inbox_Status, Inbox_Type } from "@/types/proto/api/v1/inbox_service";
|
||||||
import { useTranslate } from "@/utils/i18n";
|
import { useTranslate } from "@/utils/i18n";
|
||||||
|
|
||||||
const Inboxes = observer(() => {
|
const Inboxes = observer(() => {
|
||||||
const t = useTranslate();
|
const t = useTranslate();
|
||||||
const { md } = useResponsiveWidth();
|
const { md } = useResponsiveWidth();
|
||||||
|
|
||||||
const inboxes = sortBy(userStore.state.inboxes, (inbox) => {
|
const inboxes = sortBy(userStore.state.inboxes, (inbox: Inbox) => {
|
||||||
if (inbox.status === Inbox_Status.UNREAD) return 0;
|
if (inbox.status === Inbox_Status.UNREAD) return 0;
|
||||||
if (inbox.status === Inbox_Status.ARCHIVED) return 1;
|
if (inbox.status === Inbox_Status.ARCHIVED) return 1;
|
||||||
return 2;
|
return 2;
|
||||||
|
|
@ -36,7 +36,7 @@ const Inboxes = observer(() => {
|
||||||
<section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-center sm:pt-3 md:pt-6 pb-8">
|
<section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-center sm:pt-3 md:pt-6 pb-8">
|
||||||
{!md && <MobileHeader />}
|
{!md && <MobileHeader />}
|
||||||
<div className="w-full px-4 sm:px-6">
|
<div className="w-full px-4 sm:px-6">
|
||||||
<div className="w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-800 text-black dark:text-gray-300">
|
<div className="w-full shadow flex flex-col justify-start items-start px-4 py-3 rounded-xl bg-background text-foreground">
|
||||||
<div className="relative w-full flex flex-row justify-between items-center">
|
<div className="relative w-full flex flex-row justify-between items-center">
|
||||||
<p className="py-1 flex flex-row justify-start items-center select-none opacity-80">
|
<p className="py-1 flex flex-row justify-start items-center select-none opacity-80">
|
||||||
<BellIcon className="w-6 h-auto mr-1 opacity-80" />
|
<BellIcon className="w-6 h-auto mr-1 opacity-80" />
|
||||||
|
|
@ -47,11 +47,11 @@ const Inboxes = observer(() => {
|
||||||
{inboxes.length === 0 && (
|
{inboxes.length === 0 && (
|
||||||
<div className="w-full mt-4 mb-8 flex flex-col justify-center items-center italic">
|
<div className="w-full mt-4 mb-8 flex flex-col justify-center items-center italic">
|
||||||
<Empty />
|
<Empty />
|
||||||
<p className="mt-4 text-gray-600 dark:text-gray-400">{t("message.no-data")}</p>
|
<p className="mt-4 text-muted-foreground">{t("message.no-data")}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col justify-start items-start w-full mt-4 gap-4">
|
<div className="flex flex-col justify-start items-start w-full mt-4 gap-4">
|
||||||
{inboxes.map((inbox) => {
|
{inboxes.map((inbox: Inbox) => {
|
||||||
if (inbox.type === Inbox_Type.MEMO_COMMENT) {
|
if (inbox.type === Inbox_Type.MEMO_COMMENT) {
|
||||||
return <MemoCommentMessage key={`${inbox.name}-${inbox.status}`} inbox={inbox} />;
|
return <MemoCommentMessage key={`${inbox.name}-${inbox.status}`} inbox={inbox} />;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ function Loading() {
|
||||||
return (
|
return (
|
||||||
<div className="fixed w-full h-full flex flex-row justify-center items-center">
|
<div className="fixed w-full h-full flex flex-row justify-center items-center">
|
||||||
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-center items-center">
|
<div className="w-80 max-w-full h-full py-4 flex flex-col justify-center items-center">
|
||||||
<LoaderIcon className="animate-spin dark:text-gray-200" />
|
<LoaderIcon className="animate-spin text-foreground" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ const MemoDetail = observer(() => {
|
||||||
{parentMemo && (
|
{parentMemo && (
|
||||||
<div className="w-auto inline-block mb-2">
|
<div className="w-auto inline-block mb-2">
|
||||||
<Link
|
<Link
|
||||||
className="px-3 py-1 border border-zinc-200 rounded-lg max-w-xs w-auto text-sm flex flex-row justify-start items-center flex-nowrap text-gray-600 dark:text-gray-400 dark:border-gray-500 hover:shadow hover:opacity-80"
|
className="px-3 py-1 border border-border rounded-lg max-w-xs w-auto text-sm flex flex-row justify-start items-center flex-nowrap text-muted-foreground hover:shadow hover:opacity-80"
|
||||||
to={`/${parentMemo.name}`}
|
to={`/${parentMemo.name}`}
|
||||||
state={locationState}
|
state={locationState}
|
||||||
viewTransition
|
viewTransition
|
||||||
|
|
@ -123,8 +123,8 @@ const MemoDetail = observer(() => {
|
||||||
showCreateCommentButton && (
|
showCreateCommentButton && (
|
||||||
<div className="w-full flex flex-row justify-center items-center py-6">
|
<div className="w-full flex flex-row justify-center items-center py-6">
|
||||||
<Button variant="ghost" onClick={handleShowCommentEditor}>
|
<Button variant="ghost" onClick={handleShowCommentEditor}>
|
||||||
<span className="text-gray-500">{t("memo.comment.write-a-comment")}</span>
|
<span className="text-muted-foreground">{t("memo.comment.write-a-comment")}</span>
|
||||||
<MessageCircleIcon className="ml-2 w-5 h-auto text-gray-500" />
|
<MessageCircleIcon className="ml-2 w-5 h-auto text-muted-foreground" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
@ -132,12 +132,12 @@ const MemoDetail = observer(() => {
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-row justify-between items-center h-8 pl-3 mb-2">
|
<div className="w-full flex flex-row justify-between items-center h-8 pl-3 mb-2">
|
||||||
<div className="flex flex-row justify-start items-center">
|
<div className="flex flex-row justify-start items-center">
|
||||||
<MessageCircleIcon className="w-5 h-auto text-gray-400 mr-1" />
|
<MessageCircleIcon className="w-5 h-auto text-muted-foreground mr-1" />
|
||||||
<span className="text-gray-400 text-sm">{t("memo.comment.self")}</span>
|
<span className="text-muted-foreground text-sm">{t("memo.comment.self")}</span>
|
||||||
<span className="text-gray-400 text-sm ml-1">({comments.length})</span>
|
<span className="text-muted-foreground text-sm ml-1">({comments.length})</span>
|
||||||
</div>
|
</div>
|
||||||
{showCreateCommentButton && (
|
{showCreateCommentButton && (
|
||||||
<Button variant="ghost" className="text-gray-500" onClick={handleShowCommentEditor}>
|
<Button variant="ghost" className="text-muted-foreground" onClick={handleShowCommentEditor}>
|
||||||
{t("memo.comment.write-a-comment")}
|
{t("memo.comment.write-a-comment")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const NotFound = () => {
|
||||||
<MobileHeader />
|
<MobileHeader />
|
||||||
<div className="w-full px-4 grow flex flex-col justify-center items-center sm:px-6">
|
<div className="w-full px-4 grow flex flex-col justify-center items-center sm:px-6">
|
||||||
<p className="font-medium">{"The page you are looking for can't be found."}</p>
|
<p className="font-medium">{"The page you are looking for can't be found."}</p>
|
||||||
<p className="mt-4 text-[8rem] font-mono dark:text-gray-300">404</p>
|
<p className="mt-4 text-[8rem] font-mono text-foreground">404</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const PermissionDenied = () => {
|
||||||
<MobileHeader />
|
<MobileHeader />
|
||||||
<div className="w-full px-4 grow flex flex-col justify-center items-center sm:px-6">
|
<div className="w-full px-4 grow flex flex-col justify-center items-center sm:px-6">
|
||||||
<p className="font-medium">Permission denied</p>
|
<p className="font-medium">Permission denied</p>
|
||||||
<p className="mt-4 text-[8rem] font-mono dark:text-gray-300">403</p>
|
<p className="mt-4 text-[8rem] font-mono text-foreground">403</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,9 @@ const Setting = observer(() => {
|
||||||
<section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-start sm:pt-3 md:pt-6 pb-8">
|
<section className="@container w-full max-w-5xl min-h-full flex flex-col justify-start items-start sm:pt-3 md:pt-6 pb-8">
|
||||||
{!md && <MobileHeader />}
|
{!md && <MobileHeader />}
|
||||||
<div className="w-full px-4 sm:px-6">
|
<div className="w-full px-4 sm:px-6">
|
||||||
<div className="w-full shadow flex flex-row justify-start items-start px-4 py-3 rounded-xl bg-white dark:bg-zinc-800 text-gray-600 dark:text-gray-400">
|
<div className="w-full shadow flex flex-row justify-start items-start px-4 py-3 rounded-xl bg-background text-muted-foreground">
|
||||||
<div className="hidden sm:flex flex-col justify-start items-start w-40 h-auto shrink-0 py-2">
|
<div className="hidden sm:flex flex-col justify-start items-start w-40 h-auto shrink-0 py-2">
|
||||||
<span className="text-sm mt-0.5 pl-3 font-mono select-none text-gray-400 dark:text-gray-500">{t("common.basic")}</span>
|
<span className="text-sm mt-0.5 pl-3 font-mono select-none text-muted-foreground">{t("common.basic")}</span>
|
||||||
<div className="w-full flex flex-col justify-start items-start mt-1">
|
<div className="w-full flex flex-col justify-start items-start mt-1">
|
||||||
{BASIC_SECTIONS.map((item) => (
|
{BASIC_SECTIONS.map((item) => (
|
||||||
<SectionMenuItem
|
<SectionMenuItem
|
||||||
|
|
@ -103,7 +103,7 @@ const Setting = observer(() => {
|
||||||
</div>
|
</div>
|
||||||
{isHost ? (
|
{isHost ? (
|
||||||
<>
|
<>
|
||||||
<span className="text-sm mt-4 pl-3 font-mono select-none text-gray-400 dark:text-gray-500">{t("common.admin")}</span>
|
<span className="text-sm mt-4 pl-3 font-mono select-none text-muted-foreground">{t("common.admin")}</span>
|
||||||
<div className="w-full flex flex-col justify-start items-start mt-1">
|
<div className="w-full flex flex-col justify-start items-start mt-1">
|
||||||
{ADMIN_SECTIONS.map((item) => (
|
{ADMIN_SECTIONS.map((item) => (
|
||||||
<SectionMenuItem
|
<SectionMenuItem
|
||||||
|
|
|
||||||
|
|
@ -60,19 +60,19 @@ const SignIn = observer(() => {
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-black opacity-80 dark:text-gray-200">
|
<p className="ml-2 text-5xl text-foreground opacity-80">
|
||||||
{workspaceGeneralSetting.customProfile?.title || "Memos"}
|
{workspaceGeneralSetting.customProfile?.title || "Memos"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{!workspaceGeneralSetting.disallowPasswordAuth ? (
|
{!workspaceGeneralSetting.disallowPasswordAuth ? (
|
||||||
<PasswordSignInForm />
|
<PasswordSignInForm />
|
||||||
) : (
|
) : (
|
||||||
identityProviderList.length == 0 && <p className="w-full text-2xl mt-2 dark:text-gray-500">Password auth is not allowed.</p>
|
identityProviderList.length == 0 && <p className="w-full text-2xl mt-2 text-muted-foreground">Password auth is not allowed.</p>
|
||||||
)}
|
)}
|
||||||
{!workspaceGeneralSetting.disallowUserRegistration && !workspaceGeneralSetting.disallowPasswordAuth && (
|
{!workspaceGeneralSetting.disallowUserRegistration && !workspaceGeneralSetting.disallowPasswordAuth && (
|
||||||
<p className="w-full mt-4 text-sm">
|
<p className="w-full mt-4 text-sm">
|
||||||
<span className="dark:text-gray-500">{t("auth.sign-up-tip")}</span>
|
<span className="text-muted-foreground">{t("auth.sign-up-tip")}</span>
|
||||||
<Link to="/auth/signup" className="cursor-pointer ml-2 text-blue-600 hover:underline" viewTransition>
|
<Link to="/auth/signup" className="cursor-pointer ml-2 text-primary hover:underline" viewTransition>
|
||||||
{t("common.sign-up")}
|
{t("common.sign-up")}
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -90,7 +90,7 @@ const SignIn = observer(() => {
|
||||||
<div className="w-full flex flex-col space-y-2">
|
<div className="w-full flex flex-col space-y-2">
|
||||||
{identityProviderList.map((identityProvider) => (
|
{identityProviderList.map((identityProvider) => (
|
||||||
<Button
|
<Button
|
||||||
className="bg-white dark:bg-black w-full"
|
className="bg-background w-full"
|
||||||
key={identityProvider.name}
|
key={identityProvider.name}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
onClick={() => handleSignInWithIdentityProvider(identityProvider)}
|
onClick={() => handleSignInWithIdentityProvider(identityProvider)}
|
||||||
|
|
|
||||||
|
|
@ -72,19 +72,19 @@ const SignUp = observer(() => {
|
||||||
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
<div className="w-full py-4 grow flex flex-col justify-center items-center">
|
||||||
<div className="w-full flex flex-row justify-center items-center mb-6">
|
<div className="w-full flex flex-row justify-center items-center mb-6">
|
||||||
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
<img className="h-14 w-auto rounded-full shadow" src={workspaceGeneralSetting.customProfile?.logoUrl || "/logo.webp"} alt="" />
|
||||||
<p className="ml-2 text-5xl text-black opacity-80 dark:text-gray-200">
|
<p className="ml-2 text-5xl text-foreground opacity-80">
|
||||||
{workspaceGeneralSetting.customProfile?.title || "Memos"}
|
{workspaceGeneralSetting.customProfile?.title || "Memos"}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{!workspaceGeneralSetting.disallowUserRegistration ? (
|
{!workspaceGeneralSetting.disallowUserRegistration ? (
|
||||||
<>
|
<>
|
||||||
<p className="w-full text-2xl mt-2 dark:text-gray-500">{t("auth.create-your-account")}</p>
|
<p className="w-full text-2xl mt-2 text-muted-foreground">{t("auth.create-your-account")}</p>
|
||||||
<form className="w-full mt-2" onSubmit={handleFormSubmit}>
|
<form className="w-full mt-2" onSubmit={handleFormSubmit}>
|
||||||
<div className="flex flex-col justify-start items-start w-full gap-4">
|
<div className="flex flex-col justify-start items-start w-full gap-4">
|
||||||
<div className="w-full flex flex-col justify-start items-start">
|
<div className="w-full flex flex-col justify-start items-start">
|
||||||
<span className="leading-8 text-gray-600">{t("common.username")}</span>
|
<span className="leading-8 text-muted-foreground">{t("common.username")}</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-full bg-white dark:bg-black h-10"
|
className="w-full bg-background h-10"
|
||||||
type="text"
|
type="text"
|
||||||
readOnly={actionBtnLoadingState.isLoading}
|
readOnly={actionBtnLoadingState.isLoading}
|
||||||
placeholder={t("common.username")}
|
placeholder={t("common.username")}
|
||||||
|
|
@ -97,9 +97,9 @@ const SignUp = observer(() => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full flex flex-col justify-start items-start">
|
<div className="w-full flex flex-col justify-start items-start">
|
||||||
<span className="leading-8 text-gray-600">{t("common.password")}</span>
|
<span className="leading-8 text-muted-foreground">{t("common.password")}</span>
|
||||||
<Input
|
<Input
|
||||||
className="w-full bg-white dark:bg-black h-10"
|
className="w-full bg-background h-10"
|
||||||
type="password"
|
type="password"
|
||||||
readOnly={actionBtnLoadingState.isLoading}
|
readOnly={actionBtnLoadingState.isLoading}
|
||||||
placeholder={t("common.password")}
|
placeholder={t("common.password")}
|
||||||
|
|
@ -121,14 +121,14 @@ const SignUp = observer(() => {
|
||||||
</form>
|
</form>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<p className="w-full text-2xl mt-2 dark:text-gray-500">Sign up is not allowed.</p>
|
<p className="w-full text-2xl mt-2 text-muted-foreground">Sign up is not allowed.</p>
|
||||||
)}
|
)}
|
||||||
{!workspaceStore.state.profile.owner ? (
|
{!workspaceStore.state.profile.owner ? (
|
||||||
<p className="w-full mt-4 text-sm font-medium dark:text-gray-500">{t("auth.host-tip")}</p>
|
<p className="w-full mt-4 text-sm font-medium text-muted-foreground">{t("auth.host-tip")}</p>
|
||||||
) : (
|
) : (
|
||||||
<p className="w-full mt-4 text-sm">
|
<p className="w-full mt-4 text-sm">
|
||||||
<span className="dark:text-gray-500">{t("auth.sign-in-tip")}</span>
|
<span className="text-muted-foreground">{t("auth.sign-in-tip")}</span>
|
||||||
<Link to="/auth" className="cursor-pointer ml-2 text-blue-600 hover:underline" viewTransition>
|
<Link to="/auth" className="cursor-pointer ml-2 text-primary hover:underline" viewTransition>
|
||||||
{t("common.sign-in")}
|
{t("common.sign-in")}
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -89,10 +89,10 @@ const UserProfile = observer(() => {
|
||||||
<div className="w-full flex flex-col justify-start items-start pt-4 pb-8 px-3">
|
<div className="w-full flex flex-col justify-start items-start pt-4 pb-8 px-3">
|
||||||
<UserAvatar className="w-16! h-16! drop-shadow rounded-3xl" avatarUrl={user?.avatarUrl} />
|
<UserAvatar className="w-16! h-16! drop-shadow rounded-3xl" avatarUrl={user?.avatarUrl} />
|
||||||
<div className="mt-2 w-auto max-w-[calc(100%-6rem)] flex flex-col justify-center items-start">
|
<div className="mt-2 w-auto max-w-[calc(100%-6rem)] flex flex-col justify-center items-start">
|
||||||
<p className="w-full text-3xl text-black leading-tight font-medium opacity-80 dark:text-gray-200 truncate">
|
<p className="w-full text-3xl text-foreground leading-tight font-medium opacity-80 truncate">
|
||||||
{user.displayName || user.username}
|
{user.displayName || user.username}
|
||||||
</p>
|
</p>
|
||||||
<p className="w-full text-gray-500 leading-snug dark:text-gray-400 whitespace-pre-wrap truncate line-clamp-6">
|
<p className="w-full text-muted-foreground leading-snug whitespace-pre-wrap truncate line-clamp-6">
|
||||||
{user.description}
|
{user.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
--color-accent: var(--accent);
|
--color-accent: var(--accent);
|
||||||
--color-accent-foreground: var(--accent-foreground);
|
--color-accent-foreground: var(--accent-foreground);
|
||||||
--color-destructive: var(--destructive);
|
--color-destructive: var(--destructive);
|
||||||
|
--color-destructive-foreground: var(--destructive-foreground);
|
||||||
--color-border: var(--border);
|
--color-border: var(--border);
|
||||||
--color-input: var(--input);
|
--color-input: var(--input);
|
||||||
--color-ring: var(--ring);
|
--color-ring: var(--ring);
|
||||||
|
|
@ -48,72 +49,74 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--radius: 0.625rem;
|
--radius: 0.5rem;
|
||||||
--background: oklch(1 0 0);
|
--background: oklch(0.9818 0.0054 95.0986);
|
||||||
--foreground: oklch(0.141 0.005 285.823);
|
--foreground: oklch(0.3438 0.0269 95.7226);
|
||||||
--card: oklch(1 0 0);
|
--card: oklch(0.9818 0.0054 95.0986);
|
||||||
--card-foreground: oklch(0.141 0.005 285.823);
|
--card-foreground: oklch(0.1908 0.0020 106.5859);
|
||||||
--popover: oklch(1 0 0);
|
--popover: oklch(1.0000 0 0);
|
||||||
--popover-foreground: oklch(0.141 0.005 285.823);
|
--popover-foreground: oklch(0.2671 0.0196 98.9390);
|
||||||
--primary: oklch(0.21 0.006 285.885);
|
--primary: oklch(0.6171 0.1375 39.0427);
|
||||||
--primary-foreground: oklch(0.985 0 0);
|
--primary-foreground: oklch(1.0000 0 0);
|
||||||
--secondary: oklch(0.967 0.001 286.375);
|
--secondary: oklch(0.9245 0.0138 92.9892);
|
||||||
--secondary-foreground: oklch(0.21 0.006 285.885);
|
--secondary-foreground: oklch(0.4334 0.0177 98.6048);
|
||||||
--muted: oklch(0.967 0.001 286.375);
|
--muted: oklch(0.9341 0.0153 90.2390);
|
||||||
--muted-foreground: oklch(0.552 0.016 285.938);
|
--muted-foreground: oklch(0.6059 0.0075 97.4233);
|
||||||
--accent: oklch(0.967 0.001 286.375);
|
--accent: oklch(0.9245 0.0138 92.9892);
|
||||||
--accent-foreground: oklch(0.21 0.006 285.885);
|
--accent-foreground: oklch(0.2671 0.0196 98.9390);
|
||||||
--destructive: oklch(0.577 0.245 27.325);
|
--destructive: oklch(0.1908 0.0020 106.5859);
|
||||||
--border: oklch(0.92 0.004 286.32);
|
--destructive-foreground: oklch(1.0000 0 0);
|
||||||
--input: oklch(0.92 0.004 286.32);
|
--border: oklch(0.8847 0.0069 97.3627);
|
||||||
--ring: oklch(0.705 0.015 286.067);
|
--input: oklch(0.7621 0.0156 98.3528);
|
||||||
--chart-1: oklch(0.646 0.222 41.116);
|
--ring: oklch(0.5937 0.1673 253.0630);
|
||||||
--chart-2: oklch(0.6 0.118 184.704);
|
--chart-1: oklch(0.5583 0.1276 42.9956);
|
||||||
--chart-3: oklch(0.398 0.07 227.392);
|
--chart-2: oklch(0.6898 0.1581 290.4107);
|
||||||
--chart-4: oklch(0.828 0.189 84.429);
|
--chart-3: oklch(0.8816 0.0276 93.1280);
|
||||||
--chart-5: oklch(0.769 0.188 70.08);
|
--chart-4: oklch(0.8822 0.0403 298.1792);
|
||||||
--sidebar: oklch(0.985 0 0);
|
--chart-5: oklch(0.5608 0.1348 42.0584);
|
||||||
--sidebar-foreground: oklch(0.141 0.005 285.823);
|
--sidebar: oklch(0.9663 0.0080 98.8792);
|
||||||
--sidebar-primary: oklch(0.21 0.006 285.885);
|
--sidebar-foreground: oklch(0.3590 0.0051 106.6524);
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
--sidebar-primary: oklch(0.6171 0.1375 39.0427);
|
||||||
--sidebar-accent: oklch(0.967 0.001 286.375);
|
--sidebar-primary-foreground: oklch(0.9881 0 0);
|
||||||
--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
|
--sidebar-accent: oklch(0.9245 0.0138 92.9892);
|
||||||
--sidebar-border: oklch(0.92 0.004 286.32);
|
--sidebar-accent-foreground: oklch(0.3250 0 0);
|
||||||
--sidebar-ring: oklch(0.705 0.015 286.067);
|
--sidebar-border: oklch(0.9401 0 0);
|
||||||
|
--sidebar-ring: oklch(0.7731 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
--background: oklch(0.141 0.005 285.823);
|
--background: oklch(0.2679 0.0036 106.6427);
|
||||||
--foreground: oklch(0.985 0 0);
|
--foreground: oklch(0.8074 0.0142 93.0137);
|
||||||
--card: oklch(0.21 0.006 285.885);
|
--card: oklch(0.2679 0.0036 106.6427);
|
||||||
--card-foreground: oklch(0.985 0 0);
|
--card-foreground: oklch(0.9818 0.0054 95.0986);
|
||||||
--popover: oklch(0.21 0.006 285.885);
|
--popover: oklch(0.3085 0.0035 106.6039);
|
||||||
--popover-foreground: oklch(0.985 0 0);
|
--popover-foreground: oklch(0.9211 0.0040 106.4781);
|
||||||
--primary: oklch(0.92 0.004 286.32);
|
--primary: oklch(0.6724 0.1308 38.7559);
|
||||||
--primary-foreground: oklch(0.21 0.006 285.885);
|
--primary-foreground: oklch(1.0000 0 0);
|
||||||
--secondary: oklch(0.274 0.006 286.033);
|
--secondary: oklch(0.9818 0.0054 95.0986);
|
||||||
--secondary-foreground: oklch(0.985 0 0);
|
--secondary-foreground: oklch(0.3085 0.0035 106.6039);
|
||||||
--muted: oklch(0.274 0.006 286.033);
|
--muted: oklch(0.2213 0.0038 106.7070);
|
||||||
--muted-foreground: oklch(0.705 0.015 286.067);
|
--muted-foreground: oklch(0.7713 0.0169 99.0657);
|
||||||
--accent: oklch(0.274 0.006 286.033);
|
--accent: oklch(0.2130 0.0078 95.4245);
|
||||||
--accent-foreground: oklch(0.985 0 0);
|
--accent-foreground: oklch(0.9663 0.0080 98.8792);
|
||||||
--destructive: oklch(0.704 0.191 22.216);
|
--destructive: oklch(0.6368 0.2078 25.3313);
|
||||||
--border: oklch(1 0 0 / 10%);
|
--destructive-foreground: oklch(1.0000 0 0);
|
||||||
--input: oklch(1 0 0 / 15%);
|
--border: oklch(0.3618 0.0101 106.8928);
|
||||||
--ring: oklch(0.552 0.016 285.938);
|
--input: oklch(0.4336 0.0113 100.2195);
|
||||||
--chart-1: oklch(0.488 0.243 264.376);
|
--ring: oklch(0.5937 0.1673 253.0630);
|
||||||
--chart-2: oklch(0.696 0.17 162.48);
|
--chart-1: oklch(0.5583 0.1276 42.9956);
|
||||||
--chart-3: oklch(0.769 0.188 70.08);
|
--chart-2: oklch(0.6898 0.1581 290.4107);
|
||||||
--chart-4: oklch(0.627 0.265 303.9);
|
--chart-3: oklch(0.2130 0.0078 95.4245);
|
||||||
--chart-5: oklch(0.645 0.246 16.439);
|
--chart-4: oklch(0.3074 0.0516 289.3230);
|
||||||
--sidebar: oklch(0.21 0.006 285.885);
|
--chart-5: oklch(0.5608 0.1348 42.0584);
|
||||||
--sidebar-foreground: oklch(0.985 0 0);
|
--sidebar: oklch(0.2357 0.0024 67.7077);
|
||||||
--sidebar-primary: oklch(0.488 0.243 264.376);
|
--sidebar-foreground: oklch(0.8074 0.0142 93.0137);
|
||||||
--sidebar-primary-foreground: oklch(0.985 0 0);
|
--sidebar-primary: oklch(0.3250 0 0);
|
||||||
--sidebar-accent: oklch(0.274 0.006 286.033);
|
--sidebar-primary-foreground: oklch(0.9881 0 0);
|
||||||
--sidebar-accent-foreground: oklch(0.985 0 0);
|
--sidebar-accent: oklch(0.1680 0.0020 106.6177);
|
||||||
--sidebar-border: oklch(1 0 0 / 10%);
|
--sidebar-accent-foreground: oklch(0.8074 0.0142 93.0137);
|
||||||
--sidebar-ring: oklch(0.552 0.016 285.938);
|
--sidebar-border: oklch(0.9401 0 0);
|
||||||
|
--sidebar-ring: oklch(0.7731 0 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue