diff --git a/codebase/backend/frontend-test-site/app/index.tsx b/codebase/backend/frontend-test-site/app/index.tsx
index e06cdf4..10cdff6 100644
--- a/codebase/backend/frontend-test-site/app/index.tsx
+++ b/codebase/backend/frontend-test-site/app/index.tsx
@@ -182,7 +182,10 @@ export default function HomeScreen() {
sending={sending}
value={message}
/>
-
+
{Boolean(sendError) && (
diff --git a/codebase/backend/frontend-test-site/src/components/AppHeader.tsx b/codebase/backend/frontend-test-site/src/components/AppHeader.tsx
index 9c305c3..e08944a 100644
--- a/codebase/backend/frontend-test-site/src/components/AppHeader.tsx
+++ b/codebase/backend/frontend-test-site/src/components/AppHeader.tsx
@@ -7,7 +7,7 @@ import { useApp } from "../app-context";
import { notificationApi, notificationKeys } from "../notification-api";
import { colors, radii, spacing } from "../theme";
-export function AppHeader({ guestLabel }: { guestLabel?: string | undefined }) {
+export function AppHeader(_props: { guestLabel?: string | undefined }) {
const { authStatus } = useApp();
const authenticated = authStatus === "authenticated";
const counter = useQuery({
@@ -20,7 +20,7 @@ export function AppHeader({ guestLabel }: { guestLabel?: string | undefined }) {
return (
- [styles.centerLink, pressed && styles.pressed]}>
+ [styles.centerLink, pressed && styles.pressed]}>
{authenticated && unread > 0 && (
@@ -29,19 +29,15 @@ export function AppHeader({ guestLabel }: { guestLabel?: string | undefined }) {
)}
- Центр
-
- {guestLabel && {guestLabel}}
-
- [styles.avatar, pressed && styles.pressed]}>
-
-
-
-
-
+
+ [styles.avatar, pressed && styles.pressed]}>
+
+
+
+
);
}
@@ -57,8 +53,7 @@ const styles = StyleSheet.create({
borderBottomWidth: 1,
borderBottomColor: colors.border,
},
- centerLink: { flexDirection: "row", alignItems: "center", gap: spacing.sm },
- centerText: { fontSize: 14, color: colors.foreground },
+ centerLink: { width: 40, height: 40, alignItems: "center", justifyContent: "center" },
notificationBadge: {
position: "absolute",
top: -9,
@@ -74,8 +69,6 @@ const styles = StyleSheet.create({
borderColor: colors.background,
},
notificationBadgeText: { color: colors.primaryForeground, fontSize: 9, fontWeight: "700" },
- right: { flexDirection: "row", alignItems: "center", gap: spacing.sm },
- guestBadge: { fontSize: 12, color: colors.mutedForeground },
avatar: {
width: 40,
height: 40,
diff --git a/codebase/backend/frontend-test-site/src/components/NotificationCard.tsx b/codebase/backend/frontend-test-site/src/components/NotificationCard.tsx
index f8b15bb..61d603b 100644
--- a/codebase/backend/frontend-test-site/src/components/NotificationCard.tsx
+++ b/codebase/backend/frontend-test-site/src/components/NotificationCard.tsx
@@ -2,7 +2,7 @@ import { Feather } from "@expo/vector-icons";
import React from "react";
import { Pressable, StyleSheet, Text, View } from "react-native";
import { formatNotificationPrice, notificationIcon, notificationPalette } from "../notification-presenter";
-import { radii, spacing } from "../theme";
+import { colors, radii, spacing } from "../theme";
import type { NotificationItem, NotificationType } from "../types";
export function NotificationCard({
@@ -10,6 +10,11 @@ export function NotificationCard({
type,
onCta,
onHide,
+ onNext,
+ onPrevious,
+ position,
+ total,
+ width,
compact = false,
disabled = false,
}: {
@@ -17,6 +22,11 @@ export function NotificationCard({
type: NotificationType | undefined;
onCta: () => void;
onHide?: () => void;
+ onNext?: () => void;
+ onPrevious?: () => void;
+ position?: number;
+ total?: number;
+ width?: number;
compact?: boolean;
disabled?: boolean;
}) {
@@ -29,42 +39,65 @@ export function NotificationCard({
-
-
- {type?.label ?? "Уведомление"}
+
+ {type?.label ?? "Уведомление"}
{type?.countable && item.is_read === false && }
- {onHide && (
-
-
-
- )}
+
+ {onPrevious && total && total > 1 ? (
+
+
+
+ ) : null}
+ {position !== undefined && total && total > 1 ? (
+ {position}/{total}
+ ) : null}
+ {onNext && total && total > 1 ? (
+
+
+
+ ) : null}
+ {onHide && (
+
+
+
+ )}
+
- {item.header}
- {item.text ? {item.text} : null}
- {deadline ? (
-
-
- до {new Date(deadline).toLocaleDateString("ru-RU")}
+
+
+
- ) : null}
- {price ? (
-
- {price}
- {oldPrice ? {oldPrice} : null}
+
+ {item.header}
+ {item.text ? {item.text} : null}
+ {deadline ? (
+
+
+ до {new Date(deadline).toLocaleDateString("ru-RU")}
+
+ ) : null}
+ {price ? (
+
+ {price}
+ {oldPrice ? {oldPrice} : null}
+
+ ) : null}
- ) : null}
+
+
[local.cta, { backgroundColor: palette.accent }, pressed && local.pressed, disabled && local.disabled]}
+ style={({ pressed }) => [local.cta, pressed && local.pressed, disabled && local.disabled]}
>
- {type?.cta_text ?? "Подробнее →"}
+ {type?.cta_text ?? "Подробнее →"}
);
@@ -73,26 +106,31 @@ export function NotificationCard({
const local = StyleSheet.create({
card: {
width: 326,
- minHeight: 190,
borderWidth: 1,
borderRadius: radii.xl,
- padding: spacing.lg,
- gap: spacing.sm,
+ overflow: "hidden",
},
compact: { width: "100%", minHeight: 0 },
- headerRow: { flexDirection: "row", justifyContent: "space-between", alignItems: "center" },
- labelRow: { flexDirection: "row", alignItems: "center", gap: spacing.sm, flexShrink: 1 },
- label: { fontSize: 12, fontWeight: "600", textTransform: "uppercase", letterSpacing: 0.4 },
+ headerRow: { minHeight: 42, paddingHorizontal: 14, paddingTop: 10, paddingBottom: 6, flexDirection: "row", justifyContent: "space-between", alignItems: "center" },
+ labelBadge: { minHeight: 24, borderRadius: radii.full, paddingHorizontal: 10, flexDirection: "row", alignItems: "center", gap: 6, flexShrink: 1 },
+ label: { fontSize: 11, fontWeight: "700", textTransform: "uppercase", letterSpacing: 0.5 },
unread: { width: 8, height: 8, borderRadius: radii.full },
- title: { fontSize: 18, lineHeight: 23, fontWeight: "600" },
- text: { fontSize: 14, lineHeight: 20, opacity: 0.88 },
+ controls: { flexDirection: "row", alignItems: "center" },
+ controlButton: { width: 28, height: 28, alignItems: "center", justifyContent: "center" },
+ hideButton: { width: 28, height: 28, marginLeft: 2, alignItems: "center", justifyContent: "center" },
+ position: { minWidth: 32, textAlign: "center", fontSize: 11, color: colors.mutedForeground },
+ body: { flexDirection: "row", alignItems: "flex-start", gap: spacing.md, paddingHorizontal: 14, paddingBottom: spacing.md },
+ iconWrap: { width: 36, height: 36, borderRadius: radii.full, alignItems: "center", justifyContent: "center", flexShrink: 0 },
+ content: { flex: 1, minWidth: 0 },
+ title: { fontSize: 14, lineHeight: 19, fontWeight: "600", marginBottom: 2 },
+ text: { fontSize: 12, lineHeight: 17, color: colors.mutedForeground },
deadline: { flexDirection: "row", alignItems: "center", gap: spacing.xs },
- meta: { fontSize: 12 },
+ meta: { fontSize: 11, color: colors.mutedForeground },
priceRow: { flexDirection: "row", alignItems: "baseline", gap: spacing.sm },
- price: { fontSize: 18, fontWeight: "700" },
- oldPrice: { fontSize: 13, textDecorationLine: "line-through", opacity: 0.65 },
- cta: { alignSelf: "flex-start", minHeight: 38, justifyContent: "center", borderRadius: radii.md, paddingHorizontal: spacing.md, marginTop: "auto" },
- ctaText: { color: "#ffffff", fontSize: 14, fontWeight: "600" },
+ price: { fontSize: 14, fontWeight: "700" },
+ oldPrice: { fontSize: 11, color: colors.mutedForeground, textDecorationLine: "line-through" },
+ cta: { minHeight: 39, justifyContent: "center", borderTopWidth: 1, borderTopColor: "rgba(0, 0, 0, 0.06)", paddingHorizontal: 14 },
+ ctaText: { fontSize: 12, fontWeight: "700" },
pressed: { opacity: 0.78 },
disabled: { opacity: 0.5 },
});
diff --git a/codebase/backend/frontend-test-site/src/components/NotificationCarousel.tsx b/codebase/backend/frontend-test-site/src/components/NotificationCarousel.tsx
index 5f4938c..ad583c9 100644
--- a/codebase/backend/frontend-test-site/src/components/NotificationCarousel.tsx
+++ b/codebase/backend/frontend-test-site/src/components/NotificationCarousel.tsx
@@ -1,12 +1,12 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import React, { useEffect, useMemo, useRef, useState } from "react";
-import { FlatList, StyleSheet, Text, View } from "react-native";
+import { FlatList, StyleSheet, useWindowDimensions, View } from "react-native";
import { notificationApi, notificationKeys } from "../notification-api";
import { useNotificationAction } from "../notification-actions";
import { typeMap } from "../notification-presenter";
-import { colors, spacing } from "../theme";
+import { layout, spacing } from "../theme";
import type { NotificationItem } from "../types";
-import { ErrorNotice, Loading, styles } from "../ui";
+import { ErrorNotice, Loading } from "../ui";
import { NotificationCard } from "./NotificationCard";
export function NotificationCarousel({
@@ -24,6 +24,9 @@ export function NotificationCarousel({
const list = useRef>(null);
const [activeIndex, setActiveIndex] = useState(0);
const [actionError, setActionError] = useState();
+ const [hiddenGuestIds, setHiddenGuestIds] = useState>(() => new Set());
+ const window = useWindowDimensions();
+ const cardWidth = Math.max(0, Math.min(window.width, layout.maxWidth) - spacing.lg * 2);
const catalog = useQuery({
queryKey: notificationKeys.catalog,
queryFn: notificationApi.catalog,
@@ -45,7 +48,14 @@ export function NotificationCarousel({
},
onError: setActionError,
});
- const data = notifications.data ?? [];
+ const data = (notifications.data ?? []).filter((item) => authenticated || !hiddenGuestIds.has(item.id));
+
+ const goTo = (index: number) => {
+ if (data.length < 2) return;
+ const next = (index + data.length) % data.length;
+ setActiveIndex(next);
+ list.current?.scrollToIndex({ index: next, animated: true });
+ };
useEffect(() => {
if (!autoplay || data.length < 2) return;
@@ -59,6 +69,13 @@ export function NotificationCarousel({
return () => clearInterval(timer);
}, [autoplay, autoplayIntervalMs, data.length]);
+ useEffect(() => {
+ if (activeIndex < data.length) return;
+ const next = Math.max(data.length - 1, 0);
+ setActiveIndex(next);
+ list.current?.scrollToIndex({ index: next, animated: false });
+ }, [activeIndex, data.length]);
+
if (notifications.isLoading || catalog.isLoading) {
return ;
}
@@ -76,17 +93,21 @@ export function NotificationCarousel({
return (
- Важное для вас
({ length: cardWidth, offset: cardWidth * index, index })}
keyExtractor={(item) => item.id}
- contentContainerStyle={local.content}
- ItemSeparatorComponent={() => }
+ style={local.carousel}
onMomentumScrollEnd={(event) => {
- const width = event.nativeEvent.layoutMeasurement.width;
- if (width > 0) setActiveIndex(Math.round(event.nativeEvent.contentOffset.x / width));
+ if (cardWidth > 0) {
+ setActiveIndex(Math.min(data.length - 1, Math.round(event.nativeEvent.contentOffset.x / cardWidth)));
+ }
}}
renderItem={({ item }) => (
void action(item, byCode.get(item.notification_type))}
- {...(authenticated ? { onHide: () => hide.mutate(item.id) } : {})}
+ onNext={() => goTo(activeIndex + 1)}
+ onPrevious={() => goTo(activeIndex - 1)}
+ position={activeIndex + 1}
+ total={data.length}
+ width={cardWidth}
+ onHide={() => {
+ if (authenticated) {
+ hide.mutate(item.id);
+ } else {
+ setHiddenGuestIds((current) => new Set(current).add(item.id));
+ }
+ }}
/>
)}
showsHorizontalScrollIndicator={false}
/>
- {data.length > 1 && (
-
- {data.map((item, index) => )}
-
- )}
{Boolean(actionError) && }
);
@@ -111,11 +138,7 @@ export function NotificationCarousel({
const local = StyleSheet.create({
section: { paddingVertical: spacing.md },
- heading: { paddingHorizontal: spacing.lg, marginBottom: spacing.sm },
- content: { paddingHorizontal: spacing.lg },
+ carousel: { marginHorizontal: spacing.lg },
state: { paddingHorizontal: spacing.lg, paddingVertical: spacing.md },
- dots: { flexDirection: "row", justifyContent: "center", gap: 6, marginTop: spacing.sm },
- dot: { width: 6, height: 6, borderRadius: 3, backgroundColor: colors.muted },
- dotActive: { width: 16, backgroundColor: colors.primary },
error: { paddingHorizontal: spacing.lg, paddingTop: spacing.sm },
});
diff --git a/codebase/backend/frontend-test-site/src/components/PopularQuestionsList.tsx b/codebase/backend/frontend-test-site/src/components/PopularQuestionsList.tsx
index 524c688..88b98b7 100644
--- a/codebase/backend/frontend-test-site/src/components/PopularQuestionsList.tsx
+++ b/codebase/backend/frontend-test-site/src/components/PopularQuestionsList.tsx
@@ -22,7 +22,7 @@ export function PopularQuestionsList({ questions, onSelect }: { questions: Quest
style={({ pressed }) => [styles.item, pressed && styles.pressed]}
>
-
+
{question.text}
@@ -54,6 +54,6 @@ const styles = StyleSheet.create({
alignItems: "center",
justifyContent: "center",
},
- itemText: { flex: 1, fontSize: 14, color: colors.foreground },
+ itemText: { flex: 1, fontSize: 14, fontWeight: "600", color: colors.foreground },
pressed: { backgroundColor: colors.accent },
});
diff --git a/codebase/backend/frontend-test-site/src/components/QuickActions.tsx b/codebase/backend/frontend-test-site/src/components/QuickActions.tsx
index 5115918..2987412 100644
--- a/codebase/backend/frontend-test-site/src/components/QuickActions.tsx
+++ b/codebase/backend/frontend-test-site/src/components/QuickActions.tsx
@@ -1,39 +1,137 @@
import { Feather } from "@expo/vector-icons";
-import React from "react";
-import { Linking, Pressable, StyleSheet, Text } from "react-native";
+import { useQuery } from "@tanstack/react-query";
+import { useRouter } from "expo-router";
+import React, { useEffect, useRef } from "react";
+import { Animated, Linking, Pressable, StyleSheet, Text, View } from "react-native";
+import { dialogApi } from "../services";
import { colors, radii, spacing } from "../theme";
-export function QuickActions({ phone }: { phone?: string | undefined }) {
+function UnreadMessageBadge() {
+ const pulse = useRef(new Animated.Value(0)).current;
+
+ useEffect(() => {
+ const animation = Animated.loop(
+ Animated.timing(pulse, {
+ toValue: 1,
+ duration: 1100,
+ useNativeDriver: true,
+ }),
+ );
+ animation.start();
+ return () => animation.stop();
+ }, [pulse]);
+
+ return (
+
+
+
+ !
+
+
+ );
+}
+
+export function QuickActions({ phone, authenticated = false }: { phone?: string | undefined; authenticated?: boolean }) {
+ const router = useRouter();
+ const dialogs = useQuery({
+ queryKey: ["dialogs", "unread-indicator"],
+ queryFn: () => dialogApi.list(),
+ enabled: authenticated,
+ staleTime: 30_000,
+ refetchInterval: 30_000,
+ });
+ const hasUnreadMessages = (dialogs.data?.items ?? []).some((dialog) => (dialog.unread_count ?? 0) > 0);
+
const call = () => {
if (phone) void Linking.openURL(`tel:${phone}`);
};
return (
- [styles.button, pressed && styles.pressed, !phone && styles.disabled]}
- >
-
- Связь с оператором
-
+
+ router.push("/dialogs")}
+ style={({ pressed }) => [styles.button, styles.chatButton, pressed && styles.pressed]}
+ >
+
+
+ {hasUnreadMessages ? : null}
+
+ Чат
+
+
+ [styles.button, styles.operatorButton, pressed && styles.pressed, !phone && styles.disabled]}
+ >
+
+ Оператор
+
+
);
}
const styles = StyleSheet.create({
+ row: {
+ flexDirection: "row",
+ gap: spacing.sm,
+ marginHorizontal: spacing.lg,
+ marginBottom: spacing.lg,
+ },
button: {
+ flex: 1,
flexDirection: "row",
alignItems: "center",
justifyContent: "center",
gap: spacing.sm,
- marginHorizontal: spacing.lg,
- marginBottom: spacing.lg,
paddingVertical: 10,
borderRadius: radii.lg,
+ },
+ chatButton: {
+ backgroundColor: colors.primary,
+ },
+ operatorButton: {
backgroundColor: colors.secondary,
},
- text: { fontSize: 14, color: colors.secondaryForeground },
+ text: { fontSize: 14, fontWeight: "600", color: colors.secondaryForeground },
+ chatText: { color: colors.primaryForeground },
+ badgePosition: {
+ position: "absolute",
+ top: -8,
+ right: -9,
+ width: 14,
+ height: 14,
+ alignItems: "center",
+ justifyContent: "center",
+ },
+ pulse: {
+ position: "absolute",
+ width: 12,
+ height: 12,
+ borderRadius: radii.full,
+ backgroundColor: colors.destructive,
+ },
+ badge: {
+ width: 14,
+ height: 14,
+ borderRadius: radii.full,
+ alignItems: "center",
+ justifyContent: "center",
+ backgroundColor: colors.destructive,
+ },
+ badgeText: { color: colors.primaryForeground, fontSize: 10, lineHeight: 12, fontWeight: "800" },
pressed: { opacity: 0.8 },
disabled: { opacity: 0.5 },
});
diff --git a/codebase/backend/frontend-test-site/src/notification-presenter.ts b/codebase/backend/frontend-test-site/src/notification-presenter.ts
index 67c855f..0ab72c3 100644
--- a/codebase/backend/frontend-test-site/src/notification-presenter.ts
+++ b/codebase/backend/frontend-test-site/src/notification-presenter.ts
@@ -5,20 +5,54 @@ export type NotificationPalette = {
background: string;
foreground: string;
accent: string;
+ accentBackground: string;
+ border: string;
};
const neutral: NotificationPalette = {
background: "#f3f3f5",
foreground: "#252525",
accent: "#030213",
+ accentBackground: "#e4e4e8",
+ border: "#d7d7dc",
};
const palettes: Record = {
- critical: { background: "#feecef", foreground: "#7f1d1d", accent: "#d4183d" },
- warning: { background: "#fff7df", foreground: "#713f12", accent: "#ca8a04" },
- success: { background: "#eaf8ee", foreground: "#14532d", accent: "#16a34a" },
- info: { background: "#eaf2ff", foreground: "#1e3a8a", accent: "#2563eb" },
- promo: { background: "#f4edff", foreground: "#4c1d95", accent: "#7c3aed" },
+ critical: {
+ background: "#fdecef",
+ foreground: "#252525",
+ accent: "#d4183d",
+ accentBackground: "#f8dce2",
+ border: "#efbcc7",
+ },
+ warning: {
+ background: "#fff3e0",
+ foreground: "#252525",
+ accent: "#e65100",
+ accentBackground: "#ffe0b2",
+ border: "#ffcc80",
+ },
+ success: {
+ background: "#e8f5e9",
+ foreground: "#252525",
+ accent: "#2e7d32",
+ accentBackground: "#c8e6c9",
+ border: "#a5d6a7",
+ },
+ info: {
+ background: "#eaf2ff",
+ foreground: "#252525",
+ accent: "#2563eb",
+ accentBackground: "#d8e7ff",
+ border: "#b7d1fb",
+ },
+ promo: {
+ background: "#f4edff",
+ foreground: "#252525",
+ accent: "#7c3aed",
+ accentBackground: "#e7d8ff",
+ border: "#d4b9fb",
+ },
neutral,
};
diff --git a/codebase/backend/frontend-test-site/src/types.ts b/codebase/backend/frontend-test-site/src/types.ts
index ad4a02b..ec209cb 100644
--- a/codebase/backend/frontend-test-site/src/types.ts
+++ b/codebase/backend/frontend-test-site/src/types.ts
@@ -13,7 +13,12 @@ export type TokenSet = {
};
export type DialogStatus = "open" | "waiting_for_company" | "waiting_for_client" | "closed";
-export type Dialog = { dialog_id: string; status: DialogStatus; updated_at?: string };
+export type Dialog = {
+ dialog_id: string;
+ status: DialogStatus;
+ unread_count?: number;
+ updated_at?: string;
+};
export type Attachment = {
attachment_id: string;
file_name: string;
diff --git a/codebase/backend/frontend-test-site/tests/e2e/smoke.spec.ts b/codebase/backend/frontend-test-site/tests/e2e/smoke.spec.ts
index 5218d9b..1c33f25 100644
--- a/codebase/backend/frontend-test-site/tests/e2e/smoke.spec.ts
+++ b/codebase/backend/frontend-test-site/tests/e2e/smoke.spec.ts
@@ -55,17 +55,18 @@ test("гостевой экран загружает публичный конт
await expect(page.getByRole("button", { name: "Голосовое сообщение" })).toHaveCount(0);
await expect(page.getByRole("button", { name: "Прикрепить файл" })).toBeVisible();
await expect(page.getByText("Продление патента через 14 дней")).toHaveCount(0);
- await expect(page.getByRole("button", { name: "Связь с оператором" })).toBeEnabled();
+ await expect(page.getByRole("button", { name: "Чат" })).toBeEnabled();
+ await expect(page.getByRole("button", { name: "Оператор" })).toBeEnabled();
await expect(page.getByText("+74950000000")).toHaveCount(0);
- await expect(page.getByText(/Гость/)).toBeVisible();
+ await expect(page.getByText(/Гость/)).toHaveCount(0);
});
-test("История открывает текущий единый чат", async ({ page }) => {
+test("Колокольчик открывает центр уведомлений", async ({ page }) => {
await page.goto("/");
- await page.getByRole("link", { name: "История" }).click();
- await expect(page).toHaveURL(/\/dialogs$/);
- await expect(page.getByRole("heading", { name: "Чат" })).toBeVisible();
- await expect(page.getByText(/доступен после авторизации/)).toBeVisible();
+ await page.getByRole("link", { name: "Уведомления" }).click();
+ await expect(page).toHaveURL(/\/notifications$/);
+ await expect(page.getByRole("heading", { name: "Центр уведомлений" })).toBeVisible();
+ await expect(page.getByText(/доступны после входа/)).toBeVisible();
});
test("первое сообщение требует обязательные согласия", async ({ page }) => {
diff --git a/figma/Main page specification/ATTRIBUTIONS.md b/figma/ATTRIBUTIONS.md
similarity index 100%
rename from figma/Main page specification/ATTRIBUTIONS.md
rename to figma/ATTRIBUTIONS.md
diff --git a/figma/Main page specification.zip b/figma/Main page specification.zip
index 417bcbf..cfcabbb 100644
Binary files a/figma/Main page specification.zip and b/figma/Main page specification.zip differ
diff --git a/figma/Main page specification/README.md b/figma/README.md
similarity index 100%
rename from figma/Main page specification/README.md
rename to figma/README.md
diff --git a/figma/Main page specification/default_shadcn_theme.css b/figma/default_shadcn_theme.css
similarity index 100%
rename from figma/Main page specification/default_shadcn_theme.css
rename to figma/default_shadcn_theme.css
diff --git a/figma/Main page specification/guidelines/Guidelines.md b/figma/guidelines/Guidelines.md
similarity index 100%
rename from figma/Main page specification/guidelines/Guidelines.md
rename to figma/guidelines/Guidelines.md
diff --git a/figma/Main page specification/index.html b/figma/index.html
similarity index 100%
rename from figma/Main page specification/index.html
rename to figma/index.html
diff --git a/figma/Main page specification/package.json b/figma/package.json
similarity index 100%
rename from figma/Main page specification/package.json
rename to figma/package.json
diff --git a/figma/Main page specification/pnpm-workspace.yaml b/figma/pnpm-workspace.yaml
similarity index 100%
rename from figma/Main page specification/pnpm-workspace.yaml
rename to figma/pnpm-workspace.yaml
diff --git a/figma/Main page specification/postcss.config.mjs b/figma/postcss.config.mjs
similarity index 100%
rename from figma/Main page specification/postcss.config.mjs
rename to figma/postcss.config.mjs
diff --git a/figma/Main page specification/src/app/App.tsx b/figma/src/app/App.tsx
similarity index 100%
rename from figma/Main page specification/src/app/App.tsx
rename to figma/src/app/App.tsx
diff --git a/figma/Main page specification/src/app/components/ChatInput.tsx b/figma/src/app/components/ChatInput.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ChatInput.tsx
rename to figma/src/app/components/ChatInput.tsx
diff --git a/figma/Main page specification/src/app/components/HanLogo.tsx b/figma/src/app/components/HanLogo.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/HanLogo.tsx
rename to figma/src/app/components/HanLogo.tsx
diff --git a/figma/Main page specification/src/app/components/Header.tsx b/figma/src/app/components/Header.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/Header.tsx
rename to figma/src/app/components/Header.tsx
diff --git a/figma/Main page specification/src/app/components/Notifications.tsx b/figma/src/app/components/Notifications.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/Notifications.tsx
rename to figma/src/app/components/Notifications.tsx
diff --git a/figma/Main page specification/src/app/components/PopularQuestions.tsx b/figma/src/app/components/PopularQuestions.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/PopularQuestions.tsx
rename to figma/src/app/components/PopularQuestions.tsx
diff --git a/figma/Main page specification/src/app/components/QuickActions.tsx b/figma/src/app/components/QuickActions.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/QuickActions.tsx
rename to figma/src/app/components/QuickActions.tsx
diff --git a/figma/Main page specification/src/app/components/figma/ImageWithFallback.tsx b/figma/src/app/components/figma/ImageWithFallback.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/figma/ImageWithFallback.tsx
rename to figma/src/app/components/figma/ImageWithFallback.tsx
diff --git a/figma/Main page specification/src/app/components/ui/accordion.tsx b/figma/src/app/components/ui/accordion.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/accordion.tsx
rename to figma/src/app/components/ui/accordion.tsx
diff --git a/figma/Main page specification/src/app/components/ui/alert-dialog.tsx b/figma/src/app/components/ui/alert-dialog.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/alert-dialog.tsx
rename to figma/src/app/components/ui/alert-dialog.tsx
diff --git a/figma/Main page specification/src/app/components/ui/alert.tsx b/figma/src/app/components/ui/alert.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/alert.tsx
rename to figma/src/app/components/ui/alert.tsx
diff --git a/figma/Main page specification/src/app/components/ui/aspect-ratio.tsx b/figma/src/app/components/ui/aspect-ratio.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/aspect-ratio.tsx
rename to figma/src/app/components/ui/aspect-ratio.tsx
diff --git a/figma/Main page specification/src/app/components/ui/avatar.tsx b/figma/src/app/components/ui/avatar.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/avatar.tsx
rename to figma/src/app/components/ui/avatar.tsx
diff --git a/figma/Main page specification/src/app/components/ui/badge.tsx b/figma/src/app/components/ui/badge.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/badge.tsx
rename to figma/src/app/components/ui/badge.tsx
diff --git a/figma/Main page specification/src/app/components/ui/breadcrumb.tsx b/figma/src/app/components/ui/breadcrumb.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/breadcrumb.tsx
rename to figma/src/app/components/ui/breadcrumb.tsx
diff --git a/figma/Main page specification/src/app/components/ui/button.tsx b/figma/src/app/components/ui/button.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/button.tsx
rename to figma/src/app/components/ui/button.tsx
diff --git a/figma/Main page specification/src/app/components/ui/calendar.tsx b/figma/src/app/components/ui/calendar.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/calendar.tsx
rename to figma/src/app/components/ui/calendar.tsx
diff --git a/figma/Main page specification/src/app/components/ui/card.tsx b/figma/src/app/components/ui/card.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/card.tsx
rename to figma/src/app/components/ui/card.tsx
diff --git a/figma/Main page specification/src/app/components/ui/carousel.tsx b/figma/src/app/components/ui/carousel.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/carousel.tsx
rename to figma/src/app/components/ui/carousel.tsx
diff --git a/figma/Main page specification/src/app/components/ui/chart.tsx b/figma/src/app/components/ui/chart.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/chart.tsx
rename to figma/src/app/components/ui/chart.tsx
diff --git a/figma/Main page specification/src/app/components/ui/checkbox.tsx b/figma/src/app/components/ui/checkbox.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/checkbox.tsx
rename to figma/src/app/components/ui/checkbox.tsx
diff --git a/figma/Main page specification/src/app/components/ui/collapsible.tsx b/figma/src/app/components/ui/collapsible.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/collapsible.tsx
rename to figma/src/app/components/ui/collapsible.tsx
diff --git a/figma/Main page specification/src/app/components/ui/command.tsx b/figma/src/app/components/ui/command.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/command.tsx
rename to figma/src/app/components/ui/command.tsx
diff --git a/figma/Main page specification/src/app/components/ui/context-menu.tsx b/figma/src/app/components/ui/context-menu.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/context-menu.tsx
rename to figma/src/app/components/ui/context-menu.tsx
diff --git a/figma/Main page specification/src/app/components/ui/dialog.tsx b/figma/src/app/components/ui/dialog.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/dialog.tsx
rename to figma/src/app/components/ui/dialog.tsx
diff --git a/figma/Main page specification/src/app/components/ui/drawer.tsx b/figma/src/app/components/ui/drawer.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/drawer.tsx
rename to figma/src/app/components/ui/drawer.tsx
diff --git a/figma/Main page specification/src/app/components/ui/dropdown-menu.tsx b/figma/src/app/components/ui/dropdown-menu.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/dropdown-menu.tsx
rename to figma/src/app/components/ui/dropdown-menu.tsx
diff --git a/figma/Main page specification/src/app/components/ui/form.tsx b/figma/src/app/components/ui/form.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/form.tsx
rename to figma/src/app/components/ui/form.tsx
diff --git a/figma/Main page specification/src/app/components/ui/hover-card.tsx b/figma/src/app/components/ui/hover-card.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/hover-card.tsx
rename to figma/src/app/components/ui/hover-card.tsx
diff --git a/figma/Main page specification/src/app/components/ui/input-otp.tsx b/figma/src/app/components/ui/input-otp.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/input-otp.tsx
rename to figma/src/app/components/ui/input-otp.tsx
diff --git a/figma/Main page specification/src/app/components/ui/input.tsx b/figma/src/app/components/ui/input.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/input.tsx
rename to figma/src/app/components/ui/input.tsx
diff --git a/figma/Main page specification/src/app/components/ui/label.tsx b/figma/src/app/components/ui/label.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/label.tsx
rename to figma/src/app/components/ui/label.tsx
diff --git a/figma/Main page specification/src/app/components/ui/menubar.tsx b/figma/src/app/components/ui/menubar.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/menubar.tsx
rename to figma/src/app/components/ui/menubar.tsx
diff --git a/figma/Main page specification/src/app/components/ui/navigation-menu.tsx b/figma/src/app/components/ui/navigation-menu.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/navigation-menu.tsx
rename to figma/src/app/components/ui/navigation-menu.tsx
diff --git a/figma/Main page specification/src/app/components/ui/pagination.tsx b/figma/src/app/components/ui/pagination.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/pagination.tsx
rename to figma/src/app/components/ui/pagination.tsx
diff --git a/figma/Main page specification/src/app/components/ui/popover.tsx b/figma/src/app/components/ui/popover.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/popover.tsx
rename to figma/src/app/components/ui/popover.tsx
diff --git a/figma/Main page specification/src/app/components/ui/progress.tsx b/figma/src/app/components/ui/progress.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/progress.tsx
rename to figma/src/app/components/ui/progress.tsx
diff --git a/figma/Main page specification/src/app/components/ui/radio-group.tsx b/figma/src/app/components/ui/radio-group.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/radio-group.tsx
rename to figma/src/app/components/ui/radio-group.tsx
diff --git a/figma/Main page specification/src/app/components/ui/resizable.tsx b/figma/src/app/components/ui/resizable.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/resizable.tsx
rename to figma/src/app/components/ui/resizable.tsx
diff --git a/figma/Main page specification/src/app/components/ui/scroll-area.tsx b/figma/src/app/components/ui/scroll-area.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/scroll-area.tsx
rename to figma/src/app/components/ui/scroll-area.tsx
diff --git a/figma/Main page specification/src/app/components/ui/select.tsx b/figma/src/app/components/ui/select.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/select.tsx
rename to figma/src/app/components/ui/select.tsx
diff --git a/figma/Main page specification/src/app/components/ui/separator.tsx b/figma/src/app/components/ui/separator.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/separator.tsx
rename to figma/src/app/components/ui/separator.tsx
diff --git a/figma/Main page specification/src/app/components/ui/sheet.tsx b/figma/src/app/components/ui/sheet.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/sheet.tsx
rename to figma/src/app/components/ui/sheet.tsx
diff --git a/figma/Main page specification/src/app/components/ui/sidebar.tsx b/figma/src/app/components/ui/sidebar.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/sidebar.tsx
rename to figma/src/app/components/ui/sidebar.tsx
diff --git a/figma/Main page specification/src/app/components/ui/skeleton.tsx b/figma/src/app/components/ui/skeleton.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/skeleton.tsx
rename to figma/src/app/components/ui/skeleton.tsx
diff --git a/figma/Main page specification/src/app/components/ui/slider.tsx b/figma/src/app/components/ui/slider.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/slider.tsx
rename to figma/src/app/components/ui/slider.tsx
diff --git a/figma/Main page specification/src/app/components/ui/sonner.tsx b/figma/src/app/components/ui/sonner.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/sonner.tsx
rename to figma/src/app/components/ui/sonner.tsx
diff --git a/figma/Main page specification/src/app/components/ui/switch.tsx b/figma/src/app/components/ui/switch.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/switch.tsx
rename to figma/src/app/components/ui/switch.tsx
diff --git a/figma/Main page specification/src/app/components/ui/table.tsx b/figma/src/app/components/ui/table.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/table.tsx
rename to figma/src/app/components/ui/table.tsx
diff --git a/figma/Main page specification/src/app/components/ui/tabs.tsx b/figma/src/app/components/ui/tabs.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/tabs.tsx
rename to figma/src/app/components/ui/tabs.tsx
diff --git a/figma/Main page specification/src/app/components/ui/textarea.tsx b/figma/src/app/components/ui/textarea.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/textarea.tsx
rename to figma/src/app/components/ui/textarea.tsx
diff --git a/figma/Main page specification/src/app/components/ui/toggle-group.tsx b/figma/src/app/components/ui/toggle-group.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/toggle-group.tsx
rename to figma/src/app/components/ui/toggle-group.tsx
diff --git a/figma/Main page specification/src/app/components/ui/toggle.tsx b/figma/src/app/components/ui/toggle.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/toggle.tsx
rename to figma/src/app/components/ui/toggle.tsx
diff --git a/figma/Main page specification/src/app/components/ui/tooltip.tsx b/figma/src/app/components/ui/tooltip.tsx
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/tooltip.tsx
rename to figma/src/app/components/ui/tooltip.tsx
diff --git a/figma/Main page specification/src/app/components/ui/use-mobile.ts b/figma/src/app/components/ui/use-mobile.ts
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/use-mobile.ts
rename to figma/src/app/components/ui/use-mobile.ts
diff --git a/figma/Main page specification/src/app/components/ui/utils.ts b/figma/src/app/components/ui/utils.ts
similarity index 100%
rename from figma/Main page specification/src/app/components/ui/utils.ts
rename to figma/src/app/components/ui/utils.ts
diff --git a/figma/Main page specification/src/app/data/companyMessages.ts b/figma/src/app/data/companyMessages.ts
similarity index 100%
rename from figma/Main page specification/src/app/data/companyMessages.ts
rename to figma/src/app/data/companyMessages.ts
diff --git a/figma/Main page specification/src/app/data/session.ts b/figma/src/app/data/session.ts
similarity index 100%
rename from figma/Main page specification/src/app/data/session.ts
rename to figma/src/app/data/session.ts
diff --git a/figma/Main page specification/src/app/pages/AuthConsent.tsx b/figma/src/app/pages/AuthConsent.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/AuthConsent.tsx
rename to figma/src/app/pages/AuthConsent.tsx
diff --git a/figma/Main page specification/src/app/pages/AuthLoading.tsx b/figma/src/app/pages/AuthLoading.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/AuthLoading.tsx
rename to figma/src/app/pages/AuthLoading.tsx
diff --git a/figma/Main page specification/src/app/pages/AuthOtp.tsx b/figma/src/app/pages/AuthOtp.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/AuthOtp.tsx
rename to figma/src/app/pages/AuthOtp.tsx
diff --git a/figma/Main page specification/src/app/pages/AuthPhone.tsx b/figma/src/app/pages/AuthPhone.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/AuthPhone.tsx
rename to figma/src/app/pages/AuthPhone.tsx
diff --git a/figma/Main page specification/src/app/pages/Calendar.tsx b/figma/src/app/pages/Calendar.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/Calendar.tsx
rename to figma/src/app/pages/Calendar.tsx
diff --git a/figma/Main page specification/src/app/pages/Chat.tsx b/figma/src/app/pages/Chat.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/Chat.tsx
rename to figma/src/app/pages/Chat.tsx
diff --git a/figma/Main page specification/src/app/pages/History.tsx b/figma/src/app/pages/History.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/History.tsx
rename to figma/src/app/pages/History.tsx
diff --git a/figma/Main page specification/src/app/pages/Home.tsx b/figma/src/app/pages/Home.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/Home.tsx
rename to figma/src/app/pages/Home.tsx
diff --git a/figma/Main page specification/src/app/pages/NotificationDetail.tsx b/figma/src/app/pages/NotificationDetail.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/NotificationDetail.tsx
rename to figma/src/app/pages/NotificationDetail.tsx
diff --git a/figma/Main page specification/src/app/pages/Profile.tsx b/figma/src/app/pages/Profile.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/Profile.tsx
rename to figma/src/app/pages/Profile.tsx
diff --git a/figma/Main page specification/src/app/pages/Root.tsx b/figma/src/app/pages/Root.tsx
similarity index 100%
rename from figma/Main page specification/src/app/pages/Root.tsx
rename to figma/src/app/pages/Root.tsx
diff --git a/figma/Main page specification/src/app/routes.tsx b/figma/src/app/routes.tsx
similarity index 100%
rename from figma/Main page specification/src/app/routes.tsx
rename to figma/src/app/routes.tsx
diff --git a/figma/Main page specification/src/main.tsx b/figma/src/main.tsx
similarity index 100%
rename from figma/Main page specification/src/main.tsx
rename to figma/src/main.tsx
diff --git a/figma/Main page specification/src/styles/fonts.css b/figma/src/styles/fonts.css
similarity index 100%
rename from figma/Main page specification/src/styles/fonts.css
rename to figma/src/styles/fonts.css
diff --git a/figma/Main page specification/src/styles/globals.css b/figma/src/styles/globals.css
similarity index 100%
rename from figma/Main page specification/src/styles/globals.css
rename to figma/src/styles/globals.css
diff --git a/figma/Main page specification/src/styles/index.css b/figma/src/styles/index.css
similarity index 100%
rename from figma/Main page specification/src/styles/index.css
rename to figma/src/styles/index.css
diff --git a/figma/Main page specification/src/styles/tailwind.css b/figma/src/styles/tailwind.css
similarity index 100%
rename from figma/Main page specification/src/styles/tailwind.css
rename to figma/src/styles/tailwind.css
diff --git a/figma/Main page specification/src/styles/theme.css b/figma/src/styles/theme.css
similarity index 100%
rename from figma/Main page specification/src/styles/theme.css
rename to figma/src/styles/theme.css
diff --git a/figma/Main page specification/vite.config.ts b/figma/vite.config.ts
similarity index 100%
rename from figma/Main page specification/vite.config.ts
rename to figma/vite.config.ts