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
59 changes: 59 additions & 0 deletions apps/owner/src/app/(tabs)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"use client";

import { usePathname, useRouter } from "next/navigation";
import { BottomTabBar } from "@compasser/design-system";
import type { ReactNode } from "react";

interface TabsLayoutProps {
children: ReactNode;
}

const tabItems = [
{ key: "home", ariaLabel: "홈", iconName: "Home" },
{ key: "order", ariaLabel: "주문", iconName: "Order" },
{ key: "my", ariaLabel: "마이페이지", iconName: "My" },
] as const;

export default function TabsLayout({ children }: TabsLayoutProps) {
const router = useRouter();
const pathname = usePathname();

const activeKey = pathname.startsWith("/mypage")
? "my"
: pathname.startsWith("/order")
? "order"
: pathname.startsWith("/main")
? "home"
: "home";

const handleTabChange = (key: string) => {
if (key === "home") {
router.push("/main");
return;
}

if (key === "order") {
router.push("/order");
return;
}

if (key === "my") {
router.push("/mypage");
}
};

return (
<div className="flex h-dvh w-full flex-col overflow-hidden bg-white">
<div className="ds-scrollbar-hidden flex-1 overflow-y-auto">
{children}
</div>

<BottomTabBar
items={tabItems}
activeKey={activeKey}
onTabChange={handleTabChange}
className="max-w-[42.5rem]"
/>
</div>
);
}
63 changes: 63 additions & 0 deletions apps/owner/src/app/(tabs)/main/_components/CafeIntro.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"use client";

import { Icon } from "@compasser/design-system";

interface CafeIntroProps {
cafeName: string;
}

const formatCafeName = (name: string) => {
if (name.length <= 10) {
return { firstLine: name, secondLine: "" };
}

const firstTen = name.slice(0, 10);
const spaceIndexes = [...firstTen]
.map((char, index) => (char === " " ? index : -1))
.filter((index) => index !== -1);

if (spaceIndexes.length >= 2) {
const breakIndex = spaceIndexes[1];

return {
firstLine: name.slice(0, breakIndex).trim(),
secondLine: name.slice(breakIndex + 1).trim(),
};
}

return {
firstLine: name.slice(0, 10).trim(),
secondLine: name.slice(10).trim(),
};
};

export default function CafeIntro({ cafeName }: CafeIntroProps) {
const { firstLine, secondLine } = formatCafeName(cafeName);

return (
<section className="flex items-start justify-between">
<div className="pt-[0.5rem]">
<p className="head3-m text-gray-700">어서오세요!</p>

<div className="mt-[0.4rem]">
<p
className="head2-m whitespace-pre-line text-primary"
style={{ textShadow: "0 4px 3px rgba(0, 0, 0, 0.2)" }}
>
{firstLine}
{secondLine ? `\n${secondLine}` : ""}
</p>
</div>

<p className="mt-[0.4rem] head3-m text-gray-700">입니다.</p>
</div>

<Icon
name="Stamp"
width={100}
height={100}
className="shrink-0"
/>
</section>
);
}
52 changes: 52 additions & 0 deletions apps/owner/src/app/(tabs)/main/_components/TodayOrders.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"use client";

import { Card } from "@compasser/design-system";
import type { OrderItem } from "../_types/main.types";

interface TodayOrdersProps {
orders: OrderItem[];
}

const formatNickname = (name: string) => {
if (name.length <= 3) return `${name}님`;
return `${name.slice(0, 2)}...님`;
};

const formatRandomBoxName = (name: string) => {
if (name.length <= 11) return name;
return `${name.slice(0, 10)}...`;
};

const formatPrice = (price: number) => `${price}원`;

