Skip to content
Snippets Groups Projects
Commit 91567604 authored by Bernard Roland (Student Com20)'s avatar Bernard Roland (Student Com20)
Browse files

Merge branch 'frontend-devel'

parents f7b2064c 5568c805
No related branches found
No related tags found
No related merge requests found
......@@ -4,8 +4,65 @@
@use 'styles/functions' as fn;
:root {
--primary: #AC42FF;
--primary-dark: #930AFF;
&::before {
display: none;
content: 'light';
}
@each $key, $value in s.$light-colors {
--#{$key}: #{$value};
}
@each $key, $value in s.$light-colors {
--#{$key}-rgb: #{red($value), green($value), blue($value)};
}
}
@media (prefers-color-scheme: dark) {
:root {
&::before {
display: none;
content: 'dark';
}
@each $key, $value in s.$dark-colors {
--#{$key}: #{$value};
}
@each $key, $value in s.$dark-colors {
--#{$key}-rgb: #{red($value), green($value), blue($value)};
}
}
}
:root.light-theme {
&::before {
display: none;
content: 'light';
}
@each $key, $value in s.$light-colors {
--#{$key}: #{$value};
}
@each $key, $value in s.$light-colors {
--#{$key}-rgb: #{red($value), green($value), blue($value)};
}
}
:root.dark-theme {
&::before {
display: none;
content: 'dark';
}
@each $key, $value in s.$dark-colors {
--#{$key}: #{$value};
}
@each $key, $value in s.$dark-colors {
--#{$key}-rgb: #{red($value), green($value), blue($value)};
}
}
* {
......@@ -21,9 +78,9 @@ html {
}
body {
color: s.$body-color;
color: s.$text;
position: relative;
background: #EEF5F5;
background: s.$background;
}
button {
......@@ -173,7 +230,7 @@ $color in s.$themeLightMap {
font-size: 30px;
height: 84px;
cursor: pointer;
color: s.$body-color;
color: s.$text;
user-select: none;
}
......@@ -4,10 +4,37 @@ import ReactDOM from 'react-dom';
import App from 'App';
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
import reportWebVitals from './reportWebVitals';
import 'index.scss';
serviceWorkerRegistration.register();
const root = document.getElementsByTagName('html')[0];
export function getTheme() {
return root.classList.contains('dark-theme') ? 'dark' : 'light';
}
export function toggleTheme() {
const current = getComputedStyle(root, '::before').getPropertyValue('content');
if (current === '"dark"') {
root.classList.remove('dark-theme');
root.classList.add('light-theme');
localStorage.setItem('selected-theme', 'light');
} else {
root.classList.remove('light-theme');
root.classList.add('dark-theme');
localStorage.setItem('selected-theme', 'dark');
}
}
const lastTheme = localStorage.getItem('selected-theme');
if (lastTheme === 'dark') {
root.classList.add('dark-theme');
} else if (lastTheme === 'light') {
root.classList.add('light-theme');
}
function render() {
ReactDOM.render(
<React.StrictMode>
......@@ -27,6 +54,3 @@ export function reload() {
render();
serviceWorkerRegistration.register();
reportWebVitals();
......@@ -54,7 +54,7 @@
display: flex;
a {
color: s.$body-color;
color: s.$text;
font-weight: s.$weight-bold;
margin-left: 40px;
display: none;
......@@ -156,7 +156,7 @@
width: 100%;
border: 7px solid #303030;
border-radius: 25px;
box-shadow: 0 0 40px rgba(0, 0, 0, .15);
box-shadow: 0 0 40px rgba(s.$black, 0.15);
@include mx.breakpoint(medium) {
border-width: 10px;
......@@ -206,7 +206,7 @@
grid-gap: 24px;
justify-content: center;
align-items: center;
background: rgba(255, 255, 255, .5);
background: rgba(s.$background-white-rgb, 0.5);
border-radius: 25px;
padding: 24px;
......@@ -272,11 +272,11 @@
@keyframes move-up {
5%, 35% {
transform: translateY(0);
box-shadow: 0px 5px 25px rgba(0, 0, 0, 0.05);
box-shadow: 0px 5px 25px rgba(s.$black, 0.05);
}
10%, 30% {
transform: translateY(-10px);
box-shadow: 0px 5px 30px rgba(0, 0, 0, 0.15);
box-shadow: 0px 5px 30px rgba(s.$black, 0.15);
}
}
......
......@@ -29,7 +29,7 @@
margin-top: 20px;
border-radius: 5px;
padding: 20px;
background: s.$white;
background: s.$background-white;
}
}
// Colors
$light-colors: (
'primary': #AC42FF,
'primary-dark': #930AFF,
'secondary': #7DEFFF,
'red': #E51C4A,
'background-dark': #11061A,
'background-light': #f9f9f9,
'background-white': #ffffff,
'background-input': #f4f4f4,
'background': #EEF5F5,
'text': #3A5255,
);
$dark-colors: (
'primary': #AC42FF,
'primary-dark': #930AFF,
'secondary': #7DEFFF,
'red': #E51C4A,
'background-dark': #000000,
'background-light': #090909,
'background-white': #151515,
'background-input': #181818,
'background': #0a0a0a,
'text': #eAe2e5,
);
$primary: var(--primary);
$primary-dark: var(--primary-dark);
$secondary: #7DEFFF;
$red: #E51C4A;
$light: #F9F9F9;
$dark: #11061A;
$secondary: var(--secondary);
$red: var(--red);
$background: var(--background);
$background-dark: var(--background-dark);
$background-light: var(--background-light);
$background-white: var(--background-white);
$background-input: var(--background-input);
$text: var(--text);
$light-gray: #F8F8F8;
$gray: #F9F9F9;
$primary-rgb: var(--primary-rgb);
$primary-dark-rgb: var(--primary-dark-rgb);
$secondary-rgb: var(--secondary-rgb);
$red-rgb: var(--red-rgb);
$background-rgb: var(--background-rgb);
$background-dark-rgb: var(--background-dark-rgb);
$background-light-rgb: var(--background-light-rgb);
$background-white-rgb: var(--background-white-rgb);
$background-input-rgb: var(--background-input-rgb);
$text-rgb: var(--text-rgb);
$white: #fff;
$black: #000;
$error-color: $secondary;
$colors: (
'primary': $primary,
'secondary': $secondary,
'light': $light,
'dark': $dark,
);
$themeDarkMap: (
'red': #e61e4d,
'orange': #c94b02,
......@@ -46,9 +76,6 @@ $linear-gradient: linear-gradient(to bottom, $primary, $primary-dark);
$linear-gradient-horizontal: linear-gradient(to right, $primary, $primary-dark);
$radial-gradient: radial-gradient(100% 115% at 0% 0%, $primary 0%, $primary-dark 100%);
$body-color: #3A5255;
$body-font: 'Poppins', sans-serif;
// Typography
$weight-light: 300;
$weight-regular: 400;
......@@ -57,6 +84,8 @@ $weight-semi-bold: 600;
$weight-bold: 700;
$weight-xbold: 800;
$body-font: 'Poppins', sans-serif;
// Breakpoints
$breakpoints: (
'small': 480px,
......
......@@ -7,6 +7,7 @@ import {
formatSimpleDuration,
addTime,
subtractTime,
durationFor,
} from 'timely';
test('simple duration format works as expected', () => {
......@@ -384,3 +385,15 @@ test('in four years formats as expected', () => {
.toEqual('in 4 years');
});
test('duration formatting can contain multiple units', () => {
expect(formatDuration(1.5 * 60 * 60 * 1000, 'minute', 2)).toEqual('one hour 30 minutes');
});
test('duration formatting can be short', () => {
expect(formatDuration(1.5 * 60 * 60 * 1000, 'minute', 2, true)).toEqual('1h 30m');
});
test('get duration from amount and unit', () => {
expect(durationFor(10, 'hour')).toEqual(10 * 60 * 60 * 1000);
});
......@@ -13,22 +13,32 @@ const UNITS = {
type Unit = (keyof typeof UNITS);
function formatAmount(amount: number, base: string): string {
amount = Math.floor(amount);
if (amount === 0) {
return 'zero ' + base + 's';
} else if (amount === 1) {
return 'one ' + base;
function formatAmount(amount: number, base: string, short: boolean): string {
if (short) {
return Math.floor(amount) + base[0];
} else {
return amount.toString() + ' ' + base + 's';
amount = Math.floor(amount);
if (amount === 0) {
return 'zero ' + base + 's';
} else if (amount === 1) {
return 'one ' + base;
} else {
return amount.toString() + ' ' + base + 's';
}
}
}
export function formatDuration(millis: number, precision: Unit = 'minute'): string {
export function formatDuration(millis: number, precision: Unit = 'minute', count = 1, short = false): string {
if (millis >= UNITS[precision]) {
for (const key of (Object.keys(UNITS) as Unit[])) {
if (millis >= UNITS[key]) {
return formatAmount(millis / UNITS[key], key);
const rest = millis % UNITS[key];
const significant = formatAmount(millis / UNITS[key], key, short);
if (count <= 1 || rest < UNITS[precision]) {
return significant;
} else {
return significant + ' ' + formatDuration(rest, precision, count - 1, short);
}
}
}
}
......@@ -195,6 +205,10 @@ export function subtractTime(date: Date, time: number, unit: Unit): Date {
return addTime(date, -time, unit);
}
export function durationFor(time: number, unit: Unit): number {
return time * UNITS[unit];
}
export function durationBetween(from: Date, to: Date): number {
return to.getTime() - from.getTime();
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment