diff --git a/go.mod b/go.mod index 665bfd689..e575fdfdc 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/rs/zerolog v1.19.0 github.com/stretchr/testify v1.7.0 github.com/uber/jaeger-client-go v2.25.0+incompatible - go.dedis.ch/dela v0.0.0-20220427080805-29069c746635 + go.dedis.ch/dela v0.0.0-20220428080424-2348afb6228a go.dedis.ch/dela-apps v0.0.0-20211019120455-a0db752a0ba0 go.dedis.ch/kyber/v3 v3.1.0-alpha golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f diff --git a/go.sum b/go.sum index d78dae4fa..0ee971518 100644 --- a/go.sum +++ b/go.sum @@ -244,8 +244,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.dedis.ch/dela v0.0.0-20211018150429-1fdbe35cd189/go.mod h1:GVQ2MumgCcAkor2MmfRCoqTBsFjaaqt7HfJpQLhMGok= -go.dedis.ch/dela v0.0.0-20220427080805-29069c746635 h1:X2PICAgwLn1Sdo/I6KIoIdaNb+RZz0v+xH5T63X/0Ws= -go.dedis.ch/dela v0.0.0-20220427080805-29069c746635/go.mod h1:IIIV0aR0f1c9z4jRB2HVYYeLK7XbQ6pfqv6RufaXmUg= +go.dedis.ch/dela v0.0.0-20220428080424-2348afb6228a h1:Ahci1dtYYj9MIVOUjsA2kavD6oAEmnLZrwBctzHOYYA= +go.dedis.ch/dela v0.0.0-20220428080424-2348afb6228a/go.mod h1:IIIV0aR0f1c9z4jRB2HVYYeLK7XbQ6pfqv6RufaXmUg= go.dedis.ch/dela-apps v0.0.0-20211019120455-a0db752a0ba0 h1:gPrJd+7QUuADpfToMKr80maGnjGPeB7ft7iNrkAtwGY= go.dedis.ch/dela-apps v0.0.0-20211019120455-a0db752a0ba0/go.mod h1:MoJSdm3LXkNtiKEK3eiBKgqFhory4v8sBr7ldFP/vFc= go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= diff --git a/web/frontend/src/index.tsx b/web/frontend/src/index.tsx index 442121471..3730970c7 100644 --- a/web/frontend/src/index.tsx +++ b/web/frontend/src/index.tsx @@ -5,7 +5,7 @@ import { ENDPOINT_PERSONAL_INFO } from 'components/utils/Endpoints'; import 'index.css'; import App from 'layout/App'; import reportWebVitals from 'reportWebVitals'; -import Flash from 'layout/Flash'; +import ShortUniqueId from 'short-unique-id'; const flashTimeout = 4000; @@ -34,6 +34,7 @@ export interface AuthState { export interface FlashState { getMessages(): FlashMessage[]; addMessage(msg: string, level: number): void; + hideMessage(index: string): void; } export const enum FlashLevel { @@ -47,18 +48,22 @@ class FlashMessage { text: string; // Level defines the type of flash: info, warn, error - level: number; + level: FlashLevel; - constructor(text: string, level: number) { + // A uniq string identifier + id: string; + + constructor(text: string, level: FlashLevel) { this.text = text; this.level = level; + this.id = new ShortUniqueId({ length: 8 })(); } getText(): string { return this.text; } - getLevel(): number { + getLevel(): FlashLevel { return this.level; } } @@ -111,16 +116,24 @@ const AppContainer = () => { // add a flash to the list and set a timeout on it addMessage: (message: string, level: number) => { - const newFlashes = [...flashes, new FlashMessage(message, level)]; + const flash = new FlashMessage(message, level); + const newFlashes = [...flashes, flash]; setFlashes(newFlashes); // remove the flash after some timeout setTimeout(() => { - const removedFlashes = [...flashesRef.current]; - removedFlashes.shift(); + let removedFlashes = [...flashesRef.current]; + removedFlashes = removedFlashes.filter((f) => f.id !== flash.id); setFlashes(removedFlashes); }, flashTimeout); }, + + // Set the visibility of flashMessage to false + hideMessage: (id: string) => { + let removedFlashes = [...flashesRef.current]; + removedFlashes = removedFlashes.filter((f) => f.id !== id); + setFlashes(removedFlashes); + }, }; useEffect(() => { @@ -158,7 +171,6 @@ const AppContainer = () => { return ( - {content} ); diff --git a/web/frontend/src/layout/App.tsx b/web/frontend/src/layout/App.tsx index 029ac1698..9af2a99c7 100644 --- a/web/frontend/src/layout/App.tsx +++ b/web/frontend/src/layout/App.tsx @@ -27,6 +27,7 @@ import Footer from './Footer'; import './App.css'; import { AuthContext } from '..'; import Logged from 'pages/session/Logged'; +import Flash from './Flash'; const NotFound = () =>
404 not found
; @@ -89,6 +90,9 @@ const App = () => { } /> +
+ +
diff --git a/web/frontend/src/layout/Flash.module.css b/web/frontend/src/layout/Flash.module.css new file mode 100644 index 000000000..c55a0f27d --- /dev/null +++ b/web/frontend/src/layout/Flash.module.css @@ -0,0 +1,21 @@ +.progress { + position: absolute; + bottom: 0; + background: rgba(255, 255, 255, 0.4); + height: 5px; + left: 0; + right: 100%; + + animation-name: progress; + animation-duration: 4s; + animation-timing-function: linear; +} + +@keyframes progress { + from { + right: 100%; + } + to { + right: 0%; + } +} diff --git a/web/frontend/src/layout/Flash.tsx b/web/frontend/src/layout/Flash.tsx index 6c9a54c94..288667fe4 100644 --- a/web/frontend/src/layout/Flash.tsx +++ b/web/frontend/src/layout/Flash.tsx @@ -1,31 +1,52 @@ import { FlashContext, FlashLevel } from 'index'; import { useContext } from 'react'; +import { + ExclamationCircleIcon, + ExclamationIcon, + InformationCircleIcon, + XIcon, +} from '@heroicons/react/outline'; +import styles from './Flash.module.css'; const Flash = () => { const fctx = useContext(FlashContext); - const flashContainer = (level: number) => { - switch (level) { - case FlashLevel.Info: - return 'flex items-center text-white text-sm font-bold px-4 py-3 bg-indigo-500'; - case FlashLevel.Warning: - return 'flex items-center text-white text-sm font-bold px-4 py-3 bg-orange-500'; - case FlashLevel.Error: - return 'flex items-center text-white text-sm font-bold px-4 py-3 bg-red-500'; - } - }; - return ( -
- {fctx.getMessages().map((msg, i) => ( -
- - - -

{msg.getText()}

+
+ {fctx.getMessages().map((msg) => ( +
+ +
))}
diff --git a/web/frontend/src/pages/Home.tsx b/web/frontend/src/pages/Home.tsx index 10c8f9652..630e1e683 100644 --- a/web/frontend/src/pages/Home.tsx +++ b/web/frontend/src/pages/Home.tsx @@ -1,15 +1,43 @@ -import React, { FC } from 'react'; +import { FlashContext, FlashLevel } from 'index'; +import React, { FC, useContext } from 'react'; import { useTranslation } from 'react-i18next'; import './Home.css'; const Home: FC = () => { const { t } = useTranslation(); + const fctx = useContext(FlashContext); return (

{t('homeTitle')}

{t('homeText')}
+
+ + + +
); };