mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 14:17:13 +01:00
Implement redux.
This commit is contained in:
parent
9d8a2406e1
commit
5d4ff5cfa4
31 changed files with 341 additions and 85 deletions
|
|
@ -1,14 +1,30 @@
|
|||
import React from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useSelector } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import Link from 'components/Link';
|
||||
import styles from './Header.module.css';
|
||||
|
||||
export default function Header() {
|
||||
const user = useSelector(state => state.user);
|
||||
|
||||
return (
|
||||
<header className="container">
|
||||
<h1>
|
||||
<Link href="/">
|
||||
<a>umami</a>
|
||||
</Link>
|
||||
</h1>
|
||||
<header className={classNames(styles.header, 'container')}>
|
||||
<div className="row align-items-center">
|
||||
<div className="col">
|
||||
<Link href="/" className={styles.title}>
|
||||
umami
|
||||
</Link>
|
||||
</div>
|
||||
{user && (
|
||||
<div className="col">
|
||||
<div className={styles.nav}>
|
||||
<Link href="/">Dashboard</Link>
|
||||
<Link href="/settings">Settings</Link>
|
||||
<Link href="/logout">Logout</Link>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
25
components/Header.module.css
Normal file
25
components/Header.module.css
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
.header {
|
||||
display: flex;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.header > div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.nav {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nav > * {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
|
@ -3,9 +3,9 @@ import classNames from 'classnames';
|
|||
import NextLink from 'next/link';
|
||||
import styles from './Link.module.css';
|
||||
|
||||
export default function Link({ href, className, children }) {
|
||||
export default function Link({ className, children, ...props }) {
|
||||
return (
|
||||
<NextLink href={href}>
|
||||
<NextLink {...props}>
|
||||
<a className={classNames(styles.link, className)}>{children}</a>
|
||||
</NextLink>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export default function Login() {
|
|||
const [message, setMessage] = useState();
|
||||
|
||||
const handleSubmit = async ({ username, password }) => {
|
||||
const response = await post('/api/auth', { username, password });
|
||||
const response = await post('/api/auth/login', { username, password });
|
||||
|
||||
if (response?.token) {
|
||||
await Router.push('/');
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@
|
|||
}
|
||||
|
||||
@media only screen and (max-width: 1000px) {
|
||||
.container {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.container > div:last-child {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
min-height: 430px;
|
||||
font-size: 14px;
|
||||
padding: 20px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.header {
|
||||
|
|
@ -76,12 +78,14 @@
|
|||
|
||||
.body {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.body:empty:before {
|
||||
content: 'No data available';
|
||||
display: block;
|
||||
color: #b3b3b3;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
|
|
|||
9
components/Settings.js
Normal file
9
components/Settings.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react';
|
||||
|
||||
export default function Settings() {
|
||||
return (
|
||||
<div>
|
||||
<h2>Settings</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
.container {
|
||||
background: #fff;
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
.chart {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,23 +18,31 @@ export default function WebsiteList() {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.container}>
|
||||
{data &&
|
||||
data.websites.map(({ website_id, label }) => (
|
||||
<div key={website_id} className={styles.website}>
|
||||
<div className={styles.header}>
|
||||
<h2>
|
||||
<Link href={`/website/${website_id}/${label}`} className={styles.title}>
|
||||
<Link
|
||||
href="/website/[...id]"
|
||||
as={`/website/${website_id}/${label}`}
|
||||
className={styles.title}
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
</h2>
|
||||
<Link href={`/website/${website_id}/${label}`} className={styles.details}>
|
||||
<Link
|
||||
href="/website/[...id]"
|
||||
as={`/website/${website_id}/${label}`}
|
||||
className={styles.details}
|
||||
>
|
||||
<Icon icon={<Arrow />} /> View details
|
||||
</Link>
|
||||
</div>
|
||||
<WebsiteChart key={website_id} title={label} websiteId={website_id} />
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
.container {
|
||||
background: #fff;
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
.website {
|
||||
padding-bottom: 30px;
|
||||
border-bottom: 1px solid #e1e1e1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue