mirror of
https://github.com/umami-software/umami.git
synced 2026-02-12 00:27:11 +01:00
Responsive updates.
This commit is contained in:
parent
53b23420a4
commit
94ed67e339
20 changed files with 100 additions and 77 deletions
|
|
@ -10,12 +10,13 @@ const MetricCard = ({
|
|||
reverseColors = false,
|
||||
format = formatNumber,
|
||||
hideComparison = false,
|
||||
className,
|
||||
}) => {
|
||||
const props = useSpring({ x: Number(value) || 0, from: { x: 0 } });
|
||||
const changeProps = useSpring({ x: Number(change) || 0, from: { x: 0 } });
|
||||
|
||||
return (
|
||||
<div className={styles.card}>
|
||||
<div className={classNames(styles.card, className)}>
|
||||
<animated.div className={styles.value}>{props.x.to(x => format(x))}</animated.div>
|
||||
<div className={styles.label}>
|
||||
{label}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import useDateRange from 'hooks/useDateRange';
|
|||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format';
|
||||
import MetricCard from './MetricCard';
|
||||
import styles from './MetricsBar.module.css';
|
||||
import useMessages from 'hooks/useMessages';
|
||||
import styles from './MetricsBar.module.css';
|
||||
|
||||
export default function MetricsBar({ websiteId }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
|
|
@ -58,18 +58,21 @@ export default function MetricsBar({ websiteId }) {
|
|||
{data && !error && isFetched && (
|
||||
<>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.views)}
|
||||
value={pageviews.value}
|
||||
change={pageviews.change}
|
||||
format={formatFunc}
|
||||
/>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.visitors)}
|
||||
value={uniques.value}
|
||||
change={uniques.change}
|
||||
format={formatFunc}
|
||||
/>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.bounceRate)}
|
||||
value={uniques.value ? (num / uniques.value) * 100 : 0}
|
||||
change={
|
||||
|
|
@ -82,6 +85,7 @@ export default function MetricsBar({ websiteId }) {
|
|||
reverseColors
|
||||
/>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.averageVisitTime)}
|
||||
value={
|
||||
totaltime.value && pageviews.value
|
||||
|
|
|
|||
|
|
@ -3,11 +3,15 @@
|
|||
cursor: pointer;
|
||||
min-height: 80px;
|
||||
gap: 20px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.card {
|
||||
justify-self: flex-start;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 992px) {
|
||||
.bar {
|
||||
justify-content: space-between;
|
||||
overflow: auto;
|
||||
.card {
|
||||
flex-basis: calc(50% - 20px);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ import useTimezone from 'hooks/useTimezone';
|
|||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import { getDateArray, getDateLength } from 'lib/date';
|
||||
import Icons from 'components/icons';
|
||||
import styles from './WebsiteChart.module.css';
|
||||
import useSticky from 'hooks/useSticky';
|
||||
import useMessages from 'hooks/useMessages';
|
||||
import styles from './WebsiteChart.module.css';
|
||||
|
||||
export default function WebsiteChart({
|
||||
websiteId,
|
||||
|
|
@ -91,12 +91,14 @@ export default function WebsiteChart({
|
|||
[styles.isSticky]: isSticky,
|
||||
})}
|
||||
>
|
||||
<Column>
|
||||
<Column defaultSize={12} xl={8}>
|
||||
<MetricsBar websiteId={websiteId} />
|
||||
</Column>
|
||||
<Column className={styles.actions}>
|
||||
<RefreshButton websiteId={websiteId} isLoading={isLoading} />
|
||||
<DateFilter websiteId={websiteId} value={value} className={styles.dropdown} />
|
||||
<Column defaultSize={12} xl={4}>
|
||||
<div className={styles.actions}>
|
||||
<RefreshButton websiteId={websiteId} isLoading={isLoading} />
|
||||
<DateFilter websiteId={websiteId} value={value} className={styles.dropdown} />
|
||||
</div>
|
||||
</Column>
|
||||
</Row>
|
||||
<Row>
|
||||
|
|
|
|||
|
|
@ -27,23 +27,31 @@
|
|||
z-index: var(--z-index-above);
|
||||
}
|
||||
|
||||
.sticky {
|
||||
position: sticky;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.isSticky {
|
||||
border-bottom: 1px solid var(--base300);
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 992px) {
|
||||
.sticky {
|
||||
position: sticky;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
.isSticky {
|
||||
border-bottom: 1px solid var(--base300);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
.actions {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@ import styles from './WebsiteHeader.module.css';
|
|||
export default function WebsiteHeader({ websiteId, name, domain, children }) {
|
||||
return (
|
||||
<Row className={styles.header} justifyContent="center">
|
||||
<Column className={styles.name} variant="two">
|
||||
<Column className={styles.title} variant="two">
|
||||
<Favicon domain={domain} />
|
||||
<Text>{name}</Text>
|
||||
</Column>
|
||||
<Column className={styles.body} variant="two">
|
||||
<Column className={styles.info} variant="two">
|
||||
<ActiveUsers websiteId={websiteId} />
|
||||
{children}
|
||||
</Column>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
.header {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.name {
|
||||
.title {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
|
@ -10,12 +6,14 @@
|
|||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
overflow: hidden;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.body {
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 30px;
|
||||
min-height: 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue