mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-01 12:29:35 +01:00
Updated teams button.
This commit is contained in:
parent
992342aa72
commit
099aa7640b
@ -26,6 +26,7 @@
|
||||
padding: 0 40px;
|
||||
font-weight: 700;
|
||||
max-height: 60px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.links a,
|
||||
|
@ -1,153 +1,66 @@
|
||||
import md5 from 'md5';
|
||||
import { colord, extend } from 'colord';
|
||||
import harmoniesPlugin from 'colord/plugins/harmonies';
|
||||
import mixPlugin from 'colord/plugins/mix';
|
||||
|
||||
const pallette = [
|
||||
['#ff9a9e', '#fad0c4'],
|
||||
['#a18cd1', '#fbc2eb'],
|
||||
['#fad0c4', '#ffd1ff'],
|
||||
['#ffecd2', '#fcb69f'],
|
||||
['#ff9a9e', '#fecfef'],
|
||||
['#f6d365', '#fda085'],
|
||||
['#fbc2eb', '#a6c1ee'],
|
||||
['#fdcbf1', '#e6dee9'],
|
||||
['#a1c4fd', '#c2e9fb'],
|
||||
['#d4fc79', '#96e6a1'],
|
||||
['#84fab0', '#8fd3f4'],
|
||||
['#cfd9df', '#e2ebf0'],
|
||||
['#a6c0fe', '#f68084'],
|
||||
['#fccb90', '#d57eeb'],
|
||||
['#e0c3fc', '#8ec5fc'],
|
||||
['#f093fb', '#f5576c'],
|
||||
['#fdfbfb', '#ebedee'],
|
||||
['#4facfe', '#00f2fe'],
|
||||
['#43e97b', '#38f9d7'],
|
||||
['#fa709a', '#fee140'],
|
||||
['#30cfd0', '#330867'],
|
||||
['#a8edea', '#fed6e3'],
|
||||
['#5ee7df', '#b490ca'],
|
||||
['#d299c2', '#fef9d7'],
|
||||
['#f5f7fa', '#c3cfe2'],
|
||||
['#667eea', '#764ba2'],
|
||||
['#fdfcfb', '#e2d1c3'],
|
||||
['#89f7fe', '#66a6ff'],
|
||||
['#fddb92', '#d1fdff'],
|
||||
['#9890e3', '#b1f4cf'],
|
||||
['#ebc0fd', '#d9ded8'],
|
||||
['#96fbc4', '#f9f586'],
|
||||
['#2af598', '#009efd'],
|
||||
['#cd9cf2', '#f6f3ff'],
|
||||
['#6a11cb', '#2575fc'],
|
||||
['#37ecba', '#72afd3'],
|
||||
['#ebbba7', '#cfc7f8'],
|
||||
['#fff1eb', '#ace0f9'],
|
||||
['#c471f5', '#fa71cd'],
|
||||
['#48c6ef', '#6f86d6'],
|
||||
['#feada6', '#f5efef'],
|
||||
['#e6e9f0', '#eef1f5'],
|
||||
['#accbee', '#e7f0fd'],
|
||||
['#e9defa', '#fbfcdb'],
|
||||
['#c1dfc4', '#deecdd'],
|
||||
['#0ba360', '#3cba92'],
|
||||
['#00c6fb', '#005bea'],
|
||||
['#74ebd5', '#9face6'],
|
||||
['#6a85b6', '#bac8e0'],
|
||||
['#a3bded', '#6991c7'],
|
||||
['#9795f0', '#fbc8d4'],
|
||||
['#a7a6cb', '#8989ba'],
|
||||
['#f43b47', '#453a94'],
|
||||
['#0250c5', '#d43f8d'],
|
||||
['#88d3ce', '#6e45e2'],
|
||||
['#d9afd9', '#97d9e1'],
|
||||
['#7028e4', '#e5b2ca'],
|
||||
['#13547a', '#80d0c7'],
|
||||
['#ff0844', '#ffb199'],
|
||||
['#93a5cf', '#e4efe9'],
|
||||
['#434343', '#000000'],
|
||||
['#93a5cf', '#e4efe9'],
|
||||
['#92fe9d', '#00c9ff'],
|
||||
['#ff758c', '#ff7eb3'],
|
||||
['#868f96', '#596164'],
|
||||
['#c79081', '#dfa579'],
|
||||
['#8baaaa', '#ae8b9c'],
|
||||
['#f83600', '#f9d423'],
|
||||
['#b721ff', '#21d4fd'],
|
||||
['#6e45e2', '#88d3ce'],
|
||||
['#d558c8', '#24d292'],
|
||||
['#abecd6', '#fbed96'],
|
||||
['#5f72bd', '#9b23ea'],
|
||||
['#09203f', '#537895'],
|
||||
['#ddd6f3', '#faaca8'],
|
||||
['#dcb0ed', '#99c99c'],
|
||||
['#f3e7e9', '#e3eeff'],
|
||||
['#c71d6f', '#d09693'],
|
||||
['#96deda', '#50c9c3'],
|
||||
['#f77062', '#fe5196'],
|
||||
['#a8caba', '#5d4157'],
|
||||
['#29323c', '#485563'],
|
||||
['#16a085', '#f4d03f'],
|
||||
['#ff5858', '#f09819'],
|
||||
['#2b5876', '#4e4376'],
|
||||
['#00cdac', '#8ddad5'],
|
||||
['#4481eb', '#04befe'],
|
||||
['#dad4ec', '#f3e7e9'],
|
||||
['#874da2', '#c43a30'],
|
||||
['#4481eb', '#04befe'],
|
||||
['#e8198b', '#c7eafd'],
|
||||
['#f794a4', '#fdd6bd'],
|
||||
['#64b3f4', '#c2e59c'],
|
||||
['#0fd850', '#f9f047'],
|
||||
['#ee9ca7', '#ffdde1'],
|
||||
['#209cff', '#68e0cf'],
|
||||
['#bdc2e8', '#e6dee9'],
|
||||
['#e6b980', '#eacda3'],
|
||||
['#1e3c72', '#2a5298'],
|
||||
['#9be15d', '#00e3ae'],
|
||||
['#ed6ea0', '#ec8c69'],
|
||||
['#ffc3a0', '#ffafbd'],
|
||||
['#cc208e', '#6713d2'],
|
||||
['#b3ffab', '#12fff7'],
|
||||
['#243949', '#517fa4'],
|
||||
['#fc6076', '#ff9a44'],
|
||||
['#dfe9f3', '#ffffff'],
|
||||
['#00dbde', '#fc00ff'],
|
||||
['#f9d423', '#ff4e50'],
|
||||
['#50cc7f', '#f5d100'],
|
||||
['#0acffe', '#495aff'],
|
||||
['#616161', '#9bc5c3'],
|
||||
['#df89b5', '#bfd9fe'],
|
||||
['#ed6ea0', '#ec8c69'],
|
||||
['#d7d2cc', '#304352'],
|
||||
['#e14fad', '#f9d423'],
|
||||
['#b224ef', '#7579ff'],
|
||||
['#c1c161', '#d4d4b1'],
|
||||
['#ec77ab', '#7873f5'],
|
||||
['#007adf', '#00ecbc'],
|
||||
['#20E2D7', '#F9FEA5'],
|
||||
['#A8BFFF', '#884D80'],
|
||||
['#B6CEE8', '#F578DC'],
|
||||
['#FFFEFF', '#D7FFFE'],
|
||||
['#E3FDF5', '#FFE6FA'],
|
||||
['#7DE2FC', '#B9B6E5'],
|
||||
['#CBBACC', '#2580B3'],
|
||||
['#B7F8DB', '#50A7C2'],
|
||||
['#007adf', '#00ecbc'],
|
||||
extend([harmoniesPlugin, mixPlugin]);
|
||||
|
||||
const harmonies = [
|
||||
//'analogous',
|
||||
//'complementary',
|
||||
'double-split-complementary',
|
||||
//'rectangle',
|
||||
'split-complementary',
|
||||
'tetradic',
|
||||
//'triadic',
|
||||
];
|
||||
|
||||
const color = (value: string, invert: boolean = false) => {
|
||||
const c = colord(value.startsWith('#') ? value : `#${value}`);
|
||||
|
||||
if (invert && c.isDark()) {
|
||||
return c.invert();
|
||||
}
|
||||
|
||||
return c;
|
||||
};
|
||||
|
||||
const remix = (hash: string) => {
|
||||
const a = hash.substring(0, 6);
|
||||
const b = hash.substring(6, 12);
|
||||
const c = hash.substring(12, 18);
|
||||
const d = hash.substring(18, 24);
|
||||
const e = hash.substring(24, 30);
|
||||
const f = hash.substring(30, 32);
|
||||
|
||||
const base = [b, c, d, e]
|
||||
.reduce((acc, val) => {
|
||||
return acc.mix(color(val), 0.05);
|
||||
}, color(a))
|
||||
.saturate(0.1)
|
||||
.toHex();
|
||||
|
||||
const harmony = pick(parseInt(f, 16), harmonies);
|
||||
|
||||
return color(base, true)
|
||||
.harmonies(harmony)
|
||||
.map(c => c.toHex());
|
||||
};
|
||||
|
||||
const pick = (num: number, arr: any[]) => {
|
||||
return arr[num % arr.length];
|
||||
};
|
||||
|
||||
export function Avatar({ value }: { value: string }) {
|
||||
const hash = md5(value);
|
||||
let num = 0;
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
num += parseInt(hash.substring(i * 4, i * 4 + 4), 16);
|
||||
}
|
||||
|
||||
const index = num % pallette.length;
|
||||
const colors = remix(hash);
|
||||
|
||||
return (
|
||||
<svg viewBox="0 0 100 100">
|
||||
<defs>
|
||||
<linearGradient id={`color-${hash}`} gradientTransform={`rotate(${index % 2 ? 90 : 0})`}>
|
||||
<stop offset="0%" stopColor={pallette[index][0]} />
|
||||
<stop offset="100%" stopColor={pallette[index][1]} />
|
||||
<linearGradient id={`color-${hash}`} gradientTransform="rotate(90)">
|
||||
<stop offset="0%" stopColor={colors[1]} />
|
||||
<stop offset="100%" stopColor={colors[2]} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<circle cx="50" cy="50" r="50" fill={`url(#color-${hash})`} />
|
||||
|
@ -4,6 +4,7 @@ import Bars from 'assets/bars.svg';
|
||||
import BarChart from 'assets/bar-chart.svg';
|
||||
import Bolt from 'assets/bolt.svg';
|
||||
import Calendar from 'assets/calendar.svg';
|
||||
import Change from 'assets/change.svg';
|
||||
import Clock from 'assets/clock.svg';
|
||||
import Dashboard from 'assets/dashboard.svg';
|
||||
import Eye from 'assets/eye.svg';
|
||||
@ -29,6 +30,7 @@ const icons = {
|
||||
BarChart,
|
||||
Bolt,
|
||||
Calendar,
|
||||
Change,
|
||||
Clock,
|
||||
Dashboard,
|
||||
Eye,
|
||||
|
@ -1,10 +1,5 @@
|
||||
.button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.menu {
|
||||
background: var(--base50);
|
||||
right: -10px;
|
||||
}
|
||||
|
||||
.heading {
|
||||
@ -15,3 +10,7 @@
|
||||
text-transform: uppercase;
|
||||
border-bottom: 1px solid var(--base300);
|
||||
}
|
||||
|
||||
.selected {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -2,13 +2,14 @@ import { Key } from 'react';
|
||||
import { Text, Icon, Button, Popup, Menu, Item, PopupTrigger, Flexbox } from 'react-basics';
|
||||
import Icons from 'components/icons';
|
||||
import { useLogin, useMessages, useNavigation } from 'components/hooks';
|
||||
import Avatar from 'components/common/Avatar';
|
||||
import styles from './TeamsButton.module.css';
|
||||
import classNames from 'classnames';
|
||||
|
||||
export function TeamsButton({ teamId }: { teamId: string }) {
|
||||
const { user } = useLogin();
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { router } = useNavigation();
|
||||
const team = user?.teams?.find(({ id }) => id === teamId);
|
||||
|
||||
const handleSelect = (close: () => void, id: Key) => {
|
||||
if (id !== user.id) {
|
||||
@ -21,21 +22,28 @@ export function TeamsButton({ teamId }: { teamId: string }) {
|
||||
|
||||
return (
|
||||
<PopupTrigger>
|
||||
<Button className={styles.button}>
|
||||
<Button className={styles.button} variant="quiet">
|
||||
<Icon>{teamId ? <Icons.Users /> : <Icons.User />}</Icon>
|
||||
<Text>{teamId ? user.teams.find(({ id }) => id === teamId)?.name : user.username}</Text>
|
||||
<Text>{teamId ? team?.name : user.username}</Text>
|
||||
</Button>
|
||||
<Popup alignment="end">
|
||||
{close => (
|
||||
{(close: () => void) => (
|
||||
<Menu variant="popup" onSelect={handleSelect.bind(null, close)}>
|
||||
<div className={styles.heading}>{formatMessage(labels.myAccount)}</div>
|
||||
<Item key={user.id}>{user.username}</Item>
|
||||
<Item key={user.id} className={classNames({ [styles.selected]: !teamId })}>
|
||||
<Flexbox gap={10} alignItems="center">
|
||||
<Icon>
|
||||
<Icons.User />
|
||||
</Icon>
|
||||
<Text>{user.username}</Text>
|
||||
</Flexbox>
|
||||
</Item>
|
||||
<div className={styles.heading}>{formatMessage(labels.team)}</div>
|
||||
{user.teams.map(({ id, name }) => (
|
||||
<Item key={id}>
|
||||
{user?.teams?.map(({ id, name }) => (
|
||||
<Item key={id} className={classNames({ [styles.selected]: id === teamId })}>
|
||||
<Flexbox gap={10} alignItems="center">
|
||||
<Icon size="md">
|
||||
<Avatar value={id} />
|
||||
<Icon>
|
||||
<Icons.Users />
|
||||
</Icon>
|
||||
<Text>{name}</Text>
|
||||
</Flexbox>
|
||||
|
Loading…
Reference in New Issue
Block a user