Browse Source

feat: home page

Carson 10 tháng trước cách đây
mục cha
commit
1282e0bc07

+ 1 - 0
.vitepress/config.mts

@@ -25,6 +25,7 @@ export default defineConfig({
   //     provider: "local",
   //   },
   // },
+  appearance: false,
 
   vite: {
     publicDir: "../public",

+ 5 - 0
README.md

@@ -30,3 +30,8 @@ element-ui plus
 - 导出 figma svg,放在 assets/icons 目录下,是plain还是colored看情况而定
   - plain: 单色图标,可以通过css color属性设置颜色
   - colored: 双色图标,固定颜色,一般是多种颜色的图标
+- 导入组件使用
+  ```
+  import IconNotebook from "~icons/ccrbi-plain/notebook";
+  <IconNotebook color="blue" />
+  ```

+ 89 - 0
components/HomeCard/HomeCard.vue

@@ -0,0 +1,89 @@
+<script setup lang="ts">
+import { toRefs, computed } from "vue";
+import _ from "lodash";
+
+const props = withDefaults(
+  defineProps<{
+    title?: string;
+    color?: "info" | "skyblue" | "white";
+    span?: number;
+  }>(),
+  {
+    color: "info",
+    span: 24,
+  }
+);
+const { title, color } = toRefs(props);
+const styles = computed(() => {
+  return _.get(
+    {
+      info: {
+        backgroundColor: "#f5f9ff",
+        borderColor: "#e2eeff",
+      },
+      skyblue: {
+        backgroundColor: "#f6fdff",
+        borderColor: "#e3f8f4",
+      },
+      white: {
+        borderColor: "#e2eeff",
+        backgroundColor: "#fff",
+      },
+    },
+    color.value
+  );
+});
+</script>
+<template>
+  <el-col tag="div" :span="span">
+    <div class="card" :style="styles">
+      <slot name="title">
+        <h2 v-if="title">
+          {{ title }}
+        </h2>
+      </slot>
+      <el-row :gutter="20" tag="section">
+        <slot></slot>
+      </el-row>
+    </div>
+  </el-col>
+</template>
+
+<style lang="scss" scoped>
+h2 {
+  border: none;
+  margin: 0;
+  padding: 0;
+}
+.card {
+  display: flex;
+  flex-direction: column;
+  align-items: stretch;
+  gap: 24px;
+  border-radius: 20px;
+  padding: 32px;
+  background: #f5f9ff;
+  border: 1px solid #e2eeff;
+  min-height: 240px;
+  :deep(.card) {
+    min-height: 162px;
+  }
+  h2 {
+    display: flex;
+    align-items: center;
+    .prefix {
+      margin-right: 8px;
+    }
+    .suffix {
+      width: 24px;
+      height: 24px;
+      margin-left: 8px;
+      color: #00000042;
+    }
+  }
+  .el-row {
+    row-gap: 20px;
+    align-items: stretch;
+  }
+}
+</style>

+ 5 - 0
components/HomeCard/HomeCardContent.vue

@@ -0,0 +1,5 @@
+<template>
+  <el-col>
+    <slot></slot>
+  </el-col>
+</template>

+ 30 - 0
components/HomeCard/HomeCardTitle.vue

@@ -0,0 +1,30 @@
+<script setup lang="ts">
+import { ArrowRightBold } from "@element-plus/icons-vue";
+const props = withDefaults(
+  defineProps<{
+    showArrow: boolean;
+  }>(),
+  { showArrow: false }
+);
+</script>
+<template>
+  <h2>
+    <slot></slot>
+    <el-icon v-if="props.showArrow" class="suffix"><ArrowRightBold /></el-icon>
+  </h2>
+</template>
+<style lang="scss" scoped>
+h2 {
+  border: none;
+  margin: 0;
+  padding: 0;
+  display: flex;
+  align-items: center;
+  gap: 8px;
+  .suffix {
+    width: 24px;
+    height: 24px;
+    color: #00000042;
+  }
+}
+</style>

+ 9 - 0
components/HomeCard/index.ts

@@ -0,0 +1,9 @@
+import HomeCard from "./HomeCard.vue";
+import HomeCardContent from "./HomeCardContent.vue";
+import HomeCardTitle from "./HomeCardTitle.vue";
+
+HomeCard.Title = HomeCardTitle;
+HomeCard.Content = HomeCardContent;
+
+export default HomeCard;
+export { HomeCardTitle, HomeCardContent };

+ 125 - 61
components/HomeContent.vue

@@ -1,78 +1,142 @@
 <script setup lang="ts">
 import { ref } from "vue";
 import Search from "./Search/index.vue";
-import { ArrowRightBold } from "@element-plus/icons-vue";
-const count = ref(0);
+import HomeCard from "./HomeCard";
+import HomeSection from "./HomeSection.vue";
+import IconNotebook from "~icons/ccrbi-plain/notebook";
+import IconBook from "~icons/ccrbi-plain/book";
+import IconDirectory from "~icons/ccrbi-plain/directory";
+import IconXieTongJianGou from "~icons/ccrbi-colored/xie-tong-jian-gou";
+import IconAiZhuShou from "~icons/ccrbi-colored/ai-zhu-shou";
+import IconAiChuangJian from "~icons/ccrbi-colored/ai-chuang-jian";
 </script>
+
 <template>
   <div class="home-content">
-    <h1>您好,需要提供什么帮助?</h1>
-    <Search />
-    <h1>新手入门</h1>
-    <section>
-      <div class="card type1">
-        <h2>
-          平台概览<el-icon><ArrowRightBold /></el-icon>
-        </h2>
-        <span class="content">TODO</span>
-      </div>
+    <HomeSection title="您好,需要提供什么帮助?">
+      <Search />
+    </HomeSection>
+
+    <HomeSection title="新手入门">
+      <HomeCard color="skyblue" :span="12">
+        <template #title>
+          <HomeCard.Title showArrow> 平台概览 </HomeCard.Title>
+        </template>
+        <HomeCard.Content>
+          <span class="content">TODO</span>
+        </HomeCard.Content>
+      </HomeCard>
+      <HomeCard showArrow :span="12">
+        <template #title>
+          <HomeCard.Title showArrow> 用户登录 </HomeCard.Title>
+        </template>
+        <HomeCard.Content>
+          <span class="content">TODO</span>
+        </HomeCard.Content>
+      </HomeCard>
+    </HomeSection>
 
-      <div class="card">
-        <h2>
-          平台概览<el-icon><ArrowRightBold /></el-icon>
-        </h2>
-        <span class="content">TODO</span>
-      </div>
-    </section>
+    <HomeSection title="平台使用">
+      <HomeCard title="基础使用" :span="24">
+        <HomeCard :span="8" color="white">
+          <template #title>
+            <HomeCard.Title>
+              <IconNotebook color="#3681FC" />
+              创建课程
+            </HomeCard.Title>
+          </template>
+          <HomeCard.Content>
+            <span class="content">TODO</span>
+          </HomeCard.Content>
+        </HomeCard>
+        <HomeCard :span="8" color="white">
+          <template #title>
+            <HomeCard.Title>
+              <IconBook color="#FF822B" />
+              实施课程
+            </HomeCard.Title>
+          </template>
+          <HomeCard.Content>
+            <span class="content">TODO</span>
+          </HomeCard.Content>
+        </HomeCard>
+        <HomeCard :span="8" color="white">
+          <template #title>
+            <HomeCard.Title>
+              <IconDirectory color="#34CEAE" />
+              创建项目
+            </HomeCard.Title>
+          </template>
+          <HomeCard.Content>
+            <span class="content">TODO</span>
+          </HomeCard.Content>
+        </HomeCard>
+      </HomeCard>
+      <HomeCard title="进阶使用" :span="24">
+        <HomeCard :span="8" color="white">
+          <template #title>
+            <HomeCard.Title>
+              <IconXieTongJianGou />
+              协同建构
+            </HomeCard.Title>
+          </template>
+          <HomeCard.Content>
+            <span class="content">TODO</span>
+          </HomeCard.Content>
+        </HomeCard>
+        <HomeCard :span="8" color="white">
+          <template #title>
+            <HomeCard.Title>
+              <IconAiZhuShou />
+              AI助手
+            </HomeCard.Title>
+          </template>
+          <HomeCard.Content>
+            <span class="content">TODO</span>
+          </HomeCard.Content>
+        </HomeCard>
+        <HomeCard :span="8" color="white">
+          <template #title>
+            <HomeCard.Title>
+              <IconAiChuangJian />
+              AI创建
+            </HomeCard.Title>
+          </template>
+          <HomeCard.Content>
+            <span class="content">TODO</span>
+          </HomeCard.Content>
+        </HomeCard>
+      </HomeCard>
+    </HomeSection>
+
+    <HomeSection title="更多资源">
+      <HomeCard title="课程案例" :span="12">
+        <!-- TODO -->
+      </HomeCard>
+      <HomeCard title="项目案例" :span="12">
+        <!-- TODO -->
+      </HomeCard>
+      <HomeCard>
+        <HomeCard title="常见问题" :span="8" color="white">
+          <!-- TODO -->
+        </HomeCard>
+        <HomeCard title="更新日志" :span="8" color="white">
+          <!-- TODO -->
+        </HomeCard>
+        <HomeCard title="如何与AI对话" :span="8" color="white">
+          <!-- TODO -->
+        </HomeCard>
+      </HomeCard>
+    </HomeSection>
   </div>
 </template>
 
 <style lang="scss" scoped>
-h2 {
-  border: none;
-  margin: 0;
-  padding: 0;
-}
 .home-content {
   display: flex;
   flex-direction: column;
   align-items: center;
-  section {
-    display: flex;
-    align-items: stretch;
-    justify-content: center;
-    width: 100%;
-    gap: 20px;
-  }
-  .card {
-    flex: 1;
-    display: flex;
-    flex-direction: column;
-    align-items: stretch;
-    gap: 8px;
-    border-radius: 20px;
-    padding: 32px;
-    background: #f5f9ff;
-    border: 1px solid #e2eeff;
-    min-height: 240px;
-    &.type1 {
-      background-color: #f6fdff;
-      border: 1px solid #e3f8f4;
-    }
-    h2 {
-      display: flex;
-      align-items: center;
-      .el-icon {
-        width: 24px;
-        height: 24px;
-        margin-left: 8px;
-        color: #00000042;
-      }
-    }
-    .content {
-      font-size: 14px;
-      font-weight: 400;
-    }
-  }
+  gap: 80px;
+  padding-top: 80px;
 }
 </style>

+ 36 - 0
components/HomeSection.vue

@@ -0,0 +1,36 @@
+<script setup lang="ts">
+import { toRefs, computed, useSlots, h } from "vue";
+const props = defineProps<{
+  title?: string;
+}>();
+const { title } = toRefs(props);
+
+const slots = useSlots();
+const titleNode = computed(() => {
+  return slots.title ? slots.title() : title.value ? h("h1", {}, title.value) : null;
+});
+</script>
+<template>
+  <div class="home-section">
+    <component :is="titleNode" class="title" />
+    <el-row class="content" justify="center" :gutter="20" tag="section" v-bind="$attrs">
+      <slot></slot>
+    </el-row>
+  </div>
+</template>
+<style lang="scss" scoped>
+.home-section {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  width: 100%;
+  gap: 20px;
+}
+.content {
+  width: 100%;
+}
+.el-row {
+  row-gap: 20px;
+  align-items: stretch;
+}
+</style>