mirror of
https://github.com/keven1024/015.git
synced 2026-05-26 07:08:02 +00:00
refactor(front): replace div elements with BaseCard component for consistent styling across various views
This commit is contained in:
12
front/components/BaseCard.vue
Normal file
12
front/components/BaseCard.vue
Normal file
@@ -0,0 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
title?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rounded-xl p-5 bg-white/50 backdrop-blur-xl w-full lg:w-200">
|
||||
<div v-if="title" class="text-xl font-normal">{{ title }}</div>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -28,7 +28,6 @@ watch(
|
||||
</script>
|
||||
<template>
|
||||
<VeeForm ref="formRef" v-slot="{ values }" :keepValues="true">
|
||||
<div class="rounded-xl p-5 bg-white/50 backdrop-blur-xl w-full lg:w-200">
|
||||
<component
|
||||
:is="renderComponent"
|
||||
:data="values"
|
||||
@@ -38,6 +37,5 @@ watch(
|
||||
}
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</VeeForm>
|
||||
</template>
|
||||
|
||||
@@ -29,12 +29,11 @@ const handleFormSubmit = async (form: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gap-5 flex flex-col">
|
||||
<div class="text-xl font-normal">{{ t('page.upload.file.uploadFile') }}</div>
|
||||
<BaseCard class="gap-5 flex flex-col" :title="t('page.upload.file.uploadFile')">
|
||||
<FileUploadField name="file" rules="required" />
|
||||
<div class="flex flex-row gap-3">
|
||||
<FormButton @click="handleFormSubmit"> <LucideShare class="size-4" />{{ t('btn.submit') }} </FormButton>
|
||||
<PickupShareBtn />
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
@@ -283,7 +283,7 @@ const handleShowSpeedInfo = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid grid-cols-4 gap-5">
|
||||
<BaseCard class="grid grid-cols-4 gap-5">
|
||||
<FileUploadTotalSpeedView :speedChartData="speedChartData" />
|
||||
<FileUploadTotalProgressControlView :uploadfiles="uploadfiles" />
|
||||
<div class="col-span-4 flex flex-col bg-white/80 rounded-xl p-3 text-md gap-5">
|
||||
@@ -396,5 +396,5 @@ const handleShowSpeedInfo = () => {
|
||||
</div>
|
||||
</div>
|
||||
<FileUploadDetailView :uploadfiles="uploadfiles" :selectedFile="selectedFile" />
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
@@ -14,19 +14,26 @@ const renderComponent = computed(() => {
|
||||
return textStepList.find((item) => item.key === step.value)?.component
|
||||
})
|
||||
const formRef = ref<InstanceType<typeof VeeForm>>()
|
||||
watch(() => step.value, (newVal) => {
|
||||
watch(
|
||||
() => step.value,
|
||||
(newVal) => {
|
||||
if (newVal === 'input') {
|
||||
formRef.value?.form?.resetForm()
|
||||
// formRef.value?.form?.setValues({ file: null })
|
||||
}
|
||||
})
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<template>
|
||||
<VeeForm ref="formRef" v-slot="{ values }" :keepValues="true">
|
||||
<div class="rounded-xl p-5 bg-white/50 backdrop-blur-xl w-full lg:w-200">
|
||||
<component :is="renderComponent" :data="values" @change="(key: string) => {
|
||||
<component
|
||||
:is="renderComponent"
|
||||
:data="values"
|
||||
@change="
|
||||
(key: string) => {
|
||||
step = key
|
||||
}" />
|
||||
</div>
|
||||
}
|
||||
"
|
||||
/>
|
||||
</VeeForm>
|
||||
</template>
|
||||
@@ -21,8 +21,7 @@ const handleTextShare = ({ type, config }: { type: string; config: any }) => {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="gap-5 flex flex-col">
|
||||
<div class="text-xl font-normal">{{ t('page.upload.text.uploadText') }}</div>
|
||||
<BaseCard class="gap-5 flex flex-col" :title="t('page.upload.text.uploadText')">
|
||||
<div class="relative">
|
||||
<MarkdownInputField
|
||||
name="text"
|
||||
@@ -68,5 +67,5 @@ const handleTextShare = ({ type, config }: { type: string; config: any }) => {
|
||||
</FormButton>
|
||||
<PickupShareBtn />
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
@@ -57,8 +57,7 @@ const { copy } = useClipboard()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-3">
|
||||
<h2 class="text-lg">{{ t('page.result.file.title') }}</h2>
|
||||
<BaseCard class="flex flex-col gap-3" :title="t('page.result.file.title')">
|
||||
<div class="flex flex-col gap-3 items-center">
|
||||
<div v-if="data?.length === 1" class="flex flex-col h-30 items-center">
|
||||
<FilePreviewView :value="props?.data?.files?.[0]?.file as File" />
|
||||
@@ -206,5 +205,5 @@ const { copy } = useClipboard()
|
||||
{{ t('btn.backToHome') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
@@ -106,8 +106,7 @@ watch(
|
||||
)
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex flex-col gap-3">
|
||||
<h2 class="text-lg">图片压缩</h2>
|
||||
<BaseCard class="flex flex-col gap-3" title="图片压缩">
|
||||
<div class="flex flex-row gap-3">
|
||||
<div class="rounded-xl flex flex-col bg-white/70 px-3 py-2 gap-1 basis-2/3">
|
||||
<div class="text-sm font-semibold">总大小</div>
|
||||
@@ -196,5 +195,5 @@ watch(
|
||||
/></AsyncButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
@@ -24,8 +24,6 @@ const activeHandle = computed(() => {
|
||||
// vue这个ts蠢的没边了,本来想写component: FileShareResult | TextShareResult,结果不行
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<component v-if="'files' in data" :is="activeHandle?.component" :data="data" @change="(key: string) => emit('change', key)" />
|
||||
<component v-if="'text' in data" :is="activeHandle?.component" :data="data" @change="(key: string) => emit('change', key)" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -42,7 +42,7 @@ const { t } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-3">
|
||||
<BaseCard class="flex flex-col gap-3" :title="t('page.result.text.title')">
|
||||
<div class="flex flex-row gap-2">
|
||||
<div class="flex flex-row justify-between w-full">
|
||||
<h2 class="text-lg">{{ t('page.result.text.title') }}</h2>
|
||||
@@ -140,5 +140,5 @@ const { t } = useI18n()
|
||||
</div>
|
||||
<h2 class="text-md">{{ t('page.result.text.content') }}</h2>
|
||||
<MarkdownRender class="prose rounded-md bg-white/70 p-3 w-full max-w-full min-h-[30vh]" :markdown="props?.data?.text" />
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
@@ -14,9 +14,9 @@ const handleError = () => clearError({ redirect: '/' })
|
||||
|
||||
<template>
|
||||
<NuxtLayout>
|
||||
<div class="rounded-xl p-5 bg-white/50 backdrop-blur-xl w-full lg:w-200 flex flex-col items-center justify-center min-h-[50vh] mt-5 gap-10">
|
||||
<BaseCard class="flex flex-col items-center justify-center min-h-[50vh] mt-5 gap-10">
|
||||
<div class="font-bold text-5xl">{{ error?.statusCode }}</div>
|
||||
<Button @click="handleError">{{ t('btn.backToHome') }}</Button>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
|
||||
@@ -6,10 +6,9 @@ const { t } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rounded-xl p-5 bg-white/50 backdrop-blur-xl w-full lg:w-200 my-5 flex flex-col gap-5">
|
||||
<div class="text-xl font-normal">{{ t('page.about.title') }}</div>
|
||||
<BaseCard class="my-5 flex flex-col gap-5" :title="t('page.about.title')">
|
||||
<AboutBaseInfo />
|
||||
<AboutChartView />
|
||||
<AboutVersionView />
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
@@ -19,8 +19,7 @@ if (!isDev) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rounded-xl p-5 bg-white/50 backdrop-blur-xl w-full lg:w-200 my-5 flex flex-col gap-5">
|
||||
<h1>Dev</h1>
|
||||
<BaseCard class="my-5 flex flex-col gap-5" title="dev">
|
||||
<div class="flex flex-row gap-5 items-center">
|
||||
<Button
|
||||
@click="
|
||||
@@ -74,6 +73,6 @@ if (!isDev) {
|
||||
</div>
|
||||
</VeeForm>
|
||||
<div>测试dayjs语言包渲染:{{ dayjs().add(1, 'day').fromNow() }}</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -23,7 +23,7 @@ const { data, isLoading, error } = useQuery({
|
||||
}>(`/api/share/${id.value}`)
|
||||
return data?.data
|
||||
},
|
||||
retry: false
|
||||
retry: false,
|
||||
})
|
||||
|
||||
const isExpired = computed(() => {
|
||||
@@ -33,13 +33,12 @@ const isExpired = computed(() => {
|
||||
|
||||
const componentMap = {
|
||||
file: FileShareView,
|
||||
text: TextShareView
|
||||
text: TextShareView,
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="rounded-xl p-5 bg-white/50 backdrop-blur-xl w-full lg:w-200 my-5 overflow-hidden">
|
||||
<BaseCard class="my-5 overflow-hidden">
|
||||
<div v-if="isLoading" class="flex flex-col gap-5 items-center">
|
||||
<Skeleton class="w-20 h-5 rounded-full" />
|
||||
<Skeleton class="w-16 h-16 rounded-xl" />
|
||||
@@ -53,14 +52,18 @@ const componentMap = {
|
||||
<div v-if="isExpired || !data" class="flex flex-col gap-5 items-center">
|
||||
<LucideAlertCircle :size="48" class="text-orange-500 rounded-full bg-orange-500/30 p-2" />
|
||||
<div class="text-xl">此链接已过期。</div>
|
||||
<Button @click="() => {
|
||||
<Button
|
||||
@click="
|
||||
() => {
|
||||
router.push('/')
|
||||
}">返回首页</Button>
|
||||
}
|
||||
"
|
||||
>返回首页</Button
|
||||
>
|
||||
</div>
|
||||
<template v-else>
|
||||
<component :is="componentMap[data?.type as keyof typeof componentMap] || 'div'" :data="data" />
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user