Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
"react-dom": "18.2.0",
"react-redux": "^8.0.5",
"react-slick": "^0.29.0",
"redux-persist": "^6.0.0",
"slick-carousel": "^1.8.1",
"typescript": "5.0.2"
},
"devDependencies": {
"@types/react-redux": "^7.1.25",
"autoprefixer": "^10.4.14",
"postcss": "^8.4.21",
"tailwindcss": "^3.2.7"
Expand Down
28 changes: 28 additions & 0 deletions src/Redux/Features/UserSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { createSlice } from "@reduxjs/toolkit";

interface UserState {
email: string;
token: string;
}

const initialState: UserState = {
email: "",
token: "",
};

export const userSlice = createSlice({
name: "userSlicer",
initialState,
reducers: {
__saveEmail: function (state, { type, payload }) {
state.email = payload.email;
},
__saveToken: function (state, { type, payload }) {
state.token = payload.token;
},
},
});

export const { __saveEmail, __saveToken } = userSlice.actions;

export default userSlice.reducer;
24 changes: 0 additions & 24 deletions src/Redux/Features/exampleSlice.ts

This file was deleted.

6 changes: 6 additions & 0 deletions src/Redux/Features/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { combineReducers } from "@reduxjs/toolkit";
import UserSlice from "./UserSlice";

export const rootReducer = combineReducers({
user: UserSlice,
});
31 changes: 24 additions & 7 deletions src/Redux/store.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
'use client';
import { configureStore } from "@reduxjs/toolkit";
import { useDispatch, useSelector } from "react-redux";
import { persistReducer } from "redux-persist";
import { rootReducer } from "./Features";
import storage from "redux-persist/lib/storage";

import { configureStore } from '@reduxjs/toolkit';
import exampleSlice from './Features/exampleSlice';
const persistConfig = {
key: "root",
storage,
whitelist: ["user"],
};

export const store = configureStore({reducer:{
example: exampleSlice
}})
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
immutableCheck: false,
}),
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector = <T>(selector: (state: RootState) => T) =>
useSelector<RootState, T>(selector);
export default store;
9 changes: 8 additions & 1 deletion src/api/endpoints/UserAPIs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { DupCheckDTO, UserLoginDTO, UserSignUpDTO } from "@/data/DTO/UserDTO";
import {
DupCheckDTO,
UserDeleteDTO,
UserLoginDTO,
UserSignUpDTO,
} from "@/data/DTO/UserDTO";
import api from "../index";

export const UserAPIs = {
Expand All @@ -8,4 +13,6 @@ export const UserAPIs = {
api.post("/member/checkemail", payload),
postNickNameDupCheck: (payload: DupCheckDTO) =>
api.post("/member/checknickname", payload),
deleteUser: (payload: UserDeleteDTO) =>
api.delete(`/profile/${payload.memberId}`),
};
3 changes: 3 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useAppSelector } from "@/Redux/store";
import axios from "axios";

