Converted over all text to i18n

This commit is contained in:
Jamie Curnow
2021-07-26 13:38:28 +10:00
parent 7530fc7602
commit 93721ef2d8
15 changed files with 273 additions and 80 deletions

View File

@@ -1,6 +1,7 @@
import React from "react";
import { useHealthState } from "context";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
const FixedFooterWrapper = styled.div`
@@ -28,7 +29,10 @@ function Footer({ fixed }: Props) {
target="_blank"
rel="noreferrer"
className="link-secondary">
User Guide
<FormattedMessage
id="footer.userguide"
defaultMessage="User Guide"
/>
</a>
</li>
<li className="list-inline-item">
@@ -37,7 +41,10 @@ function Footer({ fixed }: Props) {
target="_blank"
rel="noreferrer"
className="link-secondary">
Changelog
<FormattedMessage
id="footer.changelog"
defaultMessage="Change Log"
/>
</a>
</li>
<li className="list-inline-item">
@@ -46,7 +53,10 @@ function Footer({ fixed }: Props) {
target="_blank"
rel="noreferrer"
className="link-secondary">
Github
<FormattedMessage
id="footer.github"
defaultMessage="Github"
/>
</a>
</li>
</ul>
@@ -54,13 +64,20 @@ function Footer({ fixed }: Props) {
<div className="col-12 col-lg-auto mt-3 mt-lg-0">
<ul className="list-inline list-inline-dots mb-0">
<li className="list-inline-item">
Copyright © {new Date().getFullYear()} jc21.com. Theme by{" "}
<FormattedMessage
id="footer.copyright"
defaultMessage="Copyright © {year} jc21.com."
values={{ year: new Date().getFullYear() }}
/>{" "}
<a
className="link-secondary"
href="https://preview.tabler.io/"
target="_blank"
rel="noreferrer">
Tabler
<FormattedMessage
id="footer.theme"
defaultMessage="Theme by Tabler"
/>
</a>
</li>
<li className="list-inline-item">

View File

@@ -1,6 +1,7 @@
import React from "react";
import { Navigation } from "components";
import { intl } from "locale";
import {
Book,
DeviceDesktop,
@@ -18,37 +19,58 @@ function NavMenu() {
className="mb-3"
items={[
{
title: "Home",
title: intl.formatMessage({
id: "dashboard.title",
defaultMessage: "Dashboard",
}),
icon: <Home />,
to: "/",
},
{
title: "Hosts",
title: intl.formatMessage({
id: "hosts.title",
defaultMessage: "Hosts",
}),
icon: <DeviceDesktop />,
to: "/hosts",
},
{
title: "Access Lists",
title: intl.formatMessage({
id: "accesslists.title",
defaultMessage: "Access Lists",
}),
icon: <Lock />,
to: "/access-lists",
},
{
title: "Certificates",
title: intl.formatMessage({
id: "certificates.title",
defaultMessage: "Certificates",
}),
icon: <Shield />,
to: "/certificates",
},
{
title: "Users",
title: intl.formatMessage({
id: "users.title",
defaultMessage: "Users",
}),
icon: <Users />,
to: "/users",
},
{
title: "Audit Log",
title: intl.formatMessage({
id: "auditlog.title",
defaultMessage: "Audit Log",
}),
icon: <Book />,
to: "/audit-log",
},
{
title: "Settings",
title: intl.formatMessage({
id: "settings.title",
defaultMessage: "Settings",
}),
icon: <Settings />,
to: "/settings",
},

View File

@@ -3,6 +3,8 @@ import React, { ReactNode } from "react";
import { Footer } from "components";
import { Avatar, Dropdown, Navigation } from "components";
import { useAuthState, useUserState } from "context";
import { intl } from "locale";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
import { NavMenu } from "./NavMenu";
@@ -33,13 +35,26 @@ function SiteWrapper({ children }: Props) {
avatar={<Avatar size="sm" url={user.gravatarUrl} />}
profileName={user.nickname}
profileSubName={
user.roles.includes("admin") ? "Administrator" : "Standard User"
user.roles.includes("admin")
? intl.formatMessage({
id: "users.admin",
defaultMessage: "Administrator",
})
: intl.formatMessage({
id: "users.standard",
defaultMessage: "Standard User",
})
}
profileItems={[
<Dropdown.Item key="m1-2">Profile settings</Dropdown.Item>,
<Dropdown.Item key="m1-2">
<FormattedMessage
id="profile.title"
defaultMessage="Profile settings"
/>
</Dropdown.Item>,
<Dropdown.Item divider key="m1-4" />,
<Dropdown.Item key="m1-6" onClick={logout}>
Logout
<FormattedMessage id="profile.logout" defaultMessage="Logout" />
</Dropdown.Item>,
]}
/>

View File

@@ -29,10 +29,6 @@ export interface TablePagination {
}
export interface TableProps {
/**
*
*/
title?: string;
/**
* Columns
*/
@@ -50,13 +46,7 @@ export interface TableProps {
*/
sortBy?: string;
}
export const Table = ({
title,
columns,
data,
pagination,
sortBy,
}: TableProps) => {
export const Table = ({ columns, data, pagination, sortBy }: TableProps) => {
const getFormatter = (given: any) => {
if (typeof given === "string") {
switch (given) {
@@ -177,11 +167,6 @@ export const Table = ({
return (
<>
{title ? (
<div className="card-header">
<h3 className="card-title">{title}</h3>
</div>
) : null}
<div className="table-responsive">
<table className="table card-table table-vcenter text-nowrap datatable">
<thead>

View File

@@ -2,15 +2,6 @@ import { createIntl, createIntlCache } from "react-intl";
import langEn from "./lang/en.json";
// todo
/*
const messages: Record<string, Record<string, string>> = {
"en-US": { selectalanguage: "Select a language" },
"pt-BR": { selectalanguage: "Selecione uma linguagem" },
};
*/
// end todo
const loadMessages = (locale: string) => {
switch (locale) {
/*
@@ -27,11 +18,8 @@ export const cache = createIntlCache();
const initialMessages = loadMessages(initialLocale);
console.log("MESSAGES:", initialMessages);
export const intl = createIntl(
// @ts-ignore messages file typings are correct
{ locale: initialLocale, messages: initialMessages },
cache,
);
export const fmt = intl.formatMessage;

View File

@@ -1,20 +1,80 @@
{
"setup.create": {
"defaultMessage": "Create Account"
},
"setup.title": {
"defaultMessage": "Create your first Account"
},
"user.email": {
"defaultMessage": "Email"
},
"user.name": {
"defaultMessage": "Name"
},
"user.nickname": {
"defaultMessage": "Nickname"
},
"user.password": {
"defaultMessage": "Password"
}
"accesslists.title": {
"defaultMessage": "Access Lists"
},
"auditlog.title": {
"defaultMessage": "Audit Log"
},
"certificates.title": {
"defaultMessage": "Certificates"
},
"column.description": {
"defaultMessage": "Description"
},
"column.id": {
"defaultMessage": "ID"
},
"column.name": {
"defaultMessage": "Name"
},
"dashboard.title": {
"defaultMessage": "Dashboard"
},
"footer.changelog": {
"defaultMessage": "Change Log"
},
"footer.copyright": {
"defaultMessage": "Copyright © {year} jc21.com."
},
"footer.github": {
"defaultMessage": "Github"
},
"footer.theme": {
"defaultMessage": "Theme by Tabler"
},
"footer.userguide": {
"defaultMessage": "User Guide"
},
"hosts.title": {
"defaultMessage": "Hosts"
},
"login.login": {
"defaultMessage": "Sign in"
},
"profile.logout": {
"defaultMessage": "Logout"
},
"profile.title": {
"defaultMessage": "Profile settings"
},
"settings.title": {
"defaultMessage": "Settings"
},
"setup.create": {
"defaultMessage": "Create Account"
},
"setup.title": {
"defaultMessage": "Create your first Account"
},
"user.email": {
"defaultMessage": "Email"
},
"user.name": {
"defaultMessage": "Name"
},
"user.nickname": {
"defaultMessage": "Nickname"
},
"user.password": {
"defaultMessage": "Password"
},
"users.admin": {
"defaultMessage": "Administrator"
},
"users.standard": {
"defaultMessage": "Standard User"
},
"users.title": {
"defaultMessage": "Users"
}
}

View File

@@ -1,5 +1,6 @@
import React from "react";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
const Root = styled.div`
@@ -8,7 +9,21 @@ const Root = styled.div`
`;
function AccessLists() {
return <Root>AccessLists</Root>;
return (
<Root>
<div className="card">
<div className="card-status-top bg-cyan" />
<div className="card-header">
<h3 className="card-title">
<FormattedMessage
id="accesslists.title"
defaultMessage="Access Lists"
/>
</h3>
</div>
</div>
</Root>
);
}
export default AccessLists;

