Skip to content

Commit

Permalink
✨ Implement sign in
Browse files Browse the repository at this point in the history
  • Loading branch information
SnowSuno committed Dec 29, 2023
1 parent d55d4f7 commit 26ffdd0
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 0 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@hookform/resolvers": "^3.3.3",
"axios": "^1.5.1",
"classnames": "^2.3.1",
"lz-string": "^1.5.0",
Expand All @@ -20,6 +21,7 @@
"react-copy-to-clipboard": "^5.0.3",
"react-device-detect": "^1.17.0",
"react-dom": "^17.0.2",
"react-hook-form": "^7.49.2",
"react-query": "^3.39.3",
"react-redux": "^7.2.5",
"react-router-dom": "^5.2.0",
Expand Down
18 changes: 18 additions & 0 deletions src/api/endpoints/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { auth, syncroom } from "@/common/axios";

export const login = async (username: string, password: string) => {
const {
data: { key },
} = await auth.post<{
key: string;
}>("/login", { username, password });

const credentials = await syncroom.get<{
token: string;
refreshToken: string;
}>("/token", {
params: { key },
});

return credentials.data;
};
15 changes: 15 additions & 0 deletions src/api/hooks/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useMutation } from "react-query";
import { login } from "@/api/endpoints/auth";

export const useAuth = () =>
useMutation<
{
token: string;
refreshToken: string;
},
unknown,
{
username: string;
password: string;
}
>(({ username, password }) => login(username, password));
5 changes: 5 additions & 0 deletions src/common/axios/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import axios from "axios";

export const auth = axios.create({
baseURL: "https://auth.syncroom.link/api",
});
2 changes: 2 additions & 0 deletions src/common/axios/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./auth";
export * from "./syncroom";
14 changes: 14 additions & 0 deletions src/common/axios/syncroom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios from "axios";
import { useAuthStore } from "@/store/auth";

const syncroom = axios.create({
baseURL: "https://webapi.syncroom.appservice.yamaha.com/comm",
});

syncroom.interceptors.request.use(config => {
const { token } = useAuthStore.getState();
config.headers["Authorization"] = token;
return config;
});

export { syncroom };
46 changes: 46 additions & 0 deletions src/components/pages/SignInPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useAuthStore } from "@/store/auth";
import { useAuth } from "@/api/hooks/auth";

const signInSchema = z.object({
username: z.string().email(),
password: z.string().min(1),
});

export const SignInPage: React.FC = () => {
const {
register,
handleSubmit,
formState: { isValid, errors, isSubmitting },
} = useForm<{
username: string;
password: string;
}>({ mode: "onTouched", resolver: zodResolver(signInSchema) });
const setTokens = useAuthStore(state => state.setTokens);
const { mutateAsync, data, isLoading } = useAuth();

const onSubmit = handleSubmit(data => mutateAsync(data));

useEffect(() => {
if (data) setTokens(data);
}, [data, setTokens]);

return (
<main>
<h1>Login</h1>

<form onSubmit={onSubmit}>
<input type="text" {...register("username")} />
{errors.username && <span>이메일 주소를 입력해 주세요</span>}
<input type="password" {...register("password")} />
{errors.password && <span>비밀번호를 입력해 주세요</span>}
<input type="submit" value="로그인" disabled={!isValid} />
{isLoading && <span>로딩중...</span>}
{isSubmitting && <span>제출중...</span>}
</form>
</main>
);
};
1 change: 1 addition & 0 deletions src/components/pages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./SignInPage";
3 changes: 3 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import Modal from "./components/Modal";
import Sidebar from "./components/Sidebar";
import { QueryClient, QueryClientProvider } from "react-query";

import { SignInPage } from "@/components/pages";

const store = createStore(rootReducer, applyMiddleware(ReduxThunk));

const queryClient = new QueryClient();
Expand All @@ -33,6 +35,7 @@ ReactDOM.render(
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login" component={SignInPage} />
<Route path="/join" component={Join} />
<Route path="/notice" component={Notice} />
<Route path="/buymeacoffee" component={Donate} />
Expand Down
23 changes: 23 additions & 0 deletions src/store/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { create } from "zustand";
import { createJSONStorage, persist } from "zustand/middleware";

interface AuthStore {
token?: string;
refreshToken?: string;
setTokens: (credentials: { token: string; refreshToken: string }) => void;
refreshTokens: () => void;
}

export const useAuthStore = create(
persist<AuthStore>(
set => ({
token: undefined,
refreshToken: undefined,
setTokens: tokens => set(tokens),
refreshTokens: () => {
/* TODO */
},
}),
{ name: "auth", storage: createJSONStorage(() => localStorage) },
),
);
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,11 @@
dependencies:
"@hapi/hoek" "^8.3.0"

"@hookform/resolvers@^3.3.3":
version "3.3.3"
resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-3.3.3.tgz#a90c786e5564e58a029d157347e1f2965d02e64f"
integrity sha512-bOMxKkSD3zWcS11TKoUQ8O0ZqKslFohvUsPKSrdCHiuEuMjRo/u3cq9YRJD/+xtNGYup++XD2LkjhegP5XENiw==

"@istanbuljs/load-nyc-config@^1.0.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz"
Expand Down Expand Up @@ -9859,6 +9864,11 @@ react-error-overlay@^6.0.9:
resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz"
integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew==

react-hook-form@^7.49.2:
version "7.49.2"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.49.2.tgz#6fb2742e1308020f26cb1915c7012b6c07b11ade"
integrity sha512-TZcnSc17+LPPVpMRIDNVITY6w20deMdNi6iehTFLV1x8SqThXGwu93HjlUVU09pzFgZH7qZOvLMM7UYf2ShAHA==

react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
Expand Down

0 comments on commit 26ffdd0

Please sign in to comment.