From 2b17a5de0f733a695782e2541f926bd1b7bd5750 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= <midnite@outlook.com>
Date: Fri, 24 Jan 2025 10:48:36 +0800
Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E5=AF=B9=E4=BA=8EScheme?=
 =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E7=9A=84=E5=B1=95=E7=A4=BA=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/components/SchemeSign.module.css       | 21 ++++++++++++++
 src/components/SchemeSign.tsx              | 33 ++++++++++++++++++++++
 src/models.ts                              | 23 ++++++++++++---
 src/page-components/schemes/SchemeList.tsx |  2 ++
 src/pages/SchemeDetail.module.css          |  7 +++++
 src/pages/SchemeDetail.tsx                 | 17 ++++-------
 src/stores/schemes.ts                      |  2 +-
 7 files changed, 88 insertions(+), 17 deletions(-)
 create mode 100644 src/components/SchemeSign.module.css
 create mode 100644 src/components/SchemeSign.tsx

diff --git a/src/components/SchemeSign.module.css b/src/components/SchemeSign.module.css
new file mode 100644
index 0000000..09b8591
--- /dev/null
+++ b/src/components/SchemeSign.module.css
@@ -0,0 +1,21 @@
+@layer components {
+  .badge {
+    font-size: var(--font-size-xs);
+    color: var(--color-yuebai);
+    background-color: var(--color-mose);
+    &.q {
+      background-color: var(--color-mantianxingzi);
+    }
+    &.swatch {
+      background-color: var(--color-pinlan);
+    }
+    &.m2 {
+      background-color: #03dac6;
+      color: var(--color-qihei);
+    }
+    &.m3 {
+      background-color: #a78fff;
+      color: var(--color-qihei);
+    }
+  }
+}
diff --git a/src/components/SchemeSign.tsx b/src/components/SchemeSign.tsx
new file mode 100644
index 0000000..4785f7d
--- /dev/null
+++ b/src/components/SchemeSign.tsx
@@ -0,0 +1,33 @@
+import cx from 'clsx';
+import { isNil } from 'lodash-es';
+import { useMemo } from 'react';
+import { schemeType, SchemeType } from '../models';
+import { Badge } from './Badge';
+import styles from './SchemeSign.module.css';
+
+type SchemeSignProps = {
+  scheme?: SchemeType;
+  short?: boolean;
+};
+
+export function SchemeSign({ scheme, short = false }: SchemeSignProps) {
+  const schemeName = schemeType(scheme, short);
+  const signColorStyles = useMemo(() => {
+    switch (scheme) {
+      case 'q_scheme':
+        return styles.q;
+      case 'swatch_scheme':
+        return styles.swatch;
+      case 'material_2':
+        return styles.m2;
+      case 'material_3':
+        return styles.m3;
+    }
+  }, [scheme]);
+
+  return (
+    !isNil(scheme) && (
+      <Badge extendClassName={cx(styles.badge, signColorStyles)}>{schemeName}</Badge>
+    )
+  );
+}
diff --git a/src/models.ts b/src/models.ts
index 658773d..d025636 100644
--- a/src/models.ts
+++ b/src/models.ts
@@ -1,3 +1,4 @@
+import { find, isNil } from 'lodash-es';
 import { MaterialDesign2SchemeStorage } from './material-2-scheme';
 import { MaterialDesign3SchemeStorage } from './material-3-scheme';
 import { QSchemeStorage } from './q-scheme';