View File

@@ -1,5 +1,6 @@
import React from "react";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
const Root = styled.div`
@@ -8,7 +9,18 @@ const Root = styled.div`
`;
function AuditLog() {
return <Root>AuditLog</Root>;
return (
<Root>
<div className="card">
<div className="card-status-top bg-cyan" />
<div className="card-header">
<h3 className="card-title">
<FormattedMessage id="auditlog.title" defaultMessage="Audit Log" />
</h3>
</div>
</div>
</Root>
);
}
export default AuditLog;

View File

@@ -1,5 +1,6 @@
import React from "react";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
const Root = styled.div`
@@ -8,7 +9,21 @@ const Root = styled.div`
`;
function Certificates() {
return <Root>Certificates</Root>;
return (
<Root>
<div className="card">
<div className="card-status-top bg-cyan" />
<div className="card-header">
<h3 className="card-title">
<FormattedMessage
id="certificates.title"
defaultMessage="Certificates"
/>
</h3>
</div>
</div>
</Root>
);
}
export default Certificates;

View File

@@ -1,5 +1,6 @@
import React from "react";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
const Root = styled.div`
@@ -8,7 +9,18 @@ const Root = styled.div`
`;
function Dashboard() {
return <Root>Dashboard</Root>;
return (
<Root>
<div className="card">
<div className="card-status-top bg-cyan" />
<div className="card-header">
<h3 className="card-title">
<FormattedMessage id="dashboard.title" defaultMessage="Dashboard" />
</h3>
</div>
</div>
</Root>
);
}
export default Dashboard;

View File

@@ -1,5 +1,6 @@
import React from "react";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
const Root = styled.div`
@@ -8,7 +9,18 @@ const Root = styled.div`
`;
function Hosts() {
return <Root>Hosts</Root>;
return (
<Root>
<div className="card">
<div className="card-status-top bg-cyan" />
<div className="card-header">
<h3 className="card-title">
<FormattedMessage id="hosts.title" defaultMessage="Hosts" />
</h3>
</div>
</div>
</Root>
);
}
export default Hosts;