export default function TodayOrders({ orders }: TodayOrdersProps) {
return (
<section className="mt-[6rem]">
<h2 className="body1-m text-default">오늘의 주문</h2>

<div className="mt-[1.2rem] flex flex-col gap-[0.8rem]">
{orders.slice(0, 3).map((order) => (
<Card
key={order.id}
variant="inverse-elevated"
className="px-[1rem] py-[0.8rem]"
>
<div className="flex items-center">
<span className="body1-r shrink-0 text-default">
{formatNickname(order.customerName)}
</span>

<span className="body1-r ml-[2rem] min-w-0 flex-1 truncate text-default">
{formatRandomBoxName(order.randomBoxName)}
</span>

<span className="body1-r ml-[1rem] shrink-0 text-default">
{formatPrice(order.price)}
</span>
</div>
</Card>
))}
</div>
</section>
);
}
41 changes: 41 additions & 0 deletions apps/owner/src/app/(tabs)/main/_components/TodayRewards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";

import { Card } from "@compasser/design-system";

interface TodayRewardsProps {
couponUsedCount: number;
stampSavedCount: number;
}

export default function TodayRewards({
couponUsedCount,
stampSavedCount,
}: TodayRewardsProps) {
return (
<section className="mt-[4rem]">
<h2 className="body1-m text-default">오늘의 적립</h2>

<div className="mt-[1.2rem] flex gap-[1.6rem]">
<Card
variant="inverse-elevated"
className="flex w-full flex-col items-center justify-center px-[1rem] py-[2.15rem]"
>
<p className="body1-m text-center text-gray-700">쿠폰 사용 수</p>
<p className="head1-sb mt-[2rem] text-center text-primary">
{couponUsedCount}건
</p>
</Card>

<Card
variant="inverse-elevated"
className="flex w-full flex-col items-center justify-center px-[1rem] py-[2.15rem]"
>
<p className="body1-m text-center text-gray-700">도장 적립 수</p>
<p className="head1-sb mt-[2rem] text-center text-primary">
{stampSavedCount}건
</p>
</Card>
</div>
</section>
);
}
29 changes: 29 additions & 0 deletions apps/owner/src/app/(tabs)/main/_constants/mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { OrderItem } from "../_types/main.types";

export const MOCK_CAFE_NAME = "별동네 베이커리카페 별내본점";

export const MOCK_ORDERS: OrderItem[] = [
{
id: 1,
customerName: "감자링",
randomBoxName: "랜덤박스 1레벨 주문",
price: 5000,
},
{
id: 2,
customerName: "역곡역앞",
randomBoxName: "랜덤박스 1레벨 주문",
price: 10000,
},
{
id: 3,
customerName: "하루이틀삼일",
randomBoxName: "랜덤박스 1레벨 주문",
price: 20000,
},
];

export const MOCK_REWARD_SUMMARY = {
couponUsedCount: 1,
stampSavedCount: 10,
};
6 changes: 6 additions & 0 deletions apps/owner/src/app/(tabs)/main/_types/main.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface OrderItem {
id: number;
customerName: string;
randomBoxName: string;
price: number;
}
25 changes: 25 additions & 0 deletions apps/owner/src/app/(tabs)/main/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use client";

import CafeIntro from "./_components/CafeIntro";
import TodayOrders from "./_components/TodayOrders";
import TodayRewards from "./_components/TodayRewards";
import {
MOCK_CAFE_NAME,
MOCK_ORDERS,
MOCK_REWARD_SUMMARY,
} from "./_constants/mock";

export default function OwnerMainPage() {
return (
<main className="bg-background min-h-full px-[1.6rem] pt-[5.6rem]">
<CafeIntro cafeName={MOCK_CAFE_NAME} />

<TodayOrders orders={MOCK_ORDERS} />

<TodayRewards
couponUsedCount={MOCK_REWARD_SUMMARY.couponUsedCount}
stampSavedCount={MOCK_REWARD_SUMMARY.stampSavedCount}
/>
</main>
);
}
1 change: 1 addition & 0 deletions packages/design-system/src/icons/generated/iconNames.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const iconNames = [
"ProfileCharacter",
"RadioActive",
"RadioDeactive",
"Stamp",
"StoreIcon"
] as const;
export type IconName = typeof iconNames[number];

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/design-system/src/icons/source/Stamp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion packages/design-system/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ html {

@media (hover: hover) and (pointer: fine) {
.app-wrapper {
max-width: 390px;
max-width: 425px;
}
}
Loading