FrontEnd: Playing with store (solidjs)
This commit is contained in:
9
frontend/src/components/AuthLoader.tsx
Normal file
9
frontend/src/components/AuthLoader.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
const AuthLoader = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>Auth Loading...</h2>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AuthLoader;
|
||||||
13
frontend/src/components/TestComponent.tsx
Normal file
13
frontend/src/components/TestComponent.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
interface TestComponentProps {
|
||||||
|
// add props here
|
||||||
|
}
|
||||||
|
|
||||||
|
function TestComponent(props: TestComponentProps) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>TestComponent</h2>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TestComponent;
|
||||||
@@ -1,22 +1,68 @@
|
|||||||
import { useLocation, useNavigate } from "@solidjs/router";
|
import { useLocation, useNavigate } from "@solidjs/router";
|
||||||
import { createContext } from "solid-js";
|
import { createContext, onMount, Show, useContext } from "solid-js";
|
||||||
import { createStore } from "solid-js/store";
|
import { createStore } from "solid-js/store";
|
||||||
|
import { UserType } from "supertokens-web-js/recipe/emailpassword";
|
||||||
|
import AuthLoader from "../components/AuthLoader";
|
||||||
|
import { currentUser } from "../services/auth.service";
|
||||||
|
|
||||||
const AuthStateContext = createContext();
|
const AuthStateContext = createContext();
|
||||||
const AuthDispatchContext = createContext();
|
const AuthDispatchContext = createContext<any>();
|
||||||
|
|
||||||
const initialState = {
|
interface InitState {
|
||||||
|
isLoading: boolean;
|
||||||
|
isAuthenticated: boolean;
|
||||||
|
currentUser: UserType | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: InitState = {
|
||||||
|
isLoading: false,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
isLoading: true,
|
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
currentAccount: null,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const AuthProvider = (props: any) => {
|
const AuthProvider = (props: any) => {
|
||||||
|
|
||||||
const [store, setStore] = createStore(initialState);
|
const [store, setStore] = createStore(initialState);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const location = useLocation();
|
|
||||||
|
|
||||||
|
const loadCurrentUser = async () => {
|
||||||
|
const user = await currentUser();
|
||||||
|
if (user) {
|
||||||
|
setStore("isAuthenticated", true);
|
||||||
|
setStore("currentUser", user);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await loadCurrentUser();
|
||||||
|
});
|
||||||
|
|
||||||
|
const setCurrentUser = (user: UserType) => {
|
||||||
|
setStore("isAuthenticated", true);
|
||||||
|
setStore("currentUser", user);
|
||||||
|
setStore("isLoading", false);
|
||||||
|
};
|
||||||
|
const removeCurrentUser = () => {
|
||||||
|
setStore("isAuthenticated", false);
|
||||||
|
setStore("currentUser", null);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthStateContext.Provider value={store}>
|
||||||
|
<AuthDispatchContext.Provider
|
||||||
|
value={{
|
||||||
|
setCurrentUser,
|
||||||
|
removeCurrentUser,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Show when={!store.isLoading} fallback={<AuthLoader />}>
|
||||||
|
{props.children}
|
||||||
|
</Show>
|
||||||
|
</AuthDispatchContext.Provider>
|
||||||
|
</AuthStateContext.Provider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default AuthProvider;
|
export default AuthProvider;
|
||||||
|
export const useAuthState = () => useContext(AuthStateContext);
|
||||||
|
export const useAuthDispatch = () => useContext(AuthDispatchContext);
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
|
import { useNavigate } from "@solidjs/router";
|
||||||
import { createSignal } from "solid-js";
|
import { createSignal } from "solid-js";
|
||||||
import { createStore } from "solid-js/store";
|
import { createStore } from "solid-js/store";
|
||||||
|
|
||||||
import EmailPassRecipe from "supertokens-web-js/recipe/emailpassword";
|
import EmailPassRecipe from "supertokens-web-js/recipe/emailpassword";
|
||||||
import Session from "supertokens-web-js/recipe/session";
|
import Session from "supertokens-web-js/recipe/session";
|
||||||
|
import { useAuthDispatch } from "../../context/AuthContext";
|
||||||
|
import { loginService } from "../../services/auth.service";
|
||||||
const useLogin = () => {
|
const useLogin = () => {
|
||||||
const [loading, setLoading] = createSignal(false);
|
const [loading, setLoading] = createSignal(false);
|
||||||
const [form, setForm] = createStore({
|
const [form, setForm] = createStore({
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { setCurrentUser } = useAuthDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const handleInput = (ev: any) => {
|
const handleInput = (ev: any) => {
|
||||||
setForm([ev.currentTarget.name], ev.currentTarget.value);
|
setForm([ev.currentTarget.name], ev.currentTarget.value);
|
||||||
};
|
};
|
||||||
@@ -17,18 +23,46 @@ const useLogin = () => {
|
|||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
const login = await EmailPassRecipe.signIn({
|
const loginData = await loginService({
|
||||||
formFields: [
|
formFields: [
|
||||||
{ id: "email", value: form.email },
|
{ id: "email", value: form.email },
|
||||||
{ id: "password", value: form.password },
|
{ id: "password", value: form.password },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
console.log(login)
|
if (loginData.status === "OK") {
|
||||||
|
//TODO: Add user in store. Set Authenticated true.
|
||||||
|
localStorage.setItem("current_user", JSON.stringify(loginData.user));
|
||||||
|
setCurrentUser(loginData.user);
|
||||||
|
navigate("/", { replace: true });
|
||||||
|
}
|
||||||
|
if (loginData.status === "FIELD_ERROR") {
|
||||||
|
// TODO: Handle error in UI
|
||||||
|
console.log("FIELD_ERROR", loginData);
|
||||||
|
}
|
||||||
|
if (loginData.status === "WRONG_CREDENTIALS_ERROR") {
|
||||||
|
// TODO: Handle error in UI
|
||||||
|
console.log("WRONG_CREDENTIALS_ERROR", loginData);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
//TODO: Handle error in UI
|
||||||
|
console.error("ERRRRRRRRRRr", error);
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const login = await EmailPassRecipe.signIn({
|
||||||
|
// formFields: [
|
||||||
|
// { id: "email", value: form.email },
|
||||||
|
// { id: "password", value: form.password },
|
||||||
|
// ],
|
||||||
|
// });
|
||||||
|
// console.log(login)
|
||||||
|
// } catch (error) {
|
||||||
|
// console.error(error);
|
||||||
|
// } finally {
|
||||||
|
// setLoading(false);
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
@@ -41,10 +75,10 @@ const useLogin = () => {
|
|||||||
let userId = await Session.getUserId();
|
let userId = await Session.getUserId();
|
||||||
let jwt = (await Session.getAccessTokenPayloadSecurely()).jwt;
|
let jwt = (await Session.getAccessTokenPayloadSecurely()).jwt;
|
||||||
// console.log(userId, jwt);
|
// console.log(userId, jwt);
|
||||||
const {isVerified} = await EmailPassRecipe.isEmailVerified();
|
const { isVerified } = await EmailPassRecipe.isEmailVerified();
|
||||||
console.log(isVerified)
|
console.log(isVerified);
|
||||||
if(!isVerified) {
|
if (!isVerified) {
|
||||||
const sendEmail = await EmailPassRecipe.sendVerificationEmail()
|
const sendEmail = await EmailPassRecipe.sendVerificationEmail();
|
||||||
console.log(sendEmail);
|
console.log(sendEmail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ import { render } from "solid-js/web";
|
|||||||
import "./index.css";
|
import "./index.css";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import { Router } from "@solidjs/router";
|
import { Router } from "@solidjs/router";
|
||||||
|
import AuthProvider from "./context/AuthContext";
|
||||||
|
|
||||||
render(
|
render(
|
||||||
() => (
|
() => (
|
||||||
<Router>
|
<Router>
|
||||||
<App />
|
<AuthProvider>
|
||||||
|
<App />
|
||||||
|
</AuthProvider>
|
||||||
</Router>
|
</Router>
|
||||||
),
|
),
|
||||||
document.getElementById("main-container") as HTMLElement
|
document.getElementById("main-container") as HTMLElement
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
import type { Component } from "solid-js";
|
import { Component, Show } from "solid-js";
|
||||||
|
import { useAuthState } from "../../../context/AuthContext";
|
||||||
|
|
||||||
const Home: Component = () => {
|
const Home: Component = () => {
|
||||||
return (
|
const authState: any = useAuthState();
|
||||||
<div>
|
|
||||||
<h2>Home</h2>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Home;
|
return (
|
||||||
|
<div>
|
||||||
|
<p>Home</p>
|
||||||
|
|
||||||
|
<Show when={authState?.isAuthenticated}>
|
||||||
|
<div>
|
||||||
|
<p>{JSON.parse(authState?.currentUser)}</p>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Home;
|
||||||
|
|||||||
32
frontend/src/services/auth.service.ts
Normal file
32
frontend/src/services/auth.service.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import EmailPassRecipe from "supertokens-web-js/recipe/emailpassword";
|
||||||
|
import Session from "supertokens-web-js/recipe/session";
|
||||||
|
|
||||||
|
export interface AuthData {
|
||||||
|
formFields: FormFields[];
|
||||||
|
}
|
||||||
|
interface FormFields {
|
||||||
|
id: string;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentUser = async () => {
|
||||||
|
// This method might produce bugs. Localstorage may not be the same as logged in user
|
||||||
|
// TODO: endpoing in backend (getCurrentUser)
|
||||||
|
if (
|
||||||
|
localStorage.getItem("current_user") &&
|
||||||
|
(await Session.doesSessionExist())
|
||||||
|
) {
|
||||||
|
let sessionUserId = await Session.getUserId();
|
||||||
|
const user: EmailPassRecipe.UserType = JSON.parse(localStorage.getItem("current_user")!);
|
||||||
|
if (sessionUserId === user.id) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const loginService = async (loginData: AuthData) => {
|
||||||
|
return await EmailPassRecipe.signIn(loginData);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { loginService, currentUser };
|
||||||
Reference in New Issue
Block a user