View File

@@ -2,6 +2,8 @@ import React, { useEffect, useRef, useState, ChangeEvent } from "react";
import { Alert, Button } from "components";
import { useAuthState } from "context";
import { intl } from "locale";
import { FormattedMessage } from "react-intl";
import logo from "../../img/logo-text-vertical-grey.png";
@@ -50,7 +52,9 @@ function Login() {
<div className="card-body">
{errorMessage ? <Alert type="danger">{errorMessage}</Alert> : null}
<div className="mb-3">
<label className="form-label">Email address</label>
<label className="form-label">
<FormattedMessage id="user.email" defaultMessage="Email" />
</label>
<input
ref={emailRef}
type="email"
@@ -59,13 +63,18 @@ function Login() {
name="email"
value={formData.email}
disabled={loading}
placeholder="Email"
placeholder={intl.formatMessage({
id: "user.email",
defaultMessage: "Email",
})}
maxLength={150}
required
/>
</div>
<div className="mb-2">
<label className="form-label">Password</label>
<label className="form-label">
<FormattedMessage id="user.password" defaultMessage="Password" />
</label>
<div className="input-group input-group-flat">
<input
type="password"
@@ -74,7 +83,10 @@ function Login() {
name="password"
value={formData.password}
disabled={loading}
placeholder="Password"
placeholder={intl.formatMessage({
id: "user.password",
defaultMessage: "Password",
})}
minLength={8}
maxLength={100}
autoComplete="off"
@@ -84,7 +96,7 @@ function Login() {
</div>
<div className="form-footer">
<Button color="cyan" loading={loading} className="w-100">
Sign in
<FormattedMessage id="login.login" defaultMessage="Sign in" />
</Button>
</div>
</div>

View File

@@ -3,6 +3,8 @@ import React, { useState, useEffect, useCallback } from "react";
import { SettingsResponse, requestSettings } from "api/npm";
import { Table } from "components";
import { SuspenseLoader } from "components";
import { intl } from "locale";
import { FormattedMessage } from "react-intl";
import { useInterval } from "rooks";
import styled from "styled-components";
@@ -33,13 +35,20 @@ function Settings() {
const cols = [
{
name: "id",
title: "ID",
title: intl.formatMessage({ id: "column.id", defaultMessage: "ID" }),
formatter: "id",
className: "w-1",
},
{
name: "name",
title: "Name",
title: intl.formatMessage({ id: "column.name", defaultMessage: "Name" }),
},
{
name: "description",
title: intl.formatMessage({
id: "column.description",
defaultMessage: "Description",
}),
},
];
@@ -48,8 +57,12 @@ function Settings() {
<Root>
<div className="card">
<div className="card-status-top bg-cyan" />
<div className="card-header">
<h3 className="card-title">
<FormattedMessage id="settings.title" defaultMessage="Settings" />
</h3>
</div>
<Table
title="Settings"
columns={cols}
data={data.items}
sortBy={data.sort[0].field}

View File

@@ -3,7 +3,7 @@ import React, { useEffect, useRef, useState, ChangeEvent } from "react";
import { createUser } from "api/npm";
import { Alert, Button } from "components";
import { useAuthState, useHealthState } from "context";
import { fmt } from "locale";
import { intl } from "locale";
import { FormattedMessage } from "react-intl";
import logo from "../../img/logo-text-vertical-grey.png";
@@ -105,7 +105,10 @@ function Setup() {
name="name"
value={formData.name}
disabled={loading}
placeholder={fmt({ id: "user.name", defaultMessage: "Name" })}
placeholder={intl.formatMessage({
id: "user.name",
defaultMessage: "Name",
})}
required
/>
</div>
@@ -122,7 +125,7 @@ function Setup() {
name="nickname"
value={formData.nickname}
disabled={loading}
placeholder={fmt({
placeholder={intl.formatMessage({
id: "user.nickname",
defaultMessage: "Nickname",
})}
@@ -140,7 +143,7 @@ function Setup() {
name="email"
value={formData.email}
disabled={loading}
placeholder={fmt({
placeholder={intl.formatMessage({
id: "user.email",
defaultMessage: "Email",
})}
@@ -162,7 +165,7 @@ function Setup() {
name="password"
value={formData.password}
disabled={loading}
placeholder={fmt({
placeholder={intl.formatMessage({
id: "user.password",
defaultMessage: "Password",
})}

View File

@@ -1,5 +1,6 @@
import React from "react";
import { FormattedMessage } from "react-intl";
import styled from "styled-components";
const Root = styled.div`
@@ -8,7 +9,18 @@ const Root = styled.div`
`;
function Users() {
return <Root>Users</Root>;
return (
<Root>
<div className="card">
<div className="card-status-top bg-cyan" />
<div className="card-header">
<h3 className="card-title">
<FormattedMessage id="users.title" defaultMessage="Users" />
</h3>
</div>
</div>
</Root>
);
}
export default Users;