Skip to content

Commit 67f7f83

Browse files
committed
Add auth pages
1 parent 95c93f8 commit 67f7f83

7 files changed

Lines changed: 90 additions & 40 deletions

File tree

rollup.config.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ const plugins = [
2121

2222
export default {
2323
input: "src/index.js",
24-
manualChunks: {vendor: ["solid-js", "solid-js/dom"]},
2524
output: {
2625
dir: "dist",
2726
format: "esm"

src/components/ListErrors.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default props => (
2+
<Show when={props.errors}>
3+
<ul class="error-messages">
4+
<For each={Object.keys(props.errors)}>
5+
{key => (
6+
<li>{key} {props.errors[key]}</li>
7+
)}
8+
</For>
9+
</ul>
10+
</Show>
11+
);

src/pages/Auth.js

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,73 @@
1+
import { createState } from "solid-js";
2+
import NavLink from "../components/NavLink";
3+
import ListErrors from "../components/ListErrors";
4+
import { useStore } from "../store";
5+
16
export default () => {
7+
const [state, setState] = createState({ username: "", inProgress: false }),
8+
[, { register, login }] = useStore(),
9+
isLogin = location.hash.includes("login"),
10+
text = isLogin ? "Sign in" : "Sign up",
11+
link = isLogin ? (
12+
<NavLink route="register">Need an account?</NavLink>
13+
) : (
14+
<NavLink route="login">Have an account?</NavLink>
15+
),
16+
handleSubmit = e => {
17+
e.preventDefault();
18+
setState({ inProgress: true });
19+
const p = isLogin
20+
? login(state.email, state.password)
21+
: register(state.username, state.email, state.password);
22+
p.then(() => (location.hash = "/"))
23+
.catch(errors => setState({ errors }))
24+
.finally(() => setState({ inProgress: false }));
25+
};
26+
227
return (
328
<div class="auth-page">
429
<div class="container page">
530
<div class="row">
631
<div class="col-md-6 offset-md-3 col-xs-12">
7-
<h1 class="text-xs-center">Sign up</h1>
8-
<p class="text-xs-center">
9-
<a href="">Have an account?</a>
10-
</p>
11-
12-
<ul class="error-messages">
13-
<li>That email is already taken</li>
14-
</ul>
15-
16-
<form>
17-
<fieldset class="form-group">
18-
<input
19-
class="form-control form-control-lg"
20-
type="text"
21-
placeholder="Your Name"
22-
/>
23-
</fieldset>
32+
<h1 class="text-xs-center" textContent={text} />
33+
<p class="text-xs-center">{link}</p>
34+
<ListErrors errors={state.errors} />
35+
<form onSubmit={handleSubmit}>
36+
{ !isLogin && (
37+
<fieldset class="form-group">
38+
<input
39+
class="form-control form-control-lg"
40+
type="text"
41+
placeholder="Username"
42+
value={state.username}
43+
onChange={e => setState({ username: e.target.value })}
44+
/>
45+
</fieldset>
46+
)}
2447
<fieldset class="form-group">
2548
<input
2649
class="form-control form-control-lg"
2750
type="text"
2851
placeholder="Email"
52+
value={state.email}
53+
onChange={e => setState({ email: e.target.value })}
2954
/>
3055
</fieldset>
3156
<fieldset class="form-group">
3257
<input
3358
class="form-control form-control-lg"
3459
type="password"
3560
placeholder="Password"
61+
value={state.password}
62+
onChange={e => setState({ password: e.target.value })}
3663
/>
3764
</fieldset>
38-
<button class="btn btn-lg btn-primary pull-xs-right">
39-
Sign up
40-
</button>
65+
<button
66+
class="btn btn-lg btn-primary pull-xs-right"
67+
type="submit"
68+
disabled={state.inProgress}
69+
textContent={text}
70+
/>
4171
</form>
4272
</div>
4373
</div>

src/pages/Profile/Profile.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { useStore, useRouter } from "../../store";
22
import NavLink from "../../components/NavLink";
33
import ArticleList from "../../components/ArticleList";
44

5-
export default () => {
5+
export default ({ username }) => {
66
const [store, { setPage, loadArticles, unfollow, follow }] = useStore(),
7-
{} = useRouter(),
7+
{ location } = useRouter(),
88
handleClick = ev => {
99
ev.preventDefault();
1010
store.profile.following ? unfollow() : follow();
@@ -13,7 +13,7 @@ export default () => {
1313
setPage(page);
1414
loadArticles();
1515
},
16-
isUser = store.currentUser && store.profile.username === store.currentUser.username;
16+
isUser = store.currentUser && username === store.currentUser.username;
1717

1818
return (
1919
<div class="profile-page">
@@ -22,7 +22,7 @@ export default () => {
2222
<div class="row">
2323
<div class="col-xs-12 col-md-10 offset-md-1">
2424
<img src={store.profile?.image} class="user-img" alt="" />
25-
<h4>{store.profile?.username}</h4>
25+
<h4>{username}</h4>
2626
<p>{store.profile?.bio}</p>
2727
{isUser && (
2828
<NavLink
@@ -32,7 +32,7 @@ export default () => {
3232
<i class="ion-gear-a" /> Edit Profile Settings
3333
</NavLink>
3434
)}
35-
{!isUser && (
35+
{store.token && !isUser && (
3636
<button
3737
class="btn btn-sm action-btn"
3838
classList={{
@@ -59,10 +59,8 @@ export default () => {
5959
<li class="nav-item">
6060
<NavLink
6161
class="nav-link"
62-
isActive={(match, location) => {
63-
return location.pathname.match("/favorites") ? 0 : 1;
64-
}}
65-
to={`/@${store.profile?.username}`}
62+
active={location().includes("/favorites") ? 0 : 1}
63+
href={`@${username}`}
6664
>
6765
My Articles
6866
</NavLink>
@@ -71,7 +69,8 @@ export default () => {
7169
<li class="nav-item">
7270
<NavLink
7371
class="nav-link"
74-
to={`/@${store.profile?.username}/favorites`}
72+
active={location().includes("/favorites")}
73+
href={`@${username}/favorites`}
7574
>
7675
Favorited Articles
7776
</NavLink>

src/pages/Profile/index.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import { lazy } from "solid-js";
2-
import { useStore } from "../../store";
1+
import { createEffect, lazy } from "solid-js";
2+
import { useStore, useRouter } from "../../store";
33
const Profile = lazy(() => import("./Profile"));
44

55
export default function(props) {
66
const [, { loadProfile, loadArticles }] = useStore(),
7+
{ location } = useRouter(),
78
username = props.params[0];
8-
loadProfile(username)
9-
loadArticles({ author: username })
10-
return Profile();
9+
loadProfile(username);
10+
createEffect(() =>
11+
location().includes("/favorites")
12+
? loadArticles({ favoritedBy: username })
13+
: loadArticles({ author: username })
14+
);
15+
return Profile({ username });
1116
}

src/store/createAuth.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ export default function createAuth(agent, store, loadState, setState) {
33
store[1] = {
44
...actions,
55
async login(email, password) {
6-
const { user } = await agent.Auth.login(email, password);
6+
const { user, errors } = await agent.Auth.login(email, password);
7+
if (errors) throw errors;
78
actions.setToken(user.token);
89
actions.pullUser();
910
},
1011
async register(username, email, password) {
11-
const { user } = await agent.Auth.register(username, email, password);
12+
const { user, errors } = await agent.Auth.register(username, email, password);
13+
if (errors) throw errors;
1214
actions.setToken(user.token);
1315
actions.pullUser();
1416
},

src/store/createRouteHandler.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export default function createRouteHandler(init) {
44
const [location, setLocation] = createSignal(
55
window.location.hash.slice(2) || init
66
),
7+
[read, triggerParams] = createSignal(),
78
locationHandler = () => setLocation(window.location.hash.slice(2));
89
let params;
910
window.addEventListener("hashchange", locationHandler);
@@ -13,9 +14,12 @@ export default function createRouteHandler(init) {
1314
match: (name, test) => {
1415
const loc = location().split("?")[0];
1516
const match = test.exec(loc);
16-
if (match) params = { params: match.slice(1), routeName: name };
17+
if (match) {
18+
params = { params: match.slice(1), routeName: name };
19+
triggerParams();
20+
}
1721
return !!match;
1822
},
19-
getParams: () => params
23+
getParams: () => (read(), params)
2024
};
2125
}

0 commit comments

Comments
 (0)