- {columns.map(({ key, render, className, style, cell }, index) => (
+ {columns.map(({ key, label, render, className, style, cell }, index) => (
+ {label && }
{render ? render(row) : row[key]}
))}
diff --git a/components/common/Table.module.css b/components/common/Table.module.css
index 4d7cd24b..f92338f8 100644
--- a/components/common/Table.module.css
+++ b/components/common/Table.module.css
@@ -3,6 +3,12 @@
flex-direction: column;
}
+.table label {
+ display: none;
+ font-size: var(--font-size-xsmall);
+ font-weight: bold;
+}
+
.header {
border-bottom: 1px solid var(--gray300);
}
@@ -26,5 +32,24 @@
.cell {
display: flex;
+ flex-direction: column;
align-items: flex-start;
}
+
+@media only screen and (max-width: 992px) {
+ .table label {
+ display: block;
+ }
+
+ .header {
+ display: none;
+ }
+
+ .row {
+ flex-direction: column;
+ }
+
+ .cell {
+ margin-bottom: 20px;
+ }
+}
diff --git a/components/common/Toast.js b/components/common/Toast.js
index e8218766..1685eccc 100644
--- a/components/common/Toast.js
+++ b/components/common/Toast.js
@@ -2,9 +2,9 @@ import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import ReactDOM from 'react-dom';
import { useSpring, animated } from 'react-spring';
-import styles from './Toast.module.css';
import Icon from 'components/common/Icon';
import Close from 'assets/times.svg';
+import styles from './Toast.module.css';
function Toast({ message, timeout = 3000, onClose }) {
const props = useSpring({
diff --git a/components/common/Toast.module.css b/components/common/Toast.module.css
index a65abfd1..58677dcb 100644
--- a/components/common/Toast.module.css
+++ b/components/common/Toast.module.css
@@ -1,5 +1,5 @@
.toast {
- position: absolute;
+ position: fixed;
top: 30px;
left: 0;
right: 0;
diff --git a/components/forms/AccountEditForm.js b/components/forms/AccountEditForm.js
index 4b185f1a..97317aff 100644
--- a/components/forms/AccountEditForm.js
+++ b/components/forms/AccountEditForm.js
@@ -8,7 +8,7 @@ import FormLayout, {
FormMessage,
FormRow,
} from 'components/layout/FormLayout';
-import usePost from 'hooks/usePost';
+import useApi from 'hooks/useApi';
const initialValues = {
username: '',
@@ -29,11 +29,11 @@ const validate = ({ user_id, username, password }) => {
};
export default function AccountEditForm({ values, onSave, onClose }) {
- const post = usePost();
+ const { post } = useApi();
const [message, setMessage] = useState();
const handleSubmit = async values => {
- const { ok, data } = await post('/api/account', values);
+ const { ok, data } = await post('/account', values);
if (ok) {
onSave();
diff --git a/components/forms/ChangePasswordForm.js b/components/forms/ChangePasswordForm.js
index d62b5539..29f34521 100644
--- a/components/forms/ChangePasswordForm.js
+++ b/components/forms/ChangePasswordForm.js
@@ -8,7 +8,7 @@ import FormLayout, {
FormMessage,
FormRow,
} from 'components/layout/FormLayout';
-import usePost from 'hooks/usePost';
+import useApi from 'hooks/useApi';
const initialValues = {
current_password: '',
@@ -37,11 +37,11 @@ const validate = ({ current_password, new_password, confirm_password }) => {
};
export default function ChangePasswordForm({ values, onSave, onClose }) {
- const post = usePost();
+ const { post } = useApi();
const [message, setMessage] = useState();
const handleSubmit = async values => {
- const { ok, data } = await post('/api/account/password', values);
+ const { ok, data } = await post('/account/password', values);
if (ok) {
onSave();
diff --git a/components/forms/DeleteForm.js b/components/forms/DeleteForm.js
index 78600305..7fa5d6f6 100644
--- a/components/forms/DeleteForm.js
+++ b/components/forms/DeleteForm.js
@@ -8,7 +8,7 @@ import FormLayout, {
FormMessage,
FormRow,
} from 'components/layout/FormLayout';
-import useDelete from 'hooks/useDelete';
+import useApi from 'hooks/useApi';
const CONFIRMATION_WORD = 'DELETE';
@@ -27,11 +27,11 @@ const validate = ({ confirmation }) => {
};
export default function DeleteForm({ values, onSave, onClose }) {
- const del = useDelete();
+ const { del } = useApi();
const [message, setMessage] = useState();
const handleSubmit = async ({ type, id }) => {
- const { ok, data } = await del(`/api/${type}/${id}`);
+ const { ok, data } = await del(`/${type}/${id}`);
if (ok) {
onSave();
diff --git a/components/forms/LoginForm.js b/components/forms/LoginForm.js
index 68c2775c..3c131558 100644
--- a/components/forms/LoginForm.js
+++ b/components/forms/LoginForm.js
@@ -10,11 +10,12 @@ import FormLayout, {
FormRow,
} from 'components/layout/FormLayout';
import Icon from 'components/common/Icon';
+import useApi from 'hooks/useApi';
+import { setItem } from 'lib/web';
+import { AUTH_TOKEN } from 'lib/constants';
+import { setUser } from 'store/app';
import Logo from 'assets/logo.svg';
import styles from './LoginForm.module.css';
-import usePost from 'hooks/usePost';
-import { setItem } from 'lib/web';
-import { AUTH_TOKEN } from '../../lib/constants';
const validate = ({ username, password }) => {
const errors = {};
@@ -30,12 +31,12 @@ const validate = ({ username, password }) => {
};
export default function LoginForm() {
- const post = usePost();
+ const { post } = useApi();
const router = useRouter();
const [message, setMessage] = useState();
const handleSubmit = async ({ username, password }) => {
- const { ok, status, data } = await post('/api/auth/login', {
+ const { ok, status, data } = await post('/auth/login', {
username,
password,
});
@@ -43,7 +44,11 @@ export default function LoginForm() {
if (ok) {
setItem(AUTH_TOKEN, data.token);
- return router.push('/');
+ setUser(data.user);
+
+ await router.push('/');
+
+ return null;
} else {
setMessage(
status === 401 ? (
diff --git a/components/forms/ResetForm.js b/components/forms/ResetForm.js
index 791039ac..924aa7b1 100644
--- a/components/forms/ResetForm.js
+++ b/components/forms/ResetForm.js
@@ -8,7 +8,7 @@ import FormLayout, {
FormMessage,
FormRow,
} from 'components/layout/FormLayout';
-import usePost from 'hooks/usePost';
+import useApi from 'hooks/useApi';
const CONFIRMATION_WORD = 'RESET';
@@ -27,11 +27,11 @@ const validate = ({ confirmation }) => {
};
export default function ResetForm({ values, onSave, onClose }) {
- const post = usePost();
+ const { post } = useApi();
const [message, setMessage] = useState();
const handleSubmit = async ({ type, id }) => {
- const { ok, data } = await post(`/api/${type}/${id}/reset`);
+ const { ok, data } = await post(`/${type}/${id}/reset`);
if (ok) {
onSave();
diff --git a/components/forms/TrackingCodeForm.js b/components/forms/TrackingCodeForm.js
index bfc6940d..fd679ab2 100644
--- a/components/forms/TrackingCodeForm.js
+++ b/components/forms/TrackingCodeForm.js
@@ -5,8 +5,6 @@ import Button from 'components/common/Button';
import FormLayout, { FormButtons, FormRow } from 'components/layout/FormLayout';
import CopyButton from 'components/common/CopyButton';
-const scriptName = process.env.TRACKER_SCRIPT_NAME || 'umami';
-
export default function TrackingCodeForm({ values, onClose }) {
const ref = useRef();
const { basePath } = useRouter();
@@ -26,7 +24,7 @@ export default function TrackingCodeForm({ values, onClose }) {
rows={3}
cols={60}
spellCheck={false}
- defaultValue={``}
+ defaultValue={``}
readOnly
/>
diff --git a/components/forms/WebsiteEditForm.js b/components/forms/WebsiteEditForm.js
index 0be48561..64655d56 100644
--- a/components/forms/WebsiteEditForm.js
+++ b/components/forms/WebsiteEditForm.js
@@ -10,7 +10,7 @@ import FormLayout, {
} from 'components/layout/FormLayout';
import Checkbox from 'components/common/Checkbox';
import { DOMAIN_REGEX } from 'lib/constants';
-import usePost from 'hooks/usePost';
+import useApi from 'hooks/useApi';
const initialValues = {
name: '',
@@ -34,11 +34,11 @@ const validate = ({ name, domain }) => {
};
export default function WebsiteEditForm({ values, onSave, onClose }) {
- const post = usePost();
+ const { post } = useApi();
const [message, setMessage] = useState();
const handleSubmit = async values => {
- const { ok, data } = await post('/api/website', values);
+ const { ok, data } = await post('/website', values);
if (ok) {
onSave();
diff --git a/components/helpers/StickyHeader.js b/components/helpers/StickyHeader.js
index 477bd393..9c42e4fd 100644
--- a/components/helpers/StickyHeader.js
+++ b/components/helpers/StickyHeader.js
@@ -25,9 +25,8 @@ export default function StickyHeader({
}
};
- checkPosition();
-
if (enabled) {
+ checkPosition();
window.addEventListener('scroll', checkPosition);
}
diff --git a/components/layout/ButtonLayout.module.css b/components/layout/ButtonLayout.module.css
index ef7707e4..5b979360 100644
--- a/components/layout/ButtonLayout.module.css
+++ b/components/layout/ButtonLayout.module.css
@@ -1,6 +1,7 @@
.buttons {
display: flex;
align-items: center;
+ width: 100%;
}
.buttons button + * {
diff --git a/components/layout/Footer.js b/components/layout/Footer.js
index 33eda5e2..603b9369 100644
--- a/components/layout/Footer.js
+++ b/components/layout/Footer.js
@@ -4,32 +4,29 @@ import { FormattedMessage } from 'react-intl';
import Link from 'components/common/Link';
import styles from './Footer.module.css';
import useVersion from 'hooks/useVersion';
-import useLocale from 'hooks/useLocale';
+import { HOMEPAGE_URL, VERSION_URL } from 'lib/constants';
export default function Footer() {
const { current } = useVersion();
- const { dir } = useLocale();
return (
-