Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8a79a6c
styles: edit seller main
kmh990303 Sep 25, 2024
1a45fc7
refactor: seller Login
kmh990303 Sep 25, 2024
be39968
feat: admin 리뷰 데이터 불러오기 및 리뷰 삭제 기능 추가
kmh990303 Sep 29, 2024
61a5e64
styles: admin 리뷰 모니터링 페이지 변경
kmh990303 Sep 29, 2024
2673856
styles: admin 판매 현황 페이지 스크롤바 구현
kmh990303 Sep 29, 2024
121ad55
styles: admin 판매 현황 페이지 차트 수정
kmh990303 Sep 29, 2024
50905df
refactor: admin 로고 바 컴포넌트 구축 및 스타일 수정
kmh990303 Sep 30, 2024
cf770f3
refactor: admin 푸터 바 컴포넌트 구축
kmh990303 Sep 30, 2024
3b29c21
styles: admin 리뷰 모니터링 수정
kmh990303 Sep 30, 2024
c7cbbf3
refactor: admin FooterBar
kmh990303 Sep 30, 2024
61fde35
refactor: admin FooterBar & MultiItem
kmh990303 Sep 30, 2024
df39896
refactor & styles : admin
kmh990303 Oct 1, 2024
df799d3
styles: admin footer
kmh990303 Oct 1, 2024
10e811d
styles: admin
kmh990303 Oct 1, 2024
851f13d
styles: admin
kmh990303 Oct 1, 2024
1f56e7b
refactor: admin
kmh990303 Oct 1, 2024
0952781
refactor: admin
kmh990303 Oct 3, 2024
b27bdeb
refactor: admin
kmh990303 Oct 4, 2024
0c12147
refactor: admin
kmh990303 Oct 6, 2024
9da6f14
feat: admin 데이터 필터링 구현
kmh990303 Oct 10, 2024
7c5be9d
styles: admin 로그인 페이지 스타일 수정
kmh990303 Oct 12, 2024
6496fcf
feat: admin 로딩 스피너 구현
kmh990303 Oct 12, 2024
07d31b8
refactor: 로딩스피너
kmh990303 Oct 14, 2024
3b69336
styles: admin 판매 현황 페이지
kmh990303 Oct 14, 2024
3e09aa5
style(MultiItem.tsx) : px 단위를 rem 단위로 수정
kmh990303 Oct 15, 2024
f928e20
style(product/[slug]) : 상품 상세 페이지 스타일 수정
kmh990303 Oct 15, 2024
7a1a92d
styles: admin 상품 상세 페이지 수정
kmh990303 Oct 21, 2024
b64d77a
styles: admin 상품 상세 페이지 스크롤바 수정
kmh990303 Oct 22, 2024
8d74e61
styles: 루트 디렉토리 layout.tsx에서 화면 크기 수정
kmh990303 Oct 22, 2024
c9d3e7f
styles: 상품 상세 페이지 이미지 영역 변경
kmh990303 Oct 22, 2024
7bf1f55
feat : 브랜드 별 판매 건 수 리스트 구현
kmh990303 Oct 23, 2024
8e74c51
style : mallStatus 페이지 스크롤 수정
kmh990303 Oct 24, 2024
49f158c
style : 상품, 브랜드 상세 페이지 스크롤바 수정
kmh990303 Oct 24, 2024
87a27de
style: 브랜드 상세 페이지 수정
kmh990303 Oct 28, 2024
a1546d5
style: MultiItem 수정
kmh990303 Oct 28, 2024
00152f4
style: 상품 상세 페이지 수정
kmh990303 Oct 28, 2024
631ccdf
style : 리뷰 페이지 수정
kmh990303 Oct 29, 2024
a4afa6f
style : 푸터 바 & 아이템 박스 수정
kmh990303 Oct 29, 2024
118f4d3
style : 애니메이션 효과 추가
kmh990303 Oct 29, 2024
5f3c1af
refactor: api 코드 수정
kmh990303 Nov 18, 2024
74e00c2
refactor: 상품 승인 상태 변경 수정
kmh990303 Nov 19, 2024
446b88f
fix: 토큰 인증 오류 수정
kmh990303 Nov 23, 2024
86e6f78
refactor: 브랜드 요청 코드 리팩토링
kmh990303 Nov 23, 2024
0f6e161
fix: 무한 스크롤 구현 1차 수정
kmh990303 Dec 9, 2024
82c6559
fix: 상품 페이지 무한 스크롤 구현
kmh990303 Dec 10, 2024
b1bb6cb
fix: 상품 클릭 시 라우트 미전환 버그 수정
kmh990303 Dec 10, 2024
b81f2a6
refactor: 브랜드 등록 코드 수정
kmh990303 Dec 21, 2024
ba0ba5b
fix: 새로고침 시 토큰 초기화 해결
kmh990303 Dec 22, 2024
5f38bcf
perf: admin 메인 페이지 성능 개선
kmh990303 Dec 22, 2024
ae6ad17
fix: 브랜드 get 요청 무한 스크롤 구현
kmh990303 Dec 23, 2024
369c53b
fix: 리뷰 api 코드 수정
kmh990303 Dec 23, 2024
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
1,948 changes: 1,861 additions & 87 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@
"@radix-ui/react-accordion": "^1.2.0",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-popover": "1.1.2",
"@radix-ui/react-slot": "^1.1.0",
"@react-icons/all-files": "^4.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"lucide-react": "^0.439.0",
"react-icons": "^5.4.0",
"react-spinners": "^0.14.1",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7",
"zustand": "^4.5.5"
Expand Down
8 changes: 8 additions & 0 deletions src/app/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@
"lint": "next lint"
},
"dependencies": {
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@mui/material": "^6.1.1",
"@mui/x-charts": "^7.18.0",
"@radix-ui/react-checkbox": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-slot": "^1.1.0",
"@shadcn/ui": "^0.0.4",
"@tanstack/react-table": "^8.20.5",
"next": "^14.2.12",
"react": "^18.3.1",
"react-daum-postcode": "^3.1.3",
Expand Down
69 changes: 69 additions & 0 deletions src/app/admin/src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { useAuthenticatedFetch } from '../hooks/useAuthenticatedFetch';

interface LoginResponse {
code: number;
isSuccess: boolean;
message: string;
data: {
grantType: string;
accessToken: string;
refreshToken: string;
};
}

interface KakaoAddressDocument {
address_name: string;
// Add other properties if needed
}

export const useAuthApi = () => {
const authFetch = useAuthenticatedFetch();

const login = async (email: string, password: string): Promise<LoginResponse> => {
const response = await fetch('http://taegnues.store:12324/admins/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!response.ok) {
throw new Error('Login failed');
}
return response.json();
};

// const logout = async () => {
// return authFetch('https://your-backend-api.com/logout', { method: 'POST' });
// };

// const searchKakaoAddress = async (query: string): Promise<string[]> => {

// console.log("check query", query);
// console.log("check secret key", process.env.NEXT_PUBLIC_KAKAO_REST_API_KEY);
// const url = `https://dapi.kakao.com/v2/local/search/address.json?query=${encodeURIComponent(query)}&analyze_type=similar`;

// try {
// const response = await fetch(url, {
// headers: {
// 'Authorization': `KakaoAK ${process.env.NEXT_PUBLIC_KAKAO_REST_API_KEY}`
// }
// });

// if (!response.ok) {
// throw new Error('Network response was not ok');
// }

// const data = await response.json();

// console.log("from api check data", data);
// return data.documents.map((doc: KakaoAddressDocument) => doc.address_name);
// } catch (error) {
// console.error('Error fetching address data:', error);
// return [];
// }
// };




return { login };
};
116 changes: 64 additions & 52 deletions src/app/admin/src/app/(routes)/(landing)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import { useState } from "react";
import { useRouter } from "next/navigation";
import { Button, Input } from "@/packages/ui/src/index";
import { useAuthApi } from "../../../../../buyer/src/api/auth";
import { useAuthStore } from "../../../../../buyer/src/lib/store";
import { useAuthApi } from "../../../api/auth";
import { useAuthStore } from "../../../lib/store";
import { AiOutlineMail, AiOutlineLock } from "react-icons/ai"; // 아이콘 추가

export default function ManagerLoginPage() {
function ManagerLoginPage() {
const router = useRouter();
const { login } = useAuthApi();
const { setAccessToken } = useAuthStore();
const { setAccessToken, setRefreshToken } = useAuthStore();

const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
Expand All @@ -18,60 +19,71 @@ export default function ManagerLoginPage() {
try {
const data = await login(email, password);
setAccessToken(data.data.accessToken);
router.push("/home");
setRefreshToken(data.data.refreshToken);
router.push("/main");
} catch (error) {
window.alert("로그인에 실패했습니다.");
console.error("Login error:", error);
}
};

return (
<>
<div className="px-2">
<h2 className="text-2xl font-bold text-center my-[60px]">로그인</h2>
</div>
<form className="space-y-8 py-4" onSubmit={(e) => e.preventDefault()}>
<div>
<label
htmlFor="email"
className="block text-sm font-bold text-gray-700 mb-1 translate-x-10"
>
이메일
</label>
<Input
type="email"
id="email"
placeholder="이메일 입력"
className="w-[380px] h-[47px] rounded-full border-black ml-3 mx-auto"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div className="flex justify-center items-center min-h-screen">
<div className="w-full max-w-md px-4">
<h2 className="text-2xl font-bold text-center my-12">로그인</h2>

<div>
<label
htmlFor="password"
className="block text-sm font-bold text-gray-700 mb-1 translate-x-10"
>
비밀번호
</label>
<Input
type="password"
id="password"
placeholder="비밀번호 입력"
className="w-[380px] h-[47px] rounded-full border-black ml-3 mx-auto"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<form className="space-y-6 py-4" onSubmit={(e) => e.preventDefault()}>
<div>
<label
htmlFor="email"
className="block text-sm font-bold text-gray-700 mb-2"
>
아이디
</label>
<div className="flex items-center border border-gray-300 rounded-full h-12 px-4">
<AiOutlineMail className="text-gray-500 mr-3" size={24} />{" "}
<Input
type="email"
id="email"
placeholder="이메일 입력"
className="w-full border-none outline-none"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
</div>

<div>
<label
htmlFor="password"
className="block text-sm font-bold text-gray-700 mb-2"
>
비밀번호
</label>
<div className="flex items-center border border-gray-300 rounded-full h-12 px-4">
<AiOutlineLock className="text-gray-500 mr-3" size={24} />{" "}
<Input
type="password"
id="password"
placeholder="비밀번호 입력"
className="w-full border-none outline-none"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
</div>

<Button
className="w-[380px] bg-black text-white hover:bg-gray-700 rounded-full py-2 h-[47px] translate-y-3 block mx-auto"
onClick={handleLogin}
type="button"
>
로그인
</Button>
</form>
</>
<Button
className="w-full bg-black text-white hover:bg-gray-700 rounded-full py-3 h-12 block"
onClick={handleLogin}
type="button"
>
로그인
</Button>
</form>
</div>
</div>
);
}
}

export default ManagerLoginPage;
111 changes: 111 additions & 0 deletions src/app/admin/src/app/(routes)/brand/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"use client";

import { Button } from "@/packages/ui/src/index";
import { SlArrowLeft } from "react-icons/sl";
import { IoHomeOutline } from "react-icons/io5";
import { MdCheckCircle, MdCancel } from "react-icons/md"; // 체크 및 취소 아이콘 추가
import Image from "next/image";

import adidasDetail1 from "@/app/admin/src/assets/adidasDetail.jpg";
// import adidasDetail2 from ("@/app/admin/src/assets/adidasDetail2.jpg");
import clothesLogo from "@/app/admin/src/assets/adidasLogo.png";

import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";

const BrandDetail: React.FC = () => {
const router = useRouter();
const [isApproved, setIsApproved] = useState<string | null>(null);

useEffect(() => {
if (typeof window !== "undefined") {
const queryParams = new URLSearchParams(window.location.search);
const approvedStatus = queryParams.get("isApproved");
setIsApproved(approvedStatus);
}
}, []);

const handleClick = () => {
router.back();
};

const handleHomeClick = () => {
router.push("/main");
};

return (
<>
<div className="flex items-center sticky top-0 z-10 bg-gray-100">
<menu className="flex justify-between items-center w-full py-2">
<SlArrowLeft
className="cursor-pointer ml-5 my-2"
size={20}
onClick={handleClick}
/>
<IoHomeOutline
className="cursor-pointer mr-5 my-2"
size={26}
onClick={handleHomeClick}
/>
</menu>
</div>

<div className="relative w-full mx-auto shadow-md bg-gray-100">
{/* 스크롤 가능한 영역 */}
<div>
<Image
src={adidasDetail1}
alt="shoesImg"
className="w-full h-[80vh] object-contain"
/>

{/* 브랜드 및 로고 */}
<div className="border-b-2 py-4 flex items-center bg-gray-100">
<p className="font-musinsa font-bold text-lg ml-4 text-gray-800 flex flex-col space-y-4">
아디다스
</p>
</div>

{/* 사업자 정보 */}
<div className="bg-gray-100 text-gray-500 font-musinsa text-sm">
<Image
src={clothesLogo}
alt="brandLogo"
className="w-[40%] full mx-auto"
/>
<p className="font-semibold m-1 text-center text-black">아디다스</p>
<p className="font-musinsa text-center m-1">독일 since 1949</p>
<p className="m-7 text-xs py-2">
스포츠 라이프스타일은 라커룸 밖에서도 계속됩니다. 1920년부터
독일의 헤르초게나우라흐에서 스포츠 슈즈를 만들던
아디다스(ADIDAS)는 이러한 철학을 토대로 경기장에서부터 거리에
이르기까지 모두가 즐길 수 있는 '스포츠 라이프스타일'의 개념을
처음으로 도입한 브랜드입니다. 스포츠 영역의 다양한 요소를 일상의
영역으로 가져오는 아디다스는 이를 통해 전 세계의 트렌드를 주도하고
있으며, 지금도 여전히 자신의 다양한 모습을 보여주고 싶어하는
소비자와 직접 소통하며 함께 혁신적인 트렌드를 만들고 있습니다.
</p>
</div>

{/* 승인/거부 버튼 */}
<div className="flex justify-between px-4 mt-5">
{isApproved === "PENDING" && (
<>
<Button className="text-white py-2 hover:bg-green-700 transition-colors w-full mr-2 shadow-md flex items-center justify-center border-2 border-gray-200">
<MdCheckCircle className="mr-2" />
허가
</Button>
<Button className="text-white py-2 hover:bg-red-700 transition-colors w-full ml-2 shadow-md flex items-center justify-center border-2 border-gray-200">
<MdCancel className="mr-2" />
거부
</Button>
</>
)}
</div>
</div>
</div>
</>
);
};

export default BrandDetail;
42 changes: 0 additions & 42 deletions src/app/admin/src/app/(routes)/brand/detail/page.tsx

This file was deleted.

Loading