@@ -29,14 +30,28 @@ export type ColorDescription = {
 export type SchemeType = 'q_scheme' | 'swatch_scheme' | 'material_2' | 'material_3';
 export type SchemeTypeOption = {
   label: string;
+  short: string;
   value: SchemeType;
 };
 export const SchemeTypeOptions: SchemeTypeOption[] = [
-  { label: 'Q Scheme', value: 'q_scheme' },
-  { label: 'Swatch Scheme', value: 'swatch_scheme' },
-  { label: 'Material Design 2 Scheme', value: 'material_2' },
-  { label: 'Material Design 3 Scheme', value: 'material_3' },
+  { label: 'Q Scheme', short: 'Q', value: 'q_scheme' },
+  { label: 'Swatch Scheme', short: 'Swatch', value: 'swatch_scheme' },
+  { label: 'Material Design 2 Scheme', short: 'M2', value: 'material_2' },
+  { label: 'Material Design 3 Scheme', short: 'M3', value: 'material_3' },
 ];
+
+export function schemeType(
+  value?: SchemeTypeOption['value'] | null,
+  short?: boolean,
+): string | null {
+  const useShort = short ?? false;
+  const foundType = find(SchemeTypeOptions, { value }) as SchemeTypeOption | undefined;
+  if (isNil(foundType)) {
+    return null;
+  }
+  return useShort ? foundType.short : foundType.label;
+}
+
 export type SchemeContent<SchemeStorage> = {
   id: string;
   name: string;
diff --git a/src/page-components/schemes/SchemeList.tsx b/src/page-components/schemes/SchemeList.tsx
index a035a72..0f211ab 100644
--- a/src/page-components/schemes/SchemeList.tsx
+++ b/src/page-components/schemes/SchemeList.tsx
@@ -5,6 +5,7 @@ import { useAtomValue } from 'jotai';
 import { isEmpty, isEqual } from 'lodash-es';
 import { useMemo } from 'react';
 import { Link, useNavigate, useParams } from 'react-router-dom';
+import { SchemeSign } from '../../components/SchemeSign';
 import { activeSchemeAtom, useSchemeList } from '../../stores/schemes';
 import styles from './SchemeList.module.css';
 
@@ -35,6 +36,7 @@ function SchemeItem({ item }: SchemeItemProps) {
       onClick={() => navigate(item.id)}>
       <div className={styles.name}>{item.name}</div>
       <div className={styles.status}>
+        <SchemeSign scheme={item.type} short />
         <div className={styles.create_time}>
           created at {dayjs(item.createdAt).format('YYYY-MM-DD')}
         </div>
diff --git a/src/pages/SchemeDetail.module.css b/src/pages/SchemeDetail.module.css
index 7038170..78a2aa0 100644
--- a/src/pages/SchemeDetail.module.css
+++ b/src/pages/SchemeDetail.module.css
@@ -7,5 +7,12 @@
     align-items: stretch;
     gap: var(--spacing-m);
     overflow: hidden;
+    .badge_layout {
+      padding: var(--spacing-xs) var(--spacing-m);
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+      gap: var(--spacing-m);
+    }
   }
 }
diff --git a/src/pages/SchemeDetail.tsx b/src/pages/SchemeDetail.tsx
index e5dfdeb..1969e64 100644
--- a/src/pages/SchemeDetail.tsx
+++ b/src/pages/SchemeDetail.tsx
@@ -1,10 +1,9 @@
 import { isNil, set } from 'lodash-es';
-import { useCallback, useEffect, useState } from 'react';
+import { useCallback, useEffect } from 'react';
 import { useNavigate, useParams } from 'react-router-dom';
 import { EditableDescription } from '../components/EditableDescription';
 import { EditableTitle } from '../components/EditableTitle';
-import { Tab } from '../components/Tab';
-import { SchemeView } from '../page-components/scheme/SchemeView';
+import { SchemeSign } from '../components/SchemeSign';
 import { useScheme, useUpdateScheme } from '../stores/schemes';
 import styles from './SchemeDetail.module.css';
 
@@ -13,7 +12,6 @@ export function SchemeDetail() {
   const scheme = useScheme(id);
   const navigate = useNavigate();
   const updateScheme = useUpdateScheme(id);
-  const [showScheme, setShowScheme] = useState<'light' | 'dark'>('light');
 
   const updateTitle = useCallback(
     (newTitle: string) => {
@@ -43,15 +41,10 @@ export function SchemeDetail() {
   return (
     <div className={styles.scheme_detail_layout}>
       <EditableTitle title={scheme?.name} onChange={updateTitle} />
+      <div className={styles.badge_layout}>
+        <SchemeSign scheme={scheme?.type} />
+      </div>
       <EditableDescription content={scheme?.description} onChange={updateDescription} />
-      <Tab
-        tabs={[
-          { title: 'Light Scheme', id: 'light' },
-          { title: 'Dark Scheme', id: 'dark' },
-        ]}
-        onActive={(tabId) => setShowScheme(tabId as 'light' | 'dark')}
-      />
-      <SchemeView scheme={scheme?.[`${showScheme}Scheme`]} />
     </div>
   );
 }
diff --git a/src/stores/schemes.ts b/src/stores/schemes.ts
index 198dd9b..f052eac 100644
--- a/src/stores/schemes.ts
+++ b/src/stores/schemes.ts
@@ -48,7 +48,7 @@ export function useSchemeList(): Pick<SchemeContent<SchemeStorage>, 'id' | 'name
     () =>
       schemes
         .sort((a, b) => dayjs(b.createdAt).diff(dayjs(a.createdAt)))
-        .map(({ id, name, createdAt }) => ({ id, name, createdAt })),
+        .map(({ id, name, createdAt, type }) => ({ id, name, createdAt, type })),
     [schemes],
   );