Commit 1844ef62 authored by insert's avatar insert 🎺

Add notifications, modals, buttons and other UX

parent cb888a79
Pipeline #241 passed with stage
in 1 minute and 43 seconds
......@@ -7,6 +7,7 @@
"@types/node": "12.6.2",
"@types/react": "16.8.23",
"@types/react-dom": "16.8.4",
"classnames": "^2.2.6",
"node-sass": "^4.12.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
......@@ -18,8 +19,8 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint:sass": "stylelint src/**.* --config=.stylelintrc"
"eject": "react-scripts eject",
"lint:sass": "stylelint src/**.* --config=.stylelintrc"
},
"eslintConfig": {
"extends": "react-app"
......@@ -37,6 +38,7 @@
]
},
"devDependencies": {
"@types/classnames": "^2.2.9",
"stylelint": "^10.1.0",
"stylelint-config-standard": "^18.3.0"
}
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta charset="utf-8">
<meta name="application-name" content="Riot">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link rel="apple-touch-icon" sizes="180x180" href="%PUBLIC_URL%/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="%PUBLIC_URL%/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/favicon-16x16.png">
<link rel="mask-icon" href="%PUBLIC_URL%/safari-pinned-tab.svg" color="#7b68ee">
<meta name="msapplication-config" content="%PUBLIC_URL%/browserconfig.xml" />
<meta name="msapplication-TileColor" content="#7b68ee" />
<meta name="viewport" content="width=device-width, initial-scale=0.9" />
<meta name="theme-color" content="#7B68EE" />
<meta name="msapplication-config" content="%PUBLIC_URL%/browserconfig.xml">
<meta name="msapplication-TileColor" content="#7B68EE">
<meta name="viewport" content="width=device-width, initial-scale=0.9">
<meta name="theme-color" content="#7B68EE">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
......@@ -28,7 +29,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Riot</title>
<title>Riot</title> <!--This title will be used to display other things than just the app name-->
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
......
.button {
border: none;
color: white;
padding: 10px 20px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 1rem;
border-radius: 4px;
cursor: pointer;
background: grey;
font-weight: 600;
&.accept {background: var(--accent-color); margin-right: 20px;}
&.cancel {background: #4f545c;}
&.warning {background: var(--red);}
}
.disabled {
cursor: not-allowed;
}
\ No newline at end of file
import React, { ReactNode } from 'react';
import classNames from 'classnames';
import styles from './Button.module.scss';
interface ButtonProps {
children: ReactNode[] | ReactNode
type?: 'accept' | 'cancel' | 'warning'
};
export function Button(props: ButtonProps) {
let classes: any = {
[styles.button]: true,
[styles.disabled]: true
};
if (props.type) {
classes[styles[props.type]] = true;
}
return (
<div className={classNames(classes)}>
{props.children}
</div>
);
}
\ No newline at end of file
.modal {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.8);
.root {
margin: 0 10px;
max-width: 440px;
min-width: 200px;
max-height: 660px;
min-height: 200px;
.container {
padding: 1em;
border-radius: 5px 5px 0 0;
background: var(--main);
}
.title {
text-transform: uppercase;
font-weight: 600;
}
.footer {
padding: 1em;
border-radius: 0 0 5px 5px;
background: var(--sub);
}
}
}
/**
TEMPORARY DO NOT USE IN PROD
**/
.animateIn {
animation: slide .25s ease;
}
.animateOut {
animation: aaa .25s ease;
}
.animInB {
animation: fade-in .25s ease;
}
.animOutB {
animation: fade-out .25s ease;
}
@keyframes fade-in {
from {opacity: 0;}
to {opacity: 1;}
}
@keyframes fade-out {
from {opacity: 1;}
to {opacity: 0;}
}
@keyframes slide {
from {transform: scale(0);}
to {transform: scale(1);}
}
@keyframes aaa {
from {transform: scale(1);}
to {transform: scale(0);}
}
\ No newline at end of file
import React, { useState } from 'react';
import classNames from 'classnames';
import styles from './Modal.module.scss';
import { Button } from './Button';
interface ModalProps {
title: string
dismiss?: () => void
//children: ReactNode[] | ReactNode
};
export default function Modal(props: ModalProps) {
let [ closing, setClosing ] = useState(false);
function handleClose(e?: React.MouseEvent) {
if (e && (e.target !== e.currentTarget)) return;
if (!props.dismiss) return;
setClosing(true);
setTimeout(() => {
(props.dismiss as Function)();
}, 250);
}
let modalClasses = classNames(styles.modal, {
[styles.animInB]: !closing,
[styles.animOutB]: closing
});
let classes = classNames(styles.root, {
[styles.animateIn]: !closing,
[styles.animateOut]: closing
});
return (
<div className={modalClasses} onClick={handleClose}>
<div className={classes}>
<div className={styles.container}>
<span className={styles.title}>{props.title}</span>
<p>blah blah blah<br/>this may do a thing that you dotn want, word wrap pls as well ok thank</p>
</div>
<div className={styles.footer}>
<Button type='accept'>test</Button>
<Button type='cancel'>cancel</Button>
</div>
</div>
</div>
);
}
\ No newline at end of file
......@@ -5,7 +5,7 @@
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.4);
z-index: -1;
z-index: -1;
}
.login {
......@@ -32,9 +32,7 @@
padding: 25px;
box-sizing: border-box;
box-shadow: 0 2px 10px 0 rgba(0,0,0,.2);
background: var(--main);
//border: 2px solid var(--sub);
.welcome {
font-size: 24px;
......
import React, { useState } from 'react';
//import Helmet from 'react-helmet';
import { AppContext, Page } from '../App';
import { Instance } from '../internal/Client';
import logo from '../assets/downloads/branding/logo-white-full.svg';
import styles from './Login.module.scss';
import Notification from '../components/ui/Notification';
import Notification from '../components/ui/elements/Notification';
import Modal from '../components/ui/components/Modal';
enum ErrorType {
NONE,
......@@ -38,11 +40,14 @@ export default function Login() {
});
}
let [ temp, setTemp ] = useState(true);
return (
<AppContext.Consumer>
{ app =>
<div>
<div className={styles.login}>
{ temp && <Modal title='2FA required' dismiss={() => setTemp(false)} /> }
<div className={styles.overlay}>
{ error.type !== 0 && <Notification title='Failed to login' text={error.reason} /> }
</div>
......
......@@ -3,6 +3,7 @@
:root {
--default-accent-color: #7B68EE;
--accent-color: #7B68EE;
--divider: #707070;
--mention: #DF3535;
......
......@@ -1307,6 +1307,11 @@
dependencies:
"@babel/types" "^7.3.0"
"@types/[email protected]^2.2.9":
version "2.2.9"
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.9.tgz#d868b6febb02666330410fe7f58f3c4b8258be7b"
integrity sha512-MNl+rT5UmZeilaPxAVs6YaPC2m6aA8rofviZbhbxpPpl61uKodfdQVsBtgJGTqGizEf02oW3tsVe7FYB8kK14A==
"@types/[email protected]*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
......@@ -2662,6 +2667,11 @@ [email protected]^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
[email protected]^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce"
integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==
[email protected]:
version "4.2.1"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment