css and some nav
This commit is contained in:
1 parent
a8e5e5d7cd
commit
9a42c290ae
10 files changed
+273
-195
No files matched your search
+12
-12
@@ -22,17 +22,17 @@ export default function createApi(log: Log, pg: Pg, discogs) {
|
|||||||
const app = new koa();
|
const app = new koa();
|
||||||
const server = http.createServer(app.callback());
|
const server = http.createServer(app.callback());
|
||||||
|
|
||||||
// app.use(async (ctx, next) => {
|
app.use(async (ctx, next) => {
|
||||||
// try {
|
try {
|
||||||
// await next();
|
await next();
|
||||||
// } catch (err) {
|
} catch (err) {
|
||||||
// log.error(err);
|
log.error(err);
|
||||||
// ctx.status = err.statusCode || err.status || 500;
|
ctx.status = err.statusCode || err.status || 500;
|
||||||
// ctx.body = {
|
ctx.body = {
|
||||||
// message: err.message
|
error: err.message
|
||||||
// };
|
};
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
|
|
||||||
const router = koaRouter();
|
const router = koaRouter();
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ export default function createApi(log: Log, pg: Pg, discogs) {
|
|||||||
const { id } = ctx.request.params;
|
const { id } = ctx.request.params;
|
||||||
const user = await pg.userFindId(id);
|
const user = await pg.userFindId(id);
|
||||||
|
|
||||||
// if (!user) return ctx.response.status = 404;
|
ctx.assert(user, 404, `user ${id} not found`);
|
||||||
|
|
||||||
const bundles = (await getBundles())
|
const bundles = (await getBundles())
|
||||||
.map(b => {
|
.map(b => {
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
import { KoaPassport } from 'koa-passport';
|
|
||||||
import { Strategy as LocalStrategy } from 'passport-local';
|
|
||||||
|
|
||||||
export default function authService(pg) {
|
|
||||||
const passport = new KoaPassport();
|
|
||||||
|
|
||||||
passport.serializeUser((user, done) => done(null, user.id));
|
|
||||||
passport.deserializeUser((id, done) => {
|
|
||||||
pg.userFindId(id)
|
|
||||||
.then(u => done(null, u))
|
|
||||||
.catch(e => done(e, null));
|
|
||||||
})
|
|
||||||
|
|
||||||
passport.use(new LocalStrategy(
|
|
||||||
{ usernameField: 'email '},
|
|
||||||
function localStrategy(email, password, done) {
|
|
||||||
pg.userFindEmail(email)
|
|
||||||
.then(user => {
|
|
||||||
if (!user) return done(null, false);
|
|
||||||
// if (!user.verifyPassword(password)) return done(null, false);
|
|
||||||
return done(null, user);
|
|
||||||
})
|
|
||||||
.catch(e => done(e, null));
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
return passport;
|
|
||||||
}
|
|
||||||
@@ -38,7 +38,7 @@ export default function authRouter(log, pg: Pg) {
|
|||||||
|
|
||||||
authRouter.post('/login', async (ctx, next) => {
|
authRouter.post('/login', async (ctx, next) => {
|
||||||
await passport.authenticate('local', (err, user, info, status) => {
|
await passport.authenticate('local', (err, user, info, status) => {
|
||||||
ctx.assert(user, 401, { error: 'incorrect login' });
|
ctx.assert(user, 401, 'incorrect login');
|
||||||
|
|
||||||
ctx.login(user);
|
ctx.login(user);
|
||||||
ctx.status = 200;
|
ctx.status = 200;
|
||||||
@@ -50,11 +50,12 @@ export default function authRouter(log, pg: Pg) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
authRouter.get('/login', async (ctx, next) => {
|
authRouter.get('/login', async (ctx, next) => {
|
||||||
ctx.assert(ctx.isAuthenticated(), 401, { error: 'log in required' });
|
ctx.assert(ctx.isAuthenticated(), 401, 'log in required');
|
||||||
|
|
||||||
const user = ctx.state.user;
|
const user = ctx.state.user;
|
||||||
ctx.status = 200;
|
ctx.status = 200;
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
|
id: user.id,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
discogs: user.discogs,
|
discogs: user.discogs,
|
||||||
};
|
};
|
||||||
@@ -68,6 +69,7 @@ export default function authRouter(log, pg: Pg) {
|
|||||||
ctx.login(user);
|
ctx.login(user);
|
||||||
ctx.status = 200;
|
ctx.status = 200;
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
|
id: user.id,
|
||||||
email: user.email,
|
email: user.email,
|
||||||
discogs: user.discogs,
|
discogs: user.discogs,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,22 +6,22 @@ const api = axios.create({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
getBundles: async () => {
|
getBundles: async function getBundles() {
|
||||||
const { data: bundles } = await api.get('/bundles');
|
const { data: bundles } = await api.get('/bundles');
|
||||||
return bundles;
|
return bundles;
|
||||||
},
|
},
|
||||||
|
|
||||||
getUserOffers: async (state, userId) => {
|
getUserOffers: async function getUserOffers(state, userId) {
|
||||||
const { data: offers } = await api.get(`/user/${userId}/offers`);
|
const { data: offers } = await api.get(`/user/${userId}/offers`);
|
||||||
return offers;
|
return offers;
|
||||||
},
|
},
|
||||||
|
|
||||||
getOffers: async (userId) => {
|
getOffers: async function getOffers(userId) {
|
||||||
const { data } = await api.get(`/user/${userId}/offers`);
|
const { data } = await api.get(`/user/${userId}/offers`);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
getLogin: async () => {
|
getLogin: async function getLogin() {
|
||||||
try {
|
try {
|
||||||
const { data: user } = await api.get('/auth/login')
|
const { data: user } = await api.get('/auth/login')
|
||||||
console.log(user);
|
console.log(user);
|
||||||
@@ -31,16 +31,17 @@ const actions = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
postLogin: async (email, password) => {
|
postLogin: async function postLogin(email, password) {
|
||||||
const { data } = await api.post('/auth/login', {
|
const { data } = await api.post('/auth/login', {
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
|
// discogs,
|
||||||
});
|
});
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
postRegister: async (email, password) => {
|
postRegister: async function postRegister(email, password) {
|
||||||
const { data } = await api.post('/auth/register', {
|
const { data } = await api.post('/auth/register', {
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
|
|||||||
+5
-4
@@ -9,7 +9,6 @@ import Header from './components/header';
|
|||||||
|
|
||||||
import Home from './routes/home';
|
import Home from './routes/home';
|
||||||
import Login from './routes/login';
|
import Login from './routes/login';
|
||||||
import Register from './routes/register';
|
|
||||||
import Search from './routes/search';
|
import Search from './routes/search';
|
||||||
import User from './routes/user';
|
import User from './routes/user';
|
||||||
|
|
||||||
@@ -22,6 +21,8 @@ function App() {
|
|||||||
async function getLogin() {
|
async function getLogin() {
|
||||||
const user = await actions.getLogin();
|
const user = await actions.getLogin();
|
||||||
if (!user) return route('/login');
|
if (!user) return route('/login');
|
||||||
|
setUser(user);
|
||||||
|
route('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
getLogin();
|
getLogin();
|
||||||
@@ -32,15 +33,15 @@ function App() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="app">
|
<main id="app">
|
||||||
<Header />
|
<Header user={user} />
|
||||||
<Router>
|
<Router>
|
||||||
<Route path="/" component={Home} />
|
<Route path="/" component={Home} />
|
||||||
<Route path="/login" component={Login} success={loginSuccess} />
|
<Route path="/login" component={Login} success={loginSuccess} />
|
||||||
<Route path="/search" component={Search} />
|
<Route path="/search" component={Search} />
|
||||||
<Route path="/user/:userId" component={User} />
|
<Route path="/user/:userId" component={User} />
|
||||||
</Router>
|
</Router>
|
||||||
</div>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,21 @@
|
|||||||
import { h } from 'preact';
|
import { h } from 'preact';
|
||||||
import { Link } from 'preact-router/match';
|
import { Link } from 'preact-router/match';
|
||||||
|
|
||||||
const Header = () => (
|
const Header = ({ user }) => {
|
||||||
<header class={'header'}>
|
const nav = () => (
|
||||||
<h1>Mates Crates</h1>
|
|
||||||
<nav>
|
<nav>
|
||||||
<Link activeClassName={'active'} href="/">Home</Link>
|
<a href="/search">Offers</a>
|
||||||
<Link activeClassName={'active'} href="/user/cf2384d7-f67f-45a3-a522-68e847345073">ntr</Link>
|
<a href="/search">Search</a>
|
||||||
<Link activeClassName={'active'} href="/user/0ad6c6fc-4637-4ea6-9ecc-d0dcdc7f2da2">jen</Link>
|
<a href={`/user/${user.id}`}>User</a>
|
||||||
<Link activeClassName={'active'} href="/user/ac132ae3-7876-4877-ace4-c0d96a2e4174">james</Link>
|
|
||||||
<Link activeClassName={'active'} href="/user/aa2b287d-ea3f-443a-8559-e1477b8fec07">rhys</Link>
|
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
);
|
||||||
);
|
|
||||||
|
return (
|
||||||
|
<header class={'header'}>
|
||||||
|
<h1>N8CR8</h1>
|
||||||
|
{user ? nav() : null}
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default Header;
|
export default Header;
|
||||||
@@ -6,6 +6,8 @@ const Login = ({ success }) => {
|
|||||||
const [mode, setMode] = useState('login')
|
const [mode, setMode] = useState('login')
|
||||||
const [email, setEmail] = useState('')
|
const [email, setEmail] = useState('')
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
|
// const [discogs, setDiscogs] = useState('');
|
||||||
|
const [confirmPassword, setConfirmPassword] = useState('');
|
||||||
|
|
||||||
async function postLogin() {
|
async function postLogin() {
|
||||||
const user = await actions.postLogin(email, password);
|
const user = await actions.postLogin(email, password);
|
||||||
@@ -17,17 +19,62 @@ const Login = ({ success }) => {
|
|||||||
postLogin();
|
postLogin();
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
if (mode === 'register') return (
|
||||||
<div class={'home'}>
|
<div class="login">
|
||||||
<form action="" method="get" >
|
<form action="">
|
||||||
<label for="email">email: </label>
|
<div class="item">
|
||||||
<input type="email" name="email" id="email" value={email} required onChange={(e) => setEmail(e.target.value)} />
|
<label for="email">email: </label>
|
||||||
<label for="password">password: </label>
|
<input type="email" name="email" id="email" value={email} required onChange={(e) => setEmail(e.target.value)} />
|
||||||
<input type="password" name="password" id="password" value={password} required onChange={(e) => setPassword(e.target.value)} />
|
</div>
|
||||||
<input type="submit" value="Login" onClick={handleSubmit} />
|
<div class="item">
|
||||||
|
<label for="password">confirm password: </label>
|
||||||
|
<input type="password" name="password" id="password" value={password} required onChange={(e) => setConfirmPassword(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<label for="password">confirm password: </label>
|
||||||
|
<input type="password" name="password" id="password" value={password} required onChange={(e) => setConfirmPassword(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<input type="submit" value="register" onClick={handleSubmit} />
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<button onClick={() => setMode('login')} >Click to login</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="login">
|
||||||
|
<form action="">
|
||||||
|
<div class="item">
|
||||||
|
<label for="email">email: </label>
|
||||||
|
<input type="email" name="email" id="email" value={email} required onChange={(e) => setEmail(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<label for="password">password: </label>
|
||||||
|
<input type="password" name="password" id="password" value={password} required onChange={(e) => setPassword(e.target.value)} />
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<input type="submit" value="login" onClick={handleSubmit} />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<button onClick={() => setMode('register')} >Click to register</button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Login;
|
function LoginPage({ success }) {
|
||||||
|
return (
|
||||||
|
<div class="landing">
|
||||||
|
<Login success={success} />
|
||||||
|
<div class="info">
|
||||||
|
<p>Mates Crates is a record importing service.</p>
|
||||||
|
<p>We bundle orders together from thousands of online stores to reduce the cost of shipping vinyl.</p>
|
||||||
|
<p>Based in Preston.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LoginPage;
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
import { h } from 'preact';
|
|
||||||
import { useState } from 'preact/hooks';
|
|
||||||
|
|
||||||
import actions from './../actions';
|
|
||||||
|
|
||||||
const Register = ({ success }) => {
|
|
||||||
const [email, setEmail] = useState('')
|
|
||||||
const [password, setPassword] = useState('');
|
|
||||||
|
|
||||||
async function postRegister() {
|
|
||||||
const user = await actions.postRegister(email, password);
|
|
||||||
success(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSubmit(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
postRegister();
|
|
||||||
}
|
|
||||||
|
|
||||||
function emailChange(e) {
|
|
||||||
setEmail(e.target.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function passwordChange(e) {
|
|
||||||
setPassword(e.target.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div class={'home'}>
|
|
||||||
<form action="" method="get" >
|
|
||||||
<label for="email">email: </label>
|
|
||||||
<input type="email" name="email" id="email" value={email} required onChange={emailChange} />
|
|
||||||
<label for="password">password: </label>
|
|
||||||
<input type="password" name="password" id="password" value={password} required onChange={passwordChange} />
|
|
||||||
<input type="submit" value="Register" onClick={handleSubmit} />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Register;
|
|
||||||
@@ -31,9 +31,9 @@ const User = () => {
|
|||||||
<div class={'home'}>
|
<div class={'home'}>
|
||||||
<form action="" method="get" class="form-example">
|
<form action="" method="get" class="form-example">
|
||||||
<label for="artist">Artist: </label>
|
<label for="artist">Artist: </label>
|
||||||
<input type="text" name="artist" id="artist" value={artist} required />
|
<input type="text" name="artist" id="artist" value={artist} onChange={e => setArtist(e.target.value) } required />
|
||||||
<label for="title">Title: </label>
|
<label for="title">Title: </label>
|
||||||
<input type="text" name="title" id="title" value={title} required />
|
<input type="text" name="title" id="title" value={title} onChange={e => setTitle(e.target.value)} required />
|
||||||
<input type="submit" value="Search" onClick={handleSubmit} />
|
<input type="submit" value="Search" onClick={handleSubmit} />
|
||||||
</form>
|
</form>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
+173
-81
@@ -1,91 +1,183 @@
|
|||||||
html, body {
|
// Digital Ocean reset
|
||||||
height: 100%;
|
html {
|
||||||
width: 100%;
|
box-sizing: border-box;
|
||||||
padding: 0;
|
font-size: 16px;
|
||||||
margin: 0;
|
|
||||||
background: #FAFAFA;
|
|
||||||
font-family: 'Helvetica Neue', arial, sans-serif;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #444;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
*, *:before, *:after {
|
||||||
box-sizing: border-box;
|
box-sizing: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
body, h1, h2, h3, h4, h5, h6, p, ol, ul {
|
||||||
height: 100%;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol, ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* latin */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Raleway';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: url(https://fonts.gstatic.com/s/raleway/v28/1Ptxg8zYS_SKggPN4iEgvnHyvveLxVvaorCIPrE.woff2) format('woff2');
|
||||||
|
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stuff from UX laws
|
||||||
|
html {
|
||||||
|
color:var(--base-font-color);
|
||||||
|
font-size:clamp(var(--min-font-size),calc(50% + 1vw),var(--max-font-size));
|
||||||
|
font-family:var(--base-font-family);
|
||||||
|
line-height:var(--base-line-height);
|
||||||
|
-webkit-text-size-adjust:100%;
|
||||||
|
background:var(--base-background-color);
|
||||||
|
box-sizing:border-box
|
||||||
|
}
|
||||||
|
|
||||||
|
// @charset "UTF-8";
|
||||||
|
:root {
|
||||||
|
--breakpoint-medium: 35em;
|
||||||
|
--breakpoint-large: 56em;
|
||||||
|
--color-dark-blue: #101014;
|
||||||
|
--color-mid-blue: #16171d;
|
||||||
|
--color-light-blue: #1f2128;
|
||||||
|
--color-mid-grey: #9BA0B3;
|
||||||
|
--color-off-white: #F4F1D0;
|
||||||
|
--color-accent-blue: #5E9ED6;
|
||||||
|
--base-accent-color: var(--color-accent-blue);
|
||||||
|
--hover-link-color: var(--color-off-white);
|
||||||
|
--base-background-color: var(--color-dark-blue);
|
||||||
|
--secondary-background-color: var(--color-mid-blue);
|
||||||
|
--tertiary-background-color: var(--color-light-blue);
|
||||||
|
--small-font-size: 0.75em;
|
||||||
|
--base-font-size: 1em;
|
||||||
|
--smedium-font-size: 1.333em;
|
||||||
|
--medium-font-size: 1.777em;
|
||||||
|
--large-font-size: 2.369em;
|
||||||
|
--xlarge-font-size: 3.157em;
|
||||||
|
--base-font-family: 'Raleway', Arial, Sans-Serif;
|
||||||
|
--secondary-font-family: monospace;
|
||||||
|
--base-font-color: var(--color-off-white);
|
||||||
|
--secondary-font-color: var(--color-mid-grey);
|
||||||
|
--base-line-height: 1.4;
|
||||||
|
--header-line-height: 1.2;
|
||||||
|
--min-font-size: var(--base-font-size);
|
||||||
|
--max-font-size: var(--large-font-size);
|
||||||
|
--base-duration: .3s;
|
||||||
|
--base-timing: cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||||
|
--base-border-color: var(--secondary-font-color);
|
||||||
|
--base-border: 1px solid var(--base-border-color);
|
||||||
|
--hover-border: 1px solid var(--base-font-color);
|
||||||
|
--focus-border: 1px solid var(--base-font-color);
|
||||||
|
--base-border-radius: .2rem;
|
||||||
|
--base-focus: 2px solid var(--base-accent-color);
|
||||||
|
--base-outline-offset: 0.25em;
|
||||||
|
--base-box-shadow: 0 1px 2px 0px rgba(0, 0, 0, .25);
|
||||||
|
--hover-box-shadow: 0 2px 10px 1px rgba(0, 0, 0, .5);
|
||||||
|
--base-spacing: 1rem;
|
||||||
|
--base-spacing-half: calc(var(--base-spacing)/2);
|
||||||
|
--utility-bar-header-height: calc(var(--base-spacing) * 1.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input, optgroup, select, textarea {
|
||||||
|
margin:0;
|
||||||
|
border:var(--base-border);
|
||||||
|
border-radius:var(--base-border-radius);
|
||||||
|
background:0 0;
|
||||||
|
font-family:inherit;
|
||||||
|
font-size:100%;
|
||||||
|
color:inherit;
|
||||||
|
line-height:var(--base-line-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:hover, textarea:hover {
|
||||||
|
color:var(--base-font-color);
|
||||||
|
border:var(--hover-border)
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus, textarea:focus {
|
||||||
|
border:var(--focus-border);
|
||||||
|
outline:0
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input {
|
||||||
|
overflow:visible
|
||||||
|
}
|
||||||
|
|
||||||
|
button, select {
|
||||||
|
text-transform:none
|
||||||
|
}
|
||||||
|
|
||||||
|
button, [type=button], [type=reset], [type=submit] {
|
||||||
|
-webkit-appearance:button;
|
||||||
|
cursor:pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok actual styles
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding-top: calc(var(--base-spacing)/2);
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 0 10% 0 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
button, [type=submit] {
|
||||||
|
padding: var(--base-spacing-half);
|
||||||
|
}
|
||||||
|
|
||||||
|
.landing {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.login {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: var(--base-spacing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin-bottom: var(--base-spacing);
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-bottom: var(--base-spacing-half);
|
||||||
|
}
|
||||||
|
|
||||||
|
label, input {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home {
|
.home {
|
||||||
padding: 56px 20px;
|
min-height: 100%;
|
||||||
min-height: 100%;
|
width: 100%;
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
.bundle {
|
.bundle {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.profile {
|
|
||||||
padding: 56px 20px;
|
|
||||||
min-height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
position: fixed;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 56px;
|
|
||||||
padding: 0;
|
|
||||||
background: #673AB7;
|
|
||||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
|
||||||
z-index: 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
h1 {
|
|
||||||
float: left;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 15px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 56px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
float: right;
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a {
|
|
||||||
display: inline-block;
|
|
||||||
height: 56px;
|
|
||||||
line-height: 56px;
|
|
||||||
padding: 0 15px;
|
|
||||||
min-width: 50px;
|
|
||||||
text-align: center;
|
|
||||||
background: rgba(255,255,255,0);
|
|
||||||
text-decoration: none;
|
|
||||||
color: #FFF;
|
|
||||||
will-change: background-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a:hover,
|
|
||||||
nav a:active {
|
|
||||||
background: rgba(0,0,0,0.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a.active {
|
|
||||||
background: rgba(0,0,0,0.4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in new issue
Block a user