Skip to content
Merged
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
1,409 changes: 1,409 additions & 0 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ yarn dev:user # 사용자용 앱 실행
yarn dev:admin # 관리자용 앱 실행
```

## 🔗배포주소
## 🔗 배포주소
```txt
사용자: https://www.nowait.co.kr
사용자: https://www.nowait-user.vercel.app
관리자: https://www.nowait-admin.com
```
23 changes: 17 additions & 6 deletions apps/nowait-admin/src/pages/AdminAnalytics/AdminAnalytics.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useState } from "react";
import { useGetPopularMenu } from "../../hooks/analytics/useGetPopularMenu";
import { useGetSalesByDate } from "../../hooks/analytics/useGetSalesByDate";
import { useGetTopSales } from "../../hooks/analytics/useGetTopSalse";
Expand All @@ -18,19 +19,21 @@ interface BoothRanking {
const AdminAnalytics = () => {
const today = new Date();
const formatted = today.toISOString().slice(0, 10);
const [currentDate, setCurrentDate] = useState(() => {
const today = new Date();
return today.toISOString().slice(0, 10);
});
console.log(formatted, "오늘날짜");

const width = useWindowWidth();
const isTablet = width >= 768;
const isMobile = width < 432;
const { data: boothRank } = useGetTopSales();
const { data: sales } = useGetSalesByDate(formatted);
const { data: sales } = useGetSalesByDate(currentDate);
const { data: popularMenu } = useGetPopularMenu();

const boothDisabled = boothRank?.length === 0;
const storeId = localStorage.getItem("storeId");
const saleDisabled =
typeof sales === "string" ||
sales === undefined ||
(sales?.todaySalesSum === 0 && sales?.yesterdaySalesSum === 0);
const poupularMenuDisabled = popularMenu?.length === 0;

const boothRankingData: BoothRanking[] =
Expand All @@ -46,7 +49,14 @@ const AdminAnalytics = () => {
}))
: [];

const changeDate = (days: number) => {
const newDate = new Date(currentDate);
newDate.setDate(newDate.getDate() + days);
setCurrentDate(newDate.toISOString().slice(0, 10));
};

console.log(popularMenu, "인기메뉴 원래데이터");
console.log(sales, "날짜별 조회");

return (
<div
Expand All @@ -58,9 +68,10 @@ const AdminAnalytics = () => {
isTablet={isTablet}
isMobile={isMobile}
sales={sales}
currentDate={currentDate}
popularMenu={popularMenu}
saleDisabled={saleDisabled}
poupularMenuDisabled={poupularMenuDisabled}
onDateChange={changeDate}
/>
<BoothSalesRankingCard
isTablet={isTablet}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,30 @@ interface HeaderStatusProps {
soldCount: number;
imageUrl?: string;
}[];
saleDisabled: boolean;
currentDate: string;
poupularMenuDisabled: boolean;
isTablet: boolean;
isMobile: boolean;
onDateChange: (days: number) => void;
}

const HeaderStatus: React.FC<HeaderStatusProps> = ({
sales,
currentDate,
popularMenu,
saleDisabled,
poupularMenuDisabled,
isTablet,
isMobile,
onDateChange,
}) => {
const todayAmount = sales?.todaySalesSum ?? 0;
const yesterdayAmount = sales?.yesterdaySalesSum ?? 0;
const totalAmount =
(sales?.cumulativeSalesBeforeYesterday ?? 0) + todayAmount;
const diffAmount = todayAmount - yesterdayAmount;
const percent = yesterdayAmount
? parseFloat(((diffAmount / yesterdayAmount) * 100).toFixed(1))
: 0;
// const percent = yesterdayAmount
// ? parseFloat(((diffAmount / yesterdayAmount) * 100).toFixed(1))
// : 0;

const formatDate = (date: Date | string): string => {
if (typeof date === "string") {
Expand All @@ -56,7 +58,7 @@ const HeaderStatus: React.FC<HeaderStatusProps> = ({
yesterday.setDate(today.getDate() - 1);

const todayDate = formatDate(today);
const yesterdayDate = formatDate(yesterday);
// const yesterdayDate = formatDate(yesterday);

console.log(popularMenu, "인기 메뉴");

Expand All @@ -70,25 +72,29 @@ const HeaderStatus: React.FC<HeaderStatusProps> = ({
>
<div className="flex flex-col gap-[10px]">
<SalesCard
today={{
date: todayDate,
amount: todayAmount,
diffAmount,
percent,
sales={{
date: currentDate,
amount: sales?.todaySalesSum ?? 0,
diffAmount: diffAmount,
percent: sales?.yesterdaySalesSum
? parseFloat(
(
((sales?.todaySalesSum - sales?.yesterdaySalesSum) /
sales?.yesterdaySalesSum) *
100
).toFixed(1)
)
: 0,
}}
previous={{
date: yesterdayDate,
amount: yesterdayAmount,
}}
disabled={saleDisabled}
currentDate={currentDate}
isTablet={isTablet}
onDateChange={onDateChange}
/>

<TotalSalesCard
title="누적매출"
date={`${todayDate} 기준`}
amount={totalAmount}
disabled={saleDisabled}
isTablet={isTablet}
/>
</div>
Expand Down
86 changes: 31 additions & 55 deletions apps/nowait-admin/src/pages/AdminAnalytics/components/SalesCard.tsx
Original file line number Diff line number Diff line change
@@ -1,111 +1,87 @@
import backIcon from "../../../assets/analytics/arrow_back.svg";
// import backIcon from "../../../assets/analytics/arrow_back.svg";
import forwardIcon from "../../../assets/analytics/arrow_forward.svg";
import activeBackIcon from "../../../assets/analytics/arrow_back_active.svg";
import activeForwardIcon from "../../../assets/analytics/arrow_forward_active.svg";
import { useState } from "react";

interface SalesCardProps {
today: {
sales?: {
date: string;
amount: number;
diffAmount: number;
percent: number;
};
previous: {
date: string;
amount: number;
};
disabled: boolean;
isTablet: boolean;
onDateChange: (days: number) => void;
currentDate: string;
}

const SalesCard: React.FC<SalesCardProps> = ({
today,
previous,
disabled,
sales,
isTablet,
onDateChange,
currentDate,
}) => {
const [showToday, setShowToday] = useState(true);

const formatDate = (date: String) => {
if (!date) return "";
return `${date.replace(/-/g, ".")}`;
};
const todayISO = new Date().toISOString().slice(0, 10);
const isFuture = currentDate > todayISO; // 오늘보다 미래인지 확인
const isToday = currentDate === todayISO;
console.log(sales, "오늘 판배 목록");

return (
<div
className={`bg-white rounded-[16px] flex flex-col justify-between ${
isTablet ? "p-6 w-full h-full" : "p-5 w-[335px] min-h-[150px]"
}`}
>
{/* 상단 헤더 */}
<div className="flex justify-between">
<span>
<p className="text-title-18-bold text-navy-80">
{showToday ? "오늘 매출" : "이전 매출"}
</p>
<p className="text-13-regular text-black-60 mt-1">
{showToday ? formatDate(today.date) : formatDate(previous.date)}
{isToday ? "오늘 매출" : "이전 매출"}
</p>
<p className="text-13-regular text-black-60 mt-1">{currentDate}</p>
</span>

<span className="flex">
{/* 이전 버튼 */}
{/* 왼쪽(과거) 버튼 */}
<button
className={`h-5 w-5 ${
disabled ? "cursor-not-allowed" : "cursor-pointer"
isFuture ? "cursor-not-allowed" : "cursor-pointer"
}`}
onClick={() => showToday && setShowToday(false)}
onClick={() => onDateChange(-1)}
>
<img
src={
showToday ? (disabled ? backIcon : activeBackIcon) : backIcon
}
/>
<img src={activeBackIcon} />
</button>
{/* 다음 버튼 */}

{/* 오른쪽(미래) 버튼 */}
<button
className={`h-5 w-5 ${
disabled ? "cursor-not-allowed" : "cursor-pointer"
isFuture || isToday ? "cursor-not-allowed" : "cursor-pointer"
}`}
onClick={() => !showToday && setShowToday(true)}
onClick={() => {
if (!isFuture && !isToday) onDateChange(1);
}}
>
<img
src={
!showToday
? disabled
? forwardIcon
: activeForwardIcon
: forwardIcon
}
/>
<img src={isFuture || isToday ? forwardIcon : activeForwardIcon} />
</button>
</span>
</div>

{/* 하단 내용 */}
<div className="flex flex-col">
<div className="flex items-baseline">
<p className="text-headline-22-bold text-navy-80">
{showToday
? today.amount.toLocaleString()
: previous.amount.toLocaleString()}
{`${(sales?.amount ?? 0).toLocaleString()}원`}
</p>

{!disabled && showToday && (
<span className="text-[#FF4103]">
{today.percent > 0 ? `+${today.percent}%` : ""}
</span>
{!!sales?.percent && sales.percent > 0 && (
<span className="text-[#FF4103] ml-1">{`+${sales?.percent}%`}</span>
)}
</div>

{!disabled && showToday && (
{!!sales?.diffAmount && sales.diffAmount > 0 && (
<p className="text-13-regular text-black-80">
{today.diffAmount > 0
? `어제보다 ${today.diffAmount.toLocaleString()}원 더 벌었어요!`
: ""}
{`어제보다 ${sales.diffAmount.toLocaleString()}원 더 벌었어요!`}
</p>
)}
{disabled && showToday && <></>}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ interface TotalSalesCardProps {
title: string; // 예: "누적매출"
date: string; // 예: "2025. 07.18 - 07.19"
amount: number; // 예: 1800000
disabled: boolean;
isTablet: boolean;
}

const TotalSalesCard: React.FC<TotalSalesCardProps> = ({
title,
date,
amount,
disabled,
isTablet,
}) => {
return (
Expand All @@ -30,7 +28,7 @@ const TotalSalesCard: React.FC<TotalSalesCardProps> = ({
{/* 금액 + 퍼센트 변화 */}
<div className="flex items-baseline gap-2 mt-4">
<p className="text-headline-22-bold text-[#1C1C1C]">
{disabled ? 0 : amount.toLocaleString()}원
{amount.toLocaleString()}원
</p>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions apps/nowait-user/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@vercel/speed-insights": "^1.2.0",
"axios": "^1.10.0",
"color-thief-react": "^2.1.0",
"firebase": "^12.5.0",
"framer-motion": "^12.20.1",
"jwt-decode": "^4.0.0",
"leaflet": "^1.9.4",
Expand Down
Binary file removed apps/nowait-user/src/assets/orderSuccess.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed apps/nowait-user/src/assets/remittanceWait.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions apps/nowait-user/src/firebaseConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { initializeApp } from "firebase/app";
import { getPerformance } from "firebase/performance";

const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
};

const app = initializeApp(firebaseConfig);

const perf: ReturnType<typeof getPerformance> | undefined =
typeof window !== "undefined" ? getPerformance(app) : undefined;

export { app, perf };
15 changes: 15 additions & 0 deletions apps/nowait-user/src/hooks/useFallbackImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { useEffect, useState } from "react";

export const useFallbackImage = (src: string) => {
const [isLoaded, setIsLoaded] = useState(false);
const [loadedSrc, setLoadedSrc] = useState("");
useEffect(() => {
const img = new Image();
img.src = src;
img.onload = () => {
setLoadedSrc(src);
setIsLoaded(true);
};
}, [src]);
return { isLoaded, loadedSrc };
};
3 changes: 2 additions & 1 deletion apps/nowait-user/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { createRoot } from "react-dom/client";
import "./global.css";
import App from "./App.tsx";
import { initSentry } from "./utils/initSentry.ts";

import { perf } from "./firebaseConfig";
if (perf) console.log("Firebase Performance initialized", perf);
initSentry();

createRoot(document.getElementById("root")!).render(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { useNavigate, useParams } from "react-router-dom";
import SuccessMessagePage from "../../../components/common/SuccessMessagePage";
import OrderSuccessFallback from "../../../assets/orderSuccessFallback.webp";
import OrderSuccess from "../../../assets/orderSuccess.webp";
import { useFallbackImage } from "../../../hooks/useFallbackImage";

const OrderSuccessPage = () => {
const navigate = useNavigate();
const { storeId } = useParams();
const { isLoaded, loadedSrc } = useFallbackImage(OrderSuccess);

return (
<SuccessMessagePage
ImageSrc={OrderSuccess}
ImageSrc={isLoaded ? loadedSrc : OrderSuccessFallback}
imageAlt="주문 완료 이미지"
title="주문이 접수되었어요!"
message={`입금 확인 후 조리를 진행할게요.\n조금만 기다려 주세요.`}
Expand Down
Loading