const api = axios.create({
Expand All @@ -7,6 +8,8 @@ const api = axios.create({
// request Interceptor
api.interceptors.request.use(
(data) => {
const { token } = useAppSelector((state) => state.user);
data.headers!.Authorization = "Bearer " + token;
return data;
},
() => {}
Expand Down
13 changes: 8 additions & 5 deletions src/app/Providers.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"use client";

import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { Provider } from "react-redux";
import React from "react";
import { store } from "@/Redux/store";
import store from "@/Redux/store";
import { persistStore } from "redux-persist";
import { PersistGate } from "redux-persist/integration/react";

const queryClient = new QueryClient({
defaultOptions: {
Expand All @@ -15,11 +15,14 @@ const queryClient = new QueryClient({
},
});

const persistor = persistStore(store);

const Providers = ({ children }: { children: React.ReactNode }) => {
return (
<QueryClientProvider client={queryClient}>
<Provider store={store}>{children}</Provider>

<PersistGate persistor={persistor}>
<Provider store={store}>{children}</Provider>
</PersistGate>
<ReactQueryDevtools initialIsOpen={false} position="bottom-right" />
</QueryClientProvider>
);
Expand Down
5 changes: 4 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import "./globals.css";
import Providers from "./Providers";
import BottomNav from "@/components/BottomNav";
import { usePathname } from "next/navigation";
import { MAX_WIDTH_SIZE } from "@/data/Enum";

export default function RootLayout({
children,
Expand All @@ -17,7 +18,9 @@ export default function RootLayout({
<body>
<Providers>
<main className="bg-red-300">
<section className="relative max-w-[420px] min-w-[280px] h-screen m-auto overflow-y-scroll bg-white shadow-xl">
<section
className={`relative max-w-[420px] min-w-[280px] h-screen m-auto overflow-y-scroll bg-white shadow-xl`}
>
{children}
{pathname !== "/" && <BottomNav />}
</section>
Expand Down
4 changes: 4 additions & 0 deletions src/app/main/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"use client";
import Image from "next/image";
import Logo_H from "@/assets/logo_horizontal.svg";
import BottomNav from "@/components/BottomNav";
import PostInfoCard from "@/components/Common/PostInfoCard";
import ImageCarousel from "@/components/Main/ImageCarousel";
import TodaysHotItemCarousel from "@/components/Main/TodaysHotItemCarousel";
import { useAppSelector } from "@/Redux/store";
import { useSelector } from "react-redux";

const MainPage = () => {
const { token, email } = useAppSelector((state) => state.user);
return (
<main className="overflow-x-hidden h-full">
{/* TODO: 컴포넌트 분리 */}
Expand Down
12 changes: 11 additions & 1 deletion src/app/mypage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@
import Image from "next/image";
import Logo_H_W from "@/assets/logo_horizontal_white.svg";
import Arrow_Right from "@/assets/arrow_right.svg";
import useDeleteUser from "@/hooks/query/userDelete";

const Page = () => {
const deleteUserAPI = useDeleteUser();

const deleteUserHandler = () => {
deleteUserAPI.mutate({ memberId: "kjunho.dev@gmail.com" });
};

return (
<div className="relative overflow-x-hidden h-full bg-[#F7F7F7]">
{/* Header */}
Expand Down Expand Up @@ -32,7 +39,10 @@ const Page = () => {
/>
</div>
<div className="w-[calc(100%-70px)] h-1 border-t-2 " />
<div className="flex w-full items-center justify-between px-9 cursor-pointer">
<div
className="flex w-full items-center justify-between px-9 cursor-pointer"
onClick={deleteUserHandler}
>
<div>회원탈퇴</div>
<Image
src={Arrow_Right}
Expand Down
9 changes: 9 additions & 0 deletions src/assets/thanks.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion src/components/Auth/LoginComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import Str from "@/data/string.json";
import usePostLogin from "@/hooks/query/userPostLogin";
import { ENUM } from "@/data/Enum";
import { useRouter } from "next/navigation";
import { useAppDispatch } from "@/Redux/store";
import { __saveEmail } from "@/Redux/Features/UserSlice";

interface LoginComponentProps {
toggleHandler: () => void;
Expand All @@ -21,8 +23,10 @@ const LoginComponent = ({
const [isButtonDisabled, setIsButtonDisabled] = useState<boolean>(true);
const loginAPI = usePostLogin();
const router = useRouter();
const dispatch = useAppDispatch();

const onLoginHandler = () => {
dispatch(__saveEmail({ email: loginForm.id }));
loginAPI.mutate({
email: loginForm.id,
password: loginForm.pw,
Expand All @@ -35,6 +39,7 @@ const LoginComponent = ({
},
[loginForm, setLoginForm]
);

const onChangePw = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setLoginForm({ ...loginForm, pw: e.target.value });
Expand All @@ -52,7 +57,6 @@ const LoginComponent = ({

useEffect(() => {
if (loginAPI.data?.data.statusCode === ENUM.STATUS_200) {
alert("로그인 성공");
router.push("/main");
}
}, [loginAPI, router]);
Expand Down
26 changes: 21 additions & 5 deletions src/components/Auth/RegisterComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { use, useCallback, useEffect, useState } from "react";
import React, { useEffect, useState } from "react";
import Image from "next/image";
import Back from "@/assets/backButton_red.svg";
import { RegisterFormType } from "./AuthTypes";
Expand All @@ -13,6 +13,8 @@ import usePostEmailDupCheck from "@/hooks/query/userPostEmailCheck copy";
import usePostImageUpload from "@/hooks/query/commonPostImageUpload";
import usePostSignUp from "@/hooks/query/userPostSignUp";
import { useRouter } from "next/navigation";
import Modal from "../Common/Modal";
import Thanks from "@/assets/thanks.svg";

interface RegisterComponentProps {
toggleHandler: () => void;
Expand Down Expand Up @@ -41,14 +43,16 @@ const RegisterComponent = ({
const [previewImage, setPreviewImage] = useState<string>(
"https://cdn-icons-png.flaticon.com/512/338/338864.png"
);
const router = useRouter();

const nameDupCheckAPI = usePostNameDupCheck();
const emailDupCheckAPI = usePostEmailDupCheck();
const imageAPI = usePostImageUpload();
const signupAPI = usePostSignUp();

const [regiSuccessModal, setRegiSuccessModal] = useState(false);

const onNameDupCheckHandler = () => {
nameDupCheckAPI.mutate({ nickName });
nameDupCheckAPI.mutate({ nickname: nickName });
};
const onEmailDupCheckHandler = () => {
emailDupCheckAPI.mutate({ email: id });
Expand Down Expand Up @@ -101,12 +105,24 @@ const RegisterComponent = ({

useEffect(() => {
if (signupAPI.isSuccess) {
alert("회원가입 성공");
setToggle(!toggle);
setRegiSuccessModal(true);
}
}, [signupAPI.isSuccess, toggle, setToggle]);
return (
<>
{regiSuccessModal && (
<Modal
title="회원가입을 환영합니다."
sub="TokTok 회원가입 절차가 "
sub2="완료 되었습니다."
sub3="로그인 후 서비스를"
sub4="이용해 주시기 바랍니다."
img={Thanks}
btnTxt="로그인하러 가기"
btnSetter={setToggle}
modalSetter={setRegiSuccessModal}
/>
)}
<div className="flex flex-col">
{/* 뒤로가기 */}
<div
Expand Down
33 changes: 28 additions & 5 deletions src/components/BottomNav.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
"use client";

import { MAX_WIDTH_SIZE } from "@/data/Enum";
import { useRouter } from "next/navigation";

function BottomNav() {
const router = useRouter();
const navigationHandler = (link: string) => {
router.push(link);
};
return (
<div className="fixed z-40 bottom-0 w-[420px] sm:w-full h-[70px] bg-white border-2">
<div
className={`fixed z-40 bottom-0 w-[420px] sm:w-full h-[70px] bg-white border-2`}
>
<div className="grid grid-cols-4 gap-x-4 justify-items-center mt-1">
<div>
<div
className="flex flex-col justify-center items-center cursor-pointer"
onClick={() => navigationHandler("/posts")}
>
<svg
width="40"
height="40"
Expand All @@ -16,7 +30,10 @@ function BottomNav() {
</svg>
<p className="text-xs text-center">카테고리</p>
</div>
<div>
<div
className="flex flex-col justify-center items-center cursor-pointer"
onClick={() => navigationHandler("/main")}
>
<svg
width="40"
height="40"
Expand All @@ -32,7 +49,10 @@ function BottomNav() {
</svg>
<p className="text-xs text-center">홈</p>
</div>
<div>
<div
className="flex flex-col justify-center items-center cursor-pointer"
onClick={() => navigationHandler("/toktok")}
>
<svg
width="40"
height="40"
Expand All @@ -47,7 +67,10 @@ function BottomNav() {
</svg>
<p className="text-xs text-center">톡톡</p>
</div>
<div>
<div
className="flex flex-col justify-center items-center cursor-pointer"
onClick={() => navigationHandler("/mypage")}
>
<svg
width="40"
height="40"
Expand Down
Loading