mirror of
https://github.com/hpware/news-analyze.git
synced 2025-06-23 13:04:23 +00:00
feat: enhance UI components and add accordion functionality
- Updated DraggableWindow.vue to improve shadow effects. - Refactored AboutWindow.vue for better structure and readability. - Added chatbot functionality in chatbot.vue with cookie management. - Improved navigation component for better code clarity. - Created a new chat history table in the database schema. - Modified error handling in error.vue to display error messages correctly. - Integrated ChatbotWindow into the desktop application layout. - Implemented accordion component in home.vue for Q/A section. - Enhanced API for chat functionality with improved error handling. - Removed unused routes for cleaner codebase. - Added custom animations for accordion components in tailwind.config.js. - Developed accordion UI components (Accordion, AccordionContent, AccordionItem, AccordionTrigger) for better user interaction.
This commit is contained in:
parent
f89e6aaa48
commit
5bf857f3cd
21 changed files with 402 additions and 182 deletions
|
@ -66,7 +66,7 @@ const stopDrag = () => {
|
|||
width: props.width || '400px',
|
||||
height: props.height || '300px',
|
||||
}"
|
||||
class="fixed bg-white dark:bg-gray-800 rounded-md shadow-lg overflow-hidden flex flex-col"
|
||||
class="fixed bg-white dark:bg-gray-800 rounded-md shadow-lg overflow-hidden flex flex-col shadow-lg shadow-xl/30"
|
||||
>
|
||||
<div
|
||||
@mousedown="startDrag"
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
<template>
|
||||
<div class="justify-center align-center text-center flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<span class=text-xl>為什麼要做網站?</span>
|
||||
<span>1. 台灣媒體真的很爛,要嘛有超多偏見,或是比較偏小孩不能看的新聞 (aka 擦邊通過的</span>
|
||||
<span>2. 這個網站是為了讓大家可以更方便的比較新聞,可以分析新聞的偏見</span>
|
||||
<span>3. <span class="line-through">學 TailwindCSS</span></span>
|
||||
</div>
|
||||
<hr/>
|
||||
<div class="flex flex-col">
|
||||
<span class=text-xl>關於開發者</span>
|
||||
<span class="text-center align-center justify-center">開發者:yh</span>
|
||||
<span class="text-center align-center justify-center">聯絡信箱:<a href="mailto:public+newscompareauthor@yuanhau.com">public@yuanhau.com</a></span>
|
||||
</div>
|
||||
<div class="justify-center align-center text-center flex flex-col">
|
||||
<div class="flex flex-col">
|
||||
<span class="text-xl">為什麼要做網站?</span>
|
||||
<span
|
||||
>1. 台灣媒體真的很爛,要嘛有超多偏見,或是比較偏小孩不能看的新聞 (aka
|
||||
擦邊通過的</span
|
||||
>
|
||||
<span
|
||||
>2. 這個網站是為了讓大家可以更方便的比較新聞,可以分析新聞的偏見</span
|
||||
>
|
||||
<span>3. <span class="line-through">學 TailwindCSS</span></span>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="flex flex-col">
|
||||
<span class="text-xl">關於開發者</span>
|
||||
<span class="text-center align-center justify-center">開發者:yh</span>
|
||||
<span class="text-center align-center justify-center"
|
||||
>聯絡信箱:<a href="mailto:public+newscompareauthor@yuanhau.com"
|
||||
>public@yuanhau.com</a
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
const { t } = useI18n();
|
||||
const cookie = useCookie("lastChatId");
|
||||
const lastChatId = cookie.value;
|
||||
onMounted(() => {
|
||||
console.log(lastChatId);
|
||||
if (lastChatId) {
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="justify-center align-center text-center flex flex-col">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<div class="justify-center align-center text-center flex flex-col">Hi</div>
|
||||
</template>
|
||||
|
|
|
@ -20,7 +20,9 @@ const toggleDropdown = () => {
|
|||
class="fixed top-0 inset-x-0 bg-[#81611a]/70 backdrop-blur-sm h-[55px] flex align-center items-center flex-row text-white pl-4 gap-x-5 justify-between z-50 rounded-3xl m-2"
|
||||
>
|
||||
<div class="text-3xl text-bold">
|
||||
<NuxtLink :to="localePath('home')" ref="title">{{ t("core.sitename") }}</NuxtLink>
|
||||
<NuxtLink :to="localePath('home')" ref="title">{{
|
||||
t("core.sitename")
|
||||
}}</NuxtLink>
|
||||
</div>
|
||||
<div
|
||||
class="text-[0.9em] left-1/2 absolute transform -translate-x-1/2 space-x-4 items-center"
|
||||
|
|
19
components/ui/accordion/Accordion.vue
Normal file
19
components/ui/accordion/Accordion.vue
Normal file
|
@ -0,0 +1,19 @@
|
|||
<script setup lang="ts">
|
||||
import {
|
||||
AccordionRoot,
|
||||
type AccordionRootEmits,
|
||||
type AccordionRootProps,
|
||||
useForwardPropsEmits,
|
||||
} from "reka-ui";
|
||||
|
||||
const props = defineProps<AccordionRootProps>();
|
||||
const emits = defineEmits<AccordionRootEmits>();
|
||||
|
||||
const forwarded = useForwardPropsEmits(props, emits);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AccordionRoot v-bind="forwarded">
|
||||
<slot />
|
||||
</AccordionRoot>
|
||||
</template>
|
26
components/ui/accordion/AccordionContent.vue
Normal file
26
components/ui/accordion/AccordionContent.vue
Normal file
|
@ -0,0 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { AccordionContent, type AccordionContentProps } from "reka-ui";
|
||||
import { computed, type HTMLAttributes } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
AccordionContentProps & { class?: HTMLAttributes["class"] }
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AccordionContent
|
||||
v-bind="delegatedProps"
|
||||
class="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
|
||||
>
|
||||
<div :class="cn('pb-4 pt-0', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</template>
|
27
components/ui/accordion/AccordionItem.vue
Normal file
27
components/ui/accordion/AccordionItem.vue
Normal file
|
@ -0,0 +1,27 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
AccordionItem,
|
||||
type AccordionItemProps,
|
||||
useForwardProps,
|
||||
} from "reka-ui";
|
||||
import { computed, type HTMLAttributes } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
AccordionItemProps & { class?: HTMLAttributes["class"] }
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AccordionItem v-bind="forwardedProps" :class="cn('border-b', props.class)">
|
||||
<slot />
|
||||
</AccordionItem>
|
||||
</template>
|
41
components/ui/accordion/AccordionTrigger.vue
Normal file
41
components/ui/accordion/AccordionTrigger.vue
Normal file
|
@ -0,0 +1,41 @@
|
|||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ChevronDown } from "lucide-vue-next";
|
||||
import {
|
||||
AccordionHeader,
|
||||
AccordionTrigger,
|
||||
type AccordionTriggerProps,
|
||||
} from "reka-ui";
|
||||
import { computed, type HTMLAttributes } from "vue";
|
||||
|
||||
const props = defineProps<
|
||||
AccordionTriggerProps & { class?: HTMLAttributes["class"] }
|
||||
>();
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props;
|
||||
|
||||
return delegated;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AccordionHeader class="flex">
|
||||
<AccordionTrigger
|
||||
v-bind="delegatedProps"
|
||||
:class="
|
||||
cn(
|
||||
'flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180',
|
||||
props.class,
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
<slot name="icon">
|
||||
<ChevronDown
|
||||
class="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200"
|
||||
/>
|
||||
</slot>
|
||||
</AccordionTrigger>
|
||||
</AccordionHeader>
|
||||
</template>
|
4
components/ui/accordion/index.ts
Normal file
4
components/ui/accordion/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export { default as Accordion } from "./Accordion.vue";
|
||||
export { default as AccordionContent } from "./AccordionContent.vue";
|
||||
export { default as AccordionItem } from "./AccordionItem.vue";
|
||||
export { default as AccordionTrigger } from "./AccordionTrigger.vue";
|
Loading…
Add table
Add a link
Reference in a new issue