mirror of
https://github.com/usememos/memos.git
synced 2025-02-15 02:40:53 +01:00
chore: tweak setting page
This commit is contained in:
parent
a1dda913c3
commit
1994c20c54
@ -56,15 +56,15 @@ const AccessTokenSection = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mt-8 w-full flex flex-col justify-start items-start space-y-4">
|
||||
<div className="mt-4 w-full flex flex-col justify-start items-start space-y-4">
|
||||
<div className="w-full">
|
||||
<div className="sm:flex sm:items-center sm:justify-between">
|
||||
<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-300">
|
||||
<p className="flex flex-row justify-start items-center font-medium text-gray-700 dark:text-gray-400">
|
||||
Access Tokens
|
||||
<LearnMore className="ml-2" url="https://usememos.com/docs/security/access-tokens" />
|
||||
</p>
|
||||
<p className="text-sm text-gray-700 dark:text-gray-400">A list of all access tokens for your account.</p>
|
||||
<p className="text-sm text-gray-700 dark:text-gray-500">A list of all access tokens for your account.</p>
|
||||
</div>
|
||||
<div className="mt-4 sm:mt-0">
|
||||
<Button
|
||||
@ -81,19 +81,19 @@ const AccessTokenSection = () => {
|
||||
<div className="mt-2 flow-root">
|
||||
<div className="overflow-x-auto">
|
||||
<div className="inline-block min-w-full py-2 align-middle">
|
||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-gray-400">
|
||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-600">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" className="px-3 py-3.5 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-gray-900 dark:text-gray-400">
|
||||
Token
|
||||
</th>
|
||||
<th scope="col" className="py-3.5 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-gray-900 dark:text-gray-400">
|
||||
Description
|
||||
</th>
|
||||
<th scope="col" className="px-3 py-3.5 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-gray-900 dark:text-gray-400">
|
||||
Created At
|
||||
</th>
|
||||
<th scope="col" className="px-3 py-3.5 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-gray-900 dark:text-gray-400">
|
||||
Expires At
|
||||
</th>
|
||||
<th scope="col" className="relative py-3.5 pl-3 pr-4">
|
||||
@ -101,10 +101,10 @@ const AccessTokenSection = () => {
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200 dark:divide-gray-500">
|
||||
<tbody className="divide-y divide-gray-200 dark:divide-zinc-700">
|
||||
{userAccessTokens.map((userAccessToken) => (
|
||||
<tr key={userAccessToken.accessToken}>
|
||||
<td className="whitespace-nowrap px-3 py-4 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-gray-900 dark:text-gray-400 flex flex-row justify-start items-center gap-x-1">
|
||||
<span className="font-mono">{getFormatedAccessToken(userAccessToken.accessToken)}</span>
|
||||
<IconButton
|
||||
color="neutral"
|
||||
@ -115,16 +115,16 @@ const AccessTokenSection = () => {
|
||||
<Icon.Clipboard className="w-4 h-auto text-gray-400" />
|
||||
</IconButton>
|
||||
</td>
|
||||
<td className="whitespace-nowrap py-4 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-gray-900 dark:text-gray-400">
|
||||
{userAccessToken.description}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400">
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
{userAccessToken.issuedAt?.toLocaleString()}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500 dark:text-gray-400">
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
{userAccessToken.expiresAt?.toLocaleString() ?? "Never"}
|
||||
</td>
|
||||
<td className="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm">
|
||||
<td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm">
|
||||
<IconButton
|
||||
color="danger"
|
||||
variant="plain"
|
||||
|
@ -121,8 +121,8 @@ const MemberSection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="section-container member-section-container">
|
||||
<p className="title-text">{t("setting.member-section.create-a-member")}</p>
|
||||
<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>
|
||||
<div className="w-full flex flex-col justify-start items-start gap-2">
|
||||
<div className="flex flex-col justify-start items-start gap-1">
|
||||
<span className="text-sm">{t("common.username")}</span>
|
||||
@ -140,10 +140,10 @@ const MemberSection = () => {
|
||||
<div className="title-text">{t("setting.member-list")}</div>
|
||||
</div>
|
||||
<div className="w-full overflow-x-auto">
|
||||
<div className="inline-block min-w-full align-middle border rounded-lg dark:border-gray-500">
|
||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-gray-500">
|
||||
<div className="inline-block min-w-full align-middle border rounded-lg dark:border-zinc-600">
|
||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-600">
|
||||
<thead>
|
||||
<tr className="text-sm font-semibold text-left text-gray-900 dark:text-gray-300">
|
||||
<tr className="text-sm font-semibold text-left text-gray-900 dark:text-gray-400">
|
||||
<th scope="col" className="py-2 pl-4 pr-3">
|
||||
ID
|
||||
</th>
|
||||
@ -159,16 +159,16 @@ const MemberSection = () => {
|
||||
<th scope="col" className="relative py-2 pl-3 pr-4"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200 dark:divide-gray-500">
|
||||
<tbody className="divide-y divide-gray-200 dark:divide-zinc-600">
|
||||
{userList.map((user) => (
|
||||
<tr key={user.id}>
|
||||
<td className="whitespace-nowrap py-2 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-300">{user.id}</td>
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-300">
|
||||
<td className="whitespace-nowrap py-2 pl-4 pr-3 text-sm text-gray-900 dark:text-gray-400">{user.id}</td>
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">
|
||||
{user.username}
|
||||
<span className="ml-1 italic">{user.rowStatus === RowStatus.ARCHIVED && "(Archived)"}</span>
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-300">{user.nickname}</td>
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-300">{user.email}</td>
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.nickname}</td>
|
||||
<td className="whitespace-nowrap px-3 py-2 text-sm text-gray-500 dark:text-gray-400">{user.email}</td>
|
||||
<td className="relative whitespace-nowrap py-2 pl-3 pr-4 text-right text-sm font-medium flex justify-end">
|
||||
{currentUser?.id === user.id ? (
|
||||
<span>{t("common.yourself")}</span>
|
||||
|
@ -11,28 +11,26 @@ const MyAccountSection = () => {
|
||||
const user = useCurrentUser();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section-container account-section-container">
|
||||
<p className="font-medium my-2 text-gray-700 dark:text-gray-400">{t("setting.account-section.title")}</p>
|
||||
<div className="flex flex-row justify-start items-center">
|
||||
<UserAvatar className="mr-2 w-14 h-14" avatarUrl={user.avatarUrl} />
|
||||
<div className="flex flex-col justify-center items-start">
|
||||
<span className="text-2xl font-medium">{user.nickname}</span>
|
||||
<span className="-mt-2 text-base text-gray-500 dark:text-gray-400">({user.username})</span>
|
||||
</div>
|
||||
<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>
|
||||
<div className="mt-1 flex flex-row justify-start items-center">
|
||||
<UserAvatar className="mr-2" avatarUrl={user.avatarUrl} />
|
||||
<div className="flex flex-col justify-center items-start">
|
||||
<span className="text-2xl font-medium">{user.nickname}</span>
|
||||
<span className="-mt-2 text-base text-gray-500 dark:text-gray-400">({user.username})</span>
|
||||
</div>
|
||||
<div className="w-full flex flex-row justify-start items-center mt-4 space-x-2">
|
||||
<Button variant="outlined" onClick={showUpdateAccountDialog}>
|
||||
{t("common.edit")}
|
||||
</Button>
|
||||
<Button variant="outlined" onClick={showChangePasswordDialog}>
|
||||
{t("setting.account-section.change-password")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<AccessTokenSection />
|
||||
</div>
|
||||
</>
|
||||
<div className="w-full flex flex-row justify-start items-center mt-2 space-x-2">
|
||||
<Button variant="outlined" onClick={showUpdateAccountDialog}>
|
||||
{t("common.edit")}
|
||||
</Button>
|
||||
<Button variant="outlined" onClick={showChangePasswordDialog}>
|
||||
{t("setting.account-section.change-password")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<AccessTokenSection />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,6 @@ import Icon from "../Icon";
|
||||
import LocaleSelect from "../LocaleSelect";
|
||||
import VisibilityIcon from "../VisibilityIcon";
|
||||
import WebhookSection from "./WebhookSection";
|
||||
import "@/less/settings/preferences-section.less";
|
||||
|
||||
const PreferencesSection = () => {
|
||||
const t = useTranslate();
|
||||
@ -72,19 +71,19 @@ const PreferencesSection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="section-container preferences-section-container">
|
||||
<p className="title-text">{t("common.basic")}</p>
|
||||
<div className="form-label selector">
|
||||
<span className="text-sm">{t("common.language")}</span>
|
||||
<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>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span>{t("common.language")}</span>
|
||||
<LocaleSelect value={locale} onChange={handleLocaleSelectChange} />
|
||||
</div>
|
||||
<div className="form-label selector">
|
||||
<span className="text-sm">{t("setting.preference-section.theme")}</span>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span>{t("setting.preference-section.theme")}</span>
|
||||
<AppearanceSelect value={appearance} onChange={handleAppearanceSelectChange} />
|
||||
</div>
|
||||
<p className="title-text">{t("setting.preference")}</p>
|
||||
<div className="form-label selector">
|
||||
<span className="text-sm break-keep text-ellipsis overflow-hidden">{t("setting.preference-section.default-memo-visibility")}</span>
|
||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("setting.preference")}</p>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="truncate">{t("setting.preference-section.default-memo-visibility")}</span>
|
||||
<Select
|
||||
className="!min-w-fit"
|
||||
value={setting.memoVisibility}
|
||||
@ -110,7 +109,7 @@ const PreferencesSection = () => {
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<div className="mb-2 w-full flex flex-row justify-between items-center">
|
||||
<div className="w-auto flex items-center">
|
||||
<span className="text-sm mr-1">{t("setting.preference-section.telegram-user-id")}</span>
|
||||
<span className="mr-1">{t("setting.preference-section.telegram-user-id")}</span>
|
||||
</div>
|
||||
<Button variant="outlined" color="neutral" onClick={handleSaveTelegramUserId}>
|
||||
{t("common.save")}
|
||||
|
@ -57,10 +57,10 @@ const SSOSection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="section-container">
|
||||
<div className="mb-2 w-full flex flex-row justify-between items-center gap-1">
|
||||
<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="flex flex-row items-center gap-1">
|
||||
<span className="font-mono text-sm text-gray-400">{t("setting.sso-section.sso-list")}</span>
|
||||
<span className="font-mono text-gray-400">{t("setting.sso-section.sso-list")}</span>
|
||||
<LearnMore url="https://usememos.com/docs/advanced-settings/keycloak" />
|
||||
</div>
|
||||
<Button onClick={() => showCreateIdentityProviderDialog(undefined, fetchIdentityProviderList)}>{t("common.create")}</Button>
|
||||
@ -100,8 +100,13 @@ const SSOSection = () => {
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{identityProviderList.length === 0 && (
|
||||
<div className="w-full mt-2 text-sm dark:border-zinc-700 opacity-60 flex flex-row items-center justify-between">
|
||||
<p className="">No SSO found.</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="w-full mt-8">
|
||||
<div className="w-full mt-4">
|
||||
<p className="text-sm">{t("common.learn-more")}:</p>
|
||||
<List component="ul" marker="disc" size="sm">
|
||||
<ListItem>
|
||||
|
@ -60,9 +60,9 @@ const StorageSection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="section-container">
|
||||
<div className="mt-4 mb-2 w-full flex flex-row justify-start items-center">
|
||||
<span className="font-mono text-sm text-gray-400 mr-2">{t("setting.storage-section.current-storage")}</span>
|
||||
<div className="w-full flex flex-col gap-2 pt-2 pb-4">
|
||||
<div className="w-full flex flex-row justify-start items-center">
|
||||
<span className="font-mono text-sm text-gray-400 mr-2 dark:text-gray-500">{t("setting.storage-section.current-storage")}</span>
|
||||
</div>
|
||||
<RadioGroup
|
||||
className="w-full"
|
||||
@ -82,7 +82,7 @@ const StorageSection = () => {
|
||||
<Radio key={storage.id} value={storage.id} label={storage.name} />
|
||||
))}
|
||||
</RadioGroup>
|
||||
<Divider className="!my-4" />
|
||||
<Divider className="!my-2" />
|
||||
<div className="mb-2 w-full flex flex-row justify-between items-center gap-1">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="font-mono text-sm text-gray-400">{t("setting.storage-section.storage-services")}</span>
|
||||
@ -90,7 +90,7 @@ const StorageSection = () => {
|
||||
</div>
|
||||
<Button onClick={() => showCreateStorageServiceDialog(undefined, fetchStorageList)}>{t("common.create")}</Button>
|
||||
</div>
|
||||
<div className="mt-2 w-full flex flex-col">
|
||||
<div className="w-full flex flex-col">
|
||||
{storageList.map((storage) => (
|
||||
<div
|
||||
key={storage.id}
|
||||
@ -123,7 +123,7 @@ const StorageSection = () => {
|
||||
</div>
|
||||
))}
|
||||
{storageList.length === 0 && (
|
||||
<div className="pb-2 w-full text-sm dark:border-zinc-700 opacity-60 flex flex-row items-center justify-between">
|
||||
<div className="w-full text-sm dark:border-zinc-700 opacity-60 flex flex-row items-center justify-between">
|
||||
<p className="">No storage service found.</p>
|
||||
</div>
|
||||
)}
|
||||
|
@ -10,7 +10,6 @@ import { showCommonDialog } from "../Dialog/CommonDialog";
|
||||
import showDisablePasswordLoginDialog from "../DisablePasswordLoginDialog";
|
||||
import Icon from "../Icon";
|
||||
import showUpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog";
|
||||
import "@/less/settings/system-section.less";
|
||||
|
||||
interface State {
|
||||
dbSize: number;
|
||||
@ -244,38 +243,38 @@ const SystemSection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="section-container system-section-container">
|
||||
<p className="title-text">{t("common.basic")}</p>
|
||||
<div className="form-label">
|
||||
<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>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="normal-text">
|
||||
{t("setting.system-section.server-name")}: <span className="font-mono font-bold">{systemStatus.customizedProfile.name}</span>
|
||||
</div>
|
||||
<Button onClick={handleUpdateCustomizedProfileButtonClick}>{t("common.edit")}</Button>
|
||||
</div>
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="text-sm">
|
||||
{t("setting.system-section.database-file-size")}: <span className="font-mono font-bold">{formatBytes(state.dbSize)}</span>
|
||||
</span>
|
||||
<Button onClick={handleVacuumBtnClick}>{t("common.vacuum")}</Button>
|
||||
</div>
|
||||
<p className="title-text">{t("common.settings")}</p>
|
||||
<div className="form-label">
|
||||
<p className="font-medium text-gray-700 dark:text-gray-500">{t("common.settings")}</p>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="normal-text">{t("setting.system-section.allow-user-signup")}</span>
|
||||
<Switch checked={state.allowSignUp} onChange={(event) => handleAllowSignUpChanged(event.target.checked)} />
|
||||
</div>
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="normal-text">{t("setting.system-section.disable-password-login")}</span>
|
||||
<Switch checked={state.disablePasswordLogin} onChange={(event) => handleDisablePasswordLoginChanged(event.target.checked)} />
|
||||
</div>
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="normal-text">{t("setting.system-section.disable-public-memos")}</span>
|
||||
<Switch checked={state.disablePublicMemos} onChange={(event) => handleDisablePublicMemosChanged(event.target.checked)} />
|
||||
</div>
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="normal-text">{t("setting.system-section.display-with-updated-time")}</span>
|
||||
<Switch checked={state.memoDisplayWithUpdatedTs} onChange={(event) => handleMemoDisplayWithUpdatedTs(event.target.checked)} />
|
||||
</div>
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row items-center">
|
||||
<span className="text-sm mr-1">{t("setting.system-section.max-upload-size")}</span>
|
||||
<Tooltip title={t("setting.system-section.max-upload-size-hint")} placement="top">
|
||||
@ -293,7 +292,7 @@ const SystemSection = () => {
|
||||
/>
|
||||
</div>
|
||||
<Divider className="!mt-3 !my-4" />
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="w-auto flex items-center">
|
||||
<span className="text-sm mr-1">Instance URL</span>
|
||||
@ -324,7 +323,7 @@ const SystemSection = () => {
|
||||
</Link>
|
||||
</div>
|
||||
<Divider className="!mt-3 !my-4" />
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row items-center">
|
||||
<div className="w-auto flex items-center">
|
||||
<span className="text-sm mr-1">{t("setting.system-section.telegram-bot-token")}</span>
|
||||
@ -355,7 +354,7 @@ const SystemSection = () => {
|
||||
</Link>
|
||||
</div>
|
||||
<Divider className="!mt-3 !my-4" />
|
||||
<div className="form-label">
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span className="normal-text">{t("setting.system-section.additional-style")}</span>
|
||||
<Button variant="outlined" color="neutral" onClick={handleSaveAdditionalStyle}>
|
||||
{t("common.save")}
|
||||
@ -373,7 +372,7 @@ const SystemSection = () => {
|
||||
value={state.additionalStyle}
|
||||
onChange={(event) => handleAdditionalStyleChanged(event.target.value)}
|
||||
/>
|
||||
<div className="form-label mt-2">
|
||||
<div className="w-full flex flex-row justify-between items-center mt-2">
|
||||
<span className="normal-text">{t("setting.system-section.additional-script")}</span>
|
||||
<Button variant="outlined" color="neutral" onClick={handleSaveAdditionalScript}>
|
||||
{t("common.save")}
|
||||
|
@ -49,7 +49,7 @@ const WebhookSection = () => {
|
||||
<div className="w-full flex flex-col justify-start items-start">
|
||||
<div className="w-full flex justify-between items-center">
|
||||
<div className="flex-auto space-y-1">
|
||||
<p className="flex flex-row justify-start items-center font-medium text-gray-700 dark:text-gray-300">Webhooks</p>
|
||||
<p className="flex flex-row justify-start items-center font-medium text-gray-700 dark:text-gray-400">Webhooks</p>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
@ -65,8 +65,8 @@ const WebhookSection = () => {
|
||||
</div>
|
||||
<div className="w-full mt-2 flow-root">
|
||||
<div className="overflow-x-auto">
|
||||
<div className="inline-block min-w-full border rounded-lg align-middle dark:border-gray-500">
|
||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-gray-500">
|
||||
<div className="inline-block min-w-full border rounded-lg align-middle dark:border-zinc-600">
|
||||
<table className="min-w-full divide-y divide-gray-300 dark:divide-zinc-600">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" className="px-3 py-2 text-left text-sm font-semibold text-gray-900 dark:text-gray-400">
|
||||
|
@ -1,47 +0,0 @@
|
||||
.setting-page-wrapper {
|
||||
@apply flex flex-row justify-start items-start relative w-full h-full shadow p-4 rounded-lg bg-white dark:bg-zinc-800 dark:text-gray-300 sm:gap-x-4;
|
||||
|
||||
> .section-selector-container {
|
||||
@apply hidden sm:flex flex-col justify-start items-start sm:w-40 h-auto sm:h-full shrink-0 pb-2 border-r dark:border-r-zinc-600;
|
||||
|
||||
> .section-title {
|
||||
@apply text-sm mt-2 sm:mt-4 first:mt-2 mb-1 font-mono text-gray-400;
|
||||
}
|
||||
|
||||
> .section-items-container {
|
||||
@apply w-full h-auto flex flex-row sm:flex-col justify-start items-start;
|
||||
|
||||
> .section-item {
|
||||
@apply flex flex-row justify-start items-center text-base select-none mr-3 sm:mr-0 mt-0 sm:mt-2 text-gray-700 dark:text-gray-400 cursor-pointer hover:opacity-80;
|
||||
|
||||
&.selected {
|
||||
@apply font-bold dark:text-gray-300 hover:opacity-100;
|
||||
}
|
||||
|
||||
> .icon-text {
|
||||
@apply text-base mr-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> .section-content-container {
|
||||
@apply w-full sm:w-auto pl-2 pb-4 grow flex flex-col justify-start items-start h-full;
|
||||
|
||||
> .section-container {
|
||||
@apply flex flex-col justify-start items-start w-full;
|
||||
|
||||
.title-text {
|
||||
@apply text-sm mt-4 first:mt-2 mb-3 font-mono text-gray-500 dark:text-gray-400;
|
||||
}
|
||||
|
||||
> .form-label {
|
||||
@apply flex flex-row items-center w-full mb-2;
|
||||
|
||||
> .normal-text {
|
||||
@apply shrink-0 select-text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
.preferences-section-container {
|
||||
> .title-text {
|
||||
@apply mt-4 first:mt-1;
|
||||
}
|
||||
|
||||
> .form-label.selector {
|
||||
@apply mb-2 flex flex-row justify-between items-center;
|
||||
|
||||
> .normal-text {
|
||||
@apply mr-2 text-sm;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
.system-section-container {
|
||||
> .title-text {
|
||||
@apply mt-4 first:mt-1;
|
||||
}
|
||||
|
||||
> .text-value {
|
||||
@apply mr-2 text-sm;
|
||||
}
|
||||
|
||||
> .form-label {
|
||||
@apply mb-2 flex flex-row justify-between items-center;
|
||||
|
||||
> .normal-text {
|
||||
@apply mr-2 text-sm;
|
||||
}
|
||||
}
|
||||
}
|
@ -9,9 +9,9 @@ import SSOSection from "@/components/Settings/SSOSection";
|
||||
import StorageSection from "@/components/Settings/StorageSection";
|
||||
import SystemSection from "@/components/Settings/SystemSection";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useGlobalStore } from "@/store/module";
|
||||
import { User_Role } from "@/types/proto/api/v2/user_service";
|
||||
import { useTranslate } from "@/utils/i18n";
|
||||
import "@/less/setting.less";
|
||||
|
||||
type SettingSection = "my-account" | "preference" | "member" | "system" | "storage" | "sso";
|
||||
|
||||
@ -22,6 +22,7 @@ interface State {
|
||||
const Setting = () => {
|
||||
const t = useTranslate();
|
||||
const user = useCurrentUser();
|
||||
const globalStore = useGlobalStore();
|
||||
const [state, setState] = useState<State>({
|
||||
selectedSection: "my-account",
|
||||
});
|
||||
@ -45,58 +46,71 @@ const Setting = () => {
|
||||
<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">
|
||||
<MobileHeader />
|
||||
<div className="w-full px-4 sm:px-6">
|
||||
<div className="setting-page-wrapper">
|
||||
<div className="section-selector-container">
|
||||
<span className="section-title">{t("common.basic")}</span>
|
||||
<div className="section-items-container">
|
||||
<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="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 text-gray-400 dark:text-gray-500">{t("common.basic")}</span>
|
||||
<div className="w-full flex flex-col justify-start items-start mt-1">
|
||||
<span
|
||||
className={`w-auto px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg hover:opacity-80 ${
|
||||
state.selectedSection === "my-account" ? "bg-zinc-100 shadow dark:bg-zinc-900" : ""
|
||||
}`}
|
||||
onClick={() => handleSectionSelectorItemClick("my-account")}
|
||||
className={`section-item ${state.selectedSection === "my-account" ? "selected" : ""}`}
|
||||
>
|
||||
<Icon.User className="w-4 h-auto mr-2 opacity-80" /> {t("setting.my-account")}
|
||||
</span>
|
||||
<span
|
||||
className={`w-auto px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg hover:opacity-80 ${
|
||||
state.selectedSection === "preference" ? "bg-zinc-100 shadow dark:bg-zinc-900" : ""
|
||||
}`}
|
||||
onClick={() => handleSectionSelectorItemClick("preference")}
|
||||
className={`section-item ${state.selectedSection === "preference" ? "selected" : ""}`}
|
||||
>
|
||||
<Icon.Cog className="w-4 h-auto mr-2 opacity-80" /> {t("setting.preference")}
|
||||
</span>
|
||||
</div>
|
||||
{isHost ? (
|
||||
<>
|
||||
<span className="section-title">{t("common.admin")}</span>
|
||||
<div className="section-items-container">
|
||||
<span className="text-sm mt-4 pl-3 font-mono text-gray-400 dark:text-gray-500">{t("common.admin")}</span>
|
||||
<div className="w-full flex flex-col justify-start items-start mt-1">
|
||||
<span
|
||||
onClick={() => handleSectionSelectorItemClick("member")}
|
||||
className={`section-item ${state.selectedSection === "member" ? "selected" : ""}`}
|
||||
className={`w-auto px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg hover:opacity-80 ${
|
||||
state.selectedSection === "member" ? "bg-zinc-100 shadow dark:bg-zinc-900" : ""
|
||||
}`}
|
||||
>
|
||||
<Icon.Users className="w-4 h-auto mr-2 opacity-80" /> {t("setting.member")}
|
||||
</span>
|
||||
<span
|
||||
onClick={() => handleSectionSelectorItemClick("system")}
|
||||
className={`section-item ${state.selectedSection === "system" ? "selected" : ""}`}
|
||||
className={`w-auto px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg hover:opacity-80 ${
|
||||
state.selectedSection === "system" ? "bg-zinc-100 shadow dark:bg-zinc-900" : ""
|
||||
}`}
|
||||
>
|
||||
<Icon.Settings2 className="w-4 h-auto mr-2 opacity-80" /> {t("setting.system")}
|
||||
</span>
|
||||
<span
|
||||
onClick={() => handleSectionSelectorItemClick("storage")}
|
||||
className={`section-item ${state.selectedSection === "storage" ? "selected" : ""}`}
|
||||
className={`w-auto px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg hover:opacity-80 ${
|
||||
state.selectedSection === "storage" ? "bg-zinc-100 shadow dark:bg-zinc-900" : ""
|
||||
}`}
|
||||
>
|
||||
<Icon.Database className="w-4 h-auto mr-2 opacity-80" /> {t("setting.storage")}
|
||||
</span>
|
||||
<span
|
||||
onClick={() => handleSectionSelectorItemClick("sso")}
|
||||
className={`section-item ${state.selectedSection === "sso" ? "selected" : ""}`}
|
||||
className={`w-auto px-3 leading-8 flex flex-row justify-start items-center cursor-pointer rounded-lg hover:opacity-80 ${
|
||||
state.selectedSection === "sso" ? "bg-zinc-100 shadow dark:bg-zinc-900" : ""
|
||||
}`}
|
||||
>
|
||||
<Icon.Key className="w-4 h-auto mr-2 opacity-80" /> {t("setting.sso")}
|
||||
</span>
|
||||
<span className="px-3 mt-2 opacity-70 text-sm">Version: v{globalStore.state.systemStatus.profile.version}</span>
|
||||
</div>
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="section-content-container sm:max-w-[calc(100%-12rem)]">
|
||||
<div className="w-full grow sm:pl-4 overflow-x-auto">
|
||||
<Select
|
||||
className="block mb-2 sm:!hidden"
|
||||
className="block my-2 sm:!hidden"
|
||||
value={state.selectedSection}
|
||||
onChange={(_, value) => handleSectionSelectorItemClick(value as SettingSection)}
|
||||
>
|
||||
|
Loading…
x
Reference in New Issue
Block a user