mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
Added router navigation for settings and details.
This commit is contained in:
parent
30bca80dac
commit
53c23a280b
@ -1,5 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { useRouter } from 'next/router';
|
||||
import classNames from 'classnames';
|
||||
import WebsiteChart from 'components/metrics/WebsiteChart';
|
||||
import WorldMap from 'components/common/WorldMap';
|
||||
@ -19,12 +20,28 @@ import EventsChart from './metrics/EventsChart';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import Loading from 'components/common/Loading';
|
||||
|
||||
const views = {
|
||||
url: PagesTable,
|
||||
referrer: ReferrersTable,
|
||||
browser: BrowsersTable,
|
||||
os: OSTable,
|
||||
device: DevicesTable,
|
||||
country: CountriesTable,
|
||||
event: EventsTable,
|
||||
};
|
||||
|
||||
export default function WebsiteDetails({ websiteId }) {
|
||||
const router = useRouter();
|
||||
const { data } = useFetch(`/api/website/${websiteId}`);
|
||||
const [chartLoaded, setChartLoaded] = useState(false);
|
||||
const [countryData, setCountryData] = useState();
|
||||
const [eventsData, setEventsData] = useState();
|
||||
const [expand, setExpand] = useState();
|
||||
const {
|
||||
query: { id, view },
|
||||
} = router;
|
||||
const path = `/website/${id.join('/')}`;
|
||||
|
||||
console.log({ router });
|
||||
|
||||
const BackButton = () => (
|
||||
<Button
|
||||
@ -32,7 +49,7 @@ export default function WebsiteDetails({ websiteId }) {
|
||||
className={styles.backButton}
|
||||
icon={<Arrow />}
|
||||
size="xsmall"
|
||||
onClick={() => setExpand(null)}
|
||||
onClick={() => router.push(path)}
|
||||
>
|
||||
<div>
|
||||
<FormattedMessage id="button.back" defaultMessage="Back" />
|
||||
@ -46,38 +63,31 @@ export default function WebsiteDetails({ websiteId }) {
|
||||
},
|
||||
{
|
||||
label: <FormattedMessage id="metrics.pages" defaultMessage="Pages" />,
|
||||
value: 'url',
|
||||
component: PagesTable,
|
||||
value: `${path}?view=url`,
|
||||
},
|
||||
{
|
||||
label: <FormattedMessage id="metrics.referrers" defaultMessage="Referrers" />,
|
||||
value: 'referrer',
|
||||
component: ReferrersTable,
|
||||
value: `${path}?view=referrer`,
|
||||
},
|
||||
{
|
||||
label: <FormattedMessage id="metrics.browsers" defaultMessage="Browsers" />,
|
||||
value: 'browser',
|
||||
component: BrowsersTable,
|
||||
value: `${path}?view=browser`,
|
||||
},
|
||||
{
|
||||
label: <FormattedMessage id="metrics.operating-systems" defaultMessage="Operating system" />,
|
||||
value: 'os',
|
||||
component: OSTable,
|
||||
value: `${path}?view=os`,
|
||||
},
|
||||
{
|
||||
label: <FormattedMessage id="metrics.devices" defaultMessage="Devices" />,
|
||||
value: 'device',
|
||||
component: DevicesTable,
|
||||
value: `${path}?view=device`,
|
||||
},
|
||||
{
|
||||
label: <FormattedMessage id="metrics.countries" defaultMessage="Countries" />,
|
||||
value: 'country',
|
||||
component: CountriesTable,
|
||||
value: `${path}?view=country`,
|
||||
},
|
||||
{
|
||||
label: <FormattedMessage id="metrics.events" defaultMessage="Events" />,
|
||||
value: 'event',
|
||||
component: EventsTable,
|
||||
value: `${path}?view=event`,
|
||||
},
|
||||
];
|
||||
|
||||
@ -88,11 +98,7 @@ export default function WebsiteDetails({ websiteId }) {
|
||||
onExpand: handleExpand,
|
||||
};
|
||||
|
||||
const DetailsComponent = expand?.component;
|
||||
|
||||
function getSelectedMenuOption(value) {
|
||||
return menuOptions.find(e => e.value === value);
|
||||
}
|
||||
const DetailsComponent = views[view];
|
||||
|
||||
function handleDataLoad() {
|
||||
if (!chartLoaded) {
|
||||
@ -101,11 +107,7 @@ export default function WebsiteDetails({ websiteId }) {
|
||||
}
|
||||
|
||||
function handleExpand(value) {
|
||||
setExpand(getSelectedMenuOption(value));
|
||||
}
|
||||
|
||||
function handleMenuSelect(value) {
|
||||
setExpand(getSelectedMenuOption(value));
|
||||
router.push(`${path}?view=${value}`);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
@ -126,7 +128,7 @@ export default function WebsiteDetails({ websiteId }) {
|
||||
</div>
|
||||
</div>
|
||||
{!chartLoaded && <Loading />}
|
||||
{chartLoaded && !expand && (
|
||||
{chartLoaded && !view && (
|
||||
<>
|
||||
<div className={classNames(styles.row, 'row')}>
|
||||
<div className="col-md-12 col-lg-6">
|
||||
@ -167,15 +169,8 @@ export default function WebsiteDetails({ websiteId }) {
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{expand && (
|
||||
<MenuLayout
|
||||
className={styles.expand}
|
||||
menuClassName={styles.menu}
|
||||
optionClassName={styles.option}
|
||||
menu={menuOptions}
|
||||
selectedOption={expand.value}
|
||||
onMenuSelect={handleMenuSelect}
|
||||
>
|
||||
{view && (
|
||||
<MenuLayout className={styles.view} menuClassName={styles.menu} menu={menuOptions}>
|
||||
<DetailsComponent {...tableProps} limit={false} />
|
||||
</MenuLayout>
|
||||
)}
|
||||
|
@ -2,7 +2,7 @@
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.expand {
|
||||
.view {
|
||||
border-top: 1px solid var(--gray300);
|
||||
}
|
||||
|
||||
@ -10,10 +10,6 @@
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.menu .option {
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.backButton {
|
||||
align-self: flex-start;
|
||||
margin-bottom: 16px;
|
||||
|
32
components/common/NavMenu.js
Normal file
32
components/common/NavMenu.js
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import classNames from 'classnames';
|
||||
import styles from './NavMenu.module.css';
|
||||
|
||||
export default function NavMenu({ options = [], className, onSelect = () => {} }) {
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.menu, className)}>
|
||||
{options
|
||||
.filter(({ hidden }) => !hidden)
|
||||
.map(option => {
|
||||
const { label, value, className: customClassName, render } = option;
|
||||
|
||||
return render ? (
|
||||
render(option)
|
||||
) : (
|
||||
<div
|
||||
key={value}
|
||||
className={classNames(styles.option, customClassName, {
|
||||
[styles.selected]: router.asPath === value,
|
||||
})}
|
||||
onClick={e => onSelect(value, e)}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
20
components/common/NavMenu.module.css
Normal file
20
components/common/NavMenu.module.css
Normal file
@ -0,0 +1,20 @@
|
||||
.menu {
|
||||
border: 1px solid var(--gray500);
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.option {
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background: var(--gray75);
|
||||
}
|
||||
|
||||
.selected {
|
||||
font-weight: 600;
|
||||
}
|
@ -27,6 +27,7 @@ export default function UserButton() {
|
||||
value: 'username',
|
||||
className: styles.username,
|
||||
},
|
||||
{ label: <FormattedMessage id="label.profile" defaultMessage="Profile" />, value: 'profile' },
|
||||
{ label: <FormattedMessage id="label.logout" defaultMessage="Logout" />, value: 'logout' },
|
||||
];
|
||||
|
||||
@ -35,6 +36,8 @@ export default function UserButton() {
|
||||
|
||||
if (value === 'logout') {
|
||||
router.push('/logout');
|
||||
} else if (value === 'profile') {
|
||||
router.push('/settings/profile');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,37 @@
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import classNames from 'classnames';
|
||||
import Menu from 'components/common/Menu';
|
||||
import NavMenu from 'components/common/NavMenu';
|
||||
import styles from './MenuLayout.module.css';
|
||||
|
||||
export default function MenuLayout({
|
||||
menu,
|
||||
selectedOption,
|
||||
onMenuSelect,
|
||||
className,
|
||||
menuClassName,
|
||||
contentClassName,
|
||||
optionClassName,
|
||||
children,
|
||||
replace = false,
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
function handleSelect(url) {
|
||||
if (replace) {
|
||||
router.replace(url);
|
||||
} else {
|
||||
router.push(url);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.container, className, 'row')}>
|
||||
<Menu
|
||||
<NavMenu
|
||||
options={menu}
|
||||
selectedOption={selectedOption}
|
||||
className={classNames(styles.menu, menuClassName, 'col-12 col-lg-3')}
|
||||
selectedClassName={styles.selected}
|
||||
optionClassName={classNames(styles.option, optionClassName)}
|
||||
onSelect={onMenuSelect}
|
||||
className={classNames(styles.menu, menuClassName, 'col-12 col-lg-2')}
|
||||
onSelect={handleSelect}
|
||||
/>
|
||||
<div className={classNames(styles.content, contentClassName, 'col-12 col-lg-9')}>
|
||||
<div className={classNames(styles.content, contentClassName, 'col-12 col-lg-10')}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -10,25 +10,11 @@
|
||||
}
|
||||
|
||||
.container .content {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
border-left: 1px solid var(--gray300);
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.option {
|
||||
font-size: var(--font-size-normal);
|
||||
padding: 8px 16px;
|
||||
cursor: pointer;
|
||||
margin-right: 30px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background: var(--gray75);
|
||||
}
|
||||
|
||||
.selected {
|
||||
font-weight: 600;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 992px) {
|
||||
@ -40,5 +26,6 @@
|
||||
border-top: 1px solid var(--gray300);
|
||||
border-left: 0;
|
||||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import Page from 'components/layout/Page';
|
||||
import MenuLayout from 'components/layout/MenuLayout';
|
||||
import WebsiteSettings from './WebsiteSettings';
|
||||
@ -7,13 +8,15 @@ import ProfileSettings from './ProfileSettings';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
const WEBSITES = 1;
|
||||
const ACCOUNTS = 2;
|
||||
const PROFILE = 3;
|
||||
const WEBSITES = '/settings';
|
||||
const ACCOUNTS = '/settings/accounts';
|
||||
const PROFILE = '/settings/profile';
|
||||
|
||||
export default function Settings() {
|
||||
const user = useSelector(state => state.user);
|
||||
const [option, setOption] = useState(WEBSITES);
|
||||
const router = useRouter();
|
||||
const { pathname } = router;
|
||||
|
||||
const menuOptions = [
|
||||
{
|
||||
@ -25,15 +28,18 @@ export default function Settings() {
|
||||
value: ACCOUNTS,
|
||||
hidden: !user.is_admin,
|
||||
},
|
||||
{ label: <FormattedMessage id="settings.profile" defaultMessage="Profile" />, value: PROFILE },
|
||||
{
|
||||
label: <FormattedMessage id="settings.profile" defaultMessage="Profile" />,
|
||||
value: PROFILE,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<MenuLayout menu={menuOptions} selectedOption={option} onMenuSelect={setOption}>
|
||||
{option === WEBSITES && <WebsiteSettings />}
|
||||
{option === ACCOUNTS && <AccountSettings />}
|
||||
{option === PROFILE && <ProfileSettings />}
|
||||
{pathname === WEBSITES && <WebsiteSettings />}
|
||||
{pathname === ACCOUNTS && <AccountSettings />}
|
||||
{pathname === PROFILE && <ProfileSettings />}
|
||||
</MenuLayout>
|
||||
</Page>
|
||||
);
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "Abbrechen",
|
||||
"button.change-password": "Passwort ändern",
|
||||
"button.copy-to-clipboard": "In die Zwischenablage kopieren",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Löschen",
|
||||
"button.edit": "Bearbeiten",
|
||||
"button.login": "Anmelden",
|
||||
"button.more": "Mehr",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Speichern",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "Details anzeigen",
|
||||
"button.websites": "Webseiten",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "Neues Passwort",
|
||||
"label.password": "Passwort",
|
||||
"label.passwords-dont-match": "Passwörter stimmen nicht überein",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Erforderlich",
|
||||
"label.this-month": "Diesen Monat",
|
||||
"label.this-week": "Diese Woche",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "Cancel",
|
||||
"button.change-password": "Change password",
|
||||
"button.copy-to-clipboard": "Copy to clipboard",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Delete",
|
||||
"button.edit": "Edit",
|
||||
"button.login": "Login",
|
||||
"button.more": "More",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Save",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "View details",
|
||||
"button.websites": "Websites",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "New password",
|
||||
"label.password": "Password",
|
||||
"label.passwords-dont-match": "Passwords don't match",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Required",
|
||||
"label.this-month": "This month",
|
||||
"label.this-week": "This week",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "Cancelar",
|
||||
"button.change-password": "Cambiar contraseña",
|
||||
"button.copy-to-clipboard": "Copiar al portapapeles",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Eliminar",
|
||||
"button.edit": "Editar",
|
||||
"button.login": "Iniciar sesión",
|
||||
"button.more": "Más",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Guardar",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "Ver detalles",
|
||||
"button.websites": "Sitios",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "Nueva contraseña",
|
||||
"label.password": "Contraseña",
|
||||
"label.passwords-dont-match": "Las contraseñas no coinciden",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Requerido",
|
||||
"label.this-month": "Este mes",
|
||||
"label.this-week": "Esta semana",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "Annuler",
|
||||
"button.change-password": "Changer de mot de passse",
|
||||
"button.copy-to-clipboard": "Copier dans le presse papier",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Supprimer",
|
||||
"button.edit": "Modifier",
|
||||
"button.login": "Connexion",
|
||||
"button.more": "Plus",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Sauvegarder",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "Voir les details",
|
||||
"button.websites": "Sites",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "Nouveau mot de passe",
|
||||
"label.password": "Mot de passe",
|
||||
"label.passwords-dont-match": "Les mots de passe ne correspondent pas",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Requis",
|
||||
"label.this-month": "Ce mois ci",
|
||||
"label.this-week": "Cette semaine",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "キャンセル",
|
||||
"button.change-password": "パスワード変更",
|
||||
"button.copy-to-clipboard": "クリップボードにコピー",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "削除",
|
||||
"button.edit": "編集",
|
||||
"button.login": "ログイン",
|
||||
"button.more": "さらに表示",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "保存",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "詳細表示",
|
||||
"button.websites": "Webサイト",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "新しいパスワード",
|
||||
"label.password": "パスワード",
|
||||
"label.passwords-dont-match": "パスワードが一致しません",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "必須",
|
||||
"label.this-month": "今月",
|
||||
"label.this-week": "今週",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "Цуцлах",
|
||||
"button.change-password": "Нууц үг солих",
|
||||
"button.copy-to-clipboard": "Хуулах",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Устгах",
|
||||
"button.edit": "Засах",
|
||||
"button.login": "Нэвтрэх",
|
||||
"button.more": "Цааш",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Хадгалах",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "Дэлгэрүүлж харах",
|
||||
"button.websites": "Вебүүд",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "Шинэ нууц үг",
|
||||
"label.password": "Нууц үг",
|
||||
"label.passwords-dont-match": "Нууц үг тохирохгүй байна",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Шаардлагатай",
|
||||
"label.this-month": "Энэ сар",
|
||||
"label.this-week": "Энэ долоо хоног",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "Annuleren",
|
||||
"button.change-password": "Wachtwoord wijzigen",
|
||||
"button.copy-to-clipboard": "Kopiëer naar klembord",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Verwijderen",
|
||||
"button.edit": "Bewerken",
|
||||
"button.login": "Inloggen",
|
||||
"button.more": "Toon meer",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Opslaan",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "Meer details",
|
||||
"button.websites": "Websites",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "Nieuw wachtwoord",
|
||||
"label.password": "Wachtwoord",
|
||||
"label.passwords-dont-match": "Wachtwoorden komen niet overeen",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Verplicht",
|
||||
"label.this-month": "Deze maand",
|
||||
"label.this-week": "Deze week",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "Отменить",
|
||||
"button.change-password": "Изменить пароль",
|
||||
"button.copy-to-clipboard": "Скопировать в буфер обмена",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Удалить",
|
||||
"button.edit": "Редактировать",
|
||||
"button.login": "Войти",
|
||||
"button.more": "Больше",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Сохранить",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "Посмотреть детали",
|
||||
"button.websites": "Сайты",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "Новый пароль",
|
||||
"label.password": "Пароль",
|
||||
"label.passwords-dont-match": "Пароли не совпадают",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Обязательное",
|
||||
"label.this-month": "Этот месяц",
|
||||
"label.this-week": "Эта неделя",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "İptal",
|
||||
"button.change-password": "Şifre değiştir",
|
||||
"button.copy-to-clipboard": "Panoya kopyala",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "Sil",
|
||||
"button.edit": "Düzenle",
|
||||
"button.login": "Giriş Yap",
|
||||
"button.more": "Detaylı göster",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "Kaydet",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "Detayı incele",
|
||||
"button.websites": "Web siteleri",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "Yeni parola",
|
||||
"label.password": "Parola",
|
||||
"label.passwords-dont-match": "Parolalar uyuşmuyor",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "Zorunlu alan",
|
||||
"label.this-month": "Bu ay",
|
||||
"label.this-week": "Bu hafta",
|
||||
|
@ -6,12 +6,14 @@
|
||||
"button.cancel": "取消",
|
||||
"button.change-password": "更新密码",
|
||||
"button.copy-to-clipboard": "复制",
|
||||
"button.date-range": "Date range",
|
||||
"button.delete": "删除",
|
||||
"button.edit": "编辑",
|
||||
"button.login": "登录",
|
||||
"button.more": "更多",
|
||||
"button.refresh": "Refresh",
|
||||
"button.save": "保存",
|
||||
"button.single-day": "Single day",
|
||||
"button.view-details": "查看更多",
|
||||
"button.websites": "网站",
|
||||
"device.desktop": "Desktop",
|
||||
@ -37,6 +39,7 @@
|
||||
"label.new-password": "新密码",
|
||||
"label.password": "密码",
|
||||
"label.passwords-dont-match": "密码不一致",
|
||||
"label.profile": "Profile",
|
||||
"label.required": "必填",
|
||||
"label.this-month": "本月",
|
||||
"label.this-week": "本周",
|
||||
|
3
pages/settings/accounts.js
Normal file
3
pages/settings/accounts.js
Normal file
@ -0,0 +1,3 @@
|
||||
import Index from './index';
|
||||
|
||||
export default Index;
|
3
pages/settings/profile.js
Normal file
3
pages/settings/profile.js
Normal file
@ -0,0 +1,3 @@
|
||||
import Index from './index';
|
||||
|
||||
export default Index;
|
Loading…
Reference in New Issue
Block a user