|
@@ -0,0 +1,276 @@
|
|
|
+<template>
|
|
|
+ <div class="comp-test-container">
|
|
|
+ <h1 class="page-title">Component Demo Page</h1>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">FileUpload Component</h2>
|
|
|
+ <FileUpload
|
|
|
+ upload-url="/api/upload"
|
|
|
+ :format="['png', 'jpg', 'pdf']"
|
|
|
+ @upload-success="handleUploadSuccess"
|
|
|
+ @upload-error="handleUploadError"
|
|
|
+ @valid-error="handleValidError"
|
|
|
+ />
|
|
|
+ <p class="section-description"
|
|
|
+ >Upload URL: /api/upload, Formats: png, jpg, pdf, MaxSize: 5MB</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">ImportDialog Component</h2>
|
|
|
+ <el-button type="primary" @click="openImportDialog"
|
|
|
+ >Open Import Dialog</el-button
|
|
|
+ >
|
|
|
+ <ImportDialog
|
|
|
+ ref="importDialogRef"
|
|
|
+ title="Test Import Dialog"
|
|
|
+ upload-url="/api/import"
|
|
|
+ download-url="/api/download-template"
|
|
|
+ download-filename="template.xlsx"
|
|
|
+ @upload-success="handleImportSuccess"
|
|
|
+ />
|
|
|
+ <p class="section-description"
|
|
|
+ >Title: Test Import Dialog, Upload URL: /api/import</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">UploadButton Component</h2>
|
|
|
+ <UploadButton
|
|
|
+ upload-url="/api/upload-single"
|
|
|
+ btn-text="Upload Single File"
|
|
|
+ accept=".txt,.doc"
|
|
|
+ @upload-success="handleUploadSuccess"
|
|
|
+ />
|
|
|
+ <p class="section-description"
|
|
|
+ >Upload URL: /api/upload-single, Btn Text: Upload Single File, MaxSize:
|
|
|
+ 2MB, Accept: .txt,.doc</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">SvgIcon Component</h2>
|
|
|
+ <div class="svg-icon-showcase">
|
|
|
+ <SvgIcon name="icon-home" class="demo-svg-icon" style="color: blue" />
|
|
|
+ <SvgIcon name="icon-user" class="demo-svg-icon" style="color: green" />
|
|
|
+ <SvgIcon name="icon-system" class="demo-svg-icon" style="color: red" />
|
|
|
+ <SvgIcon name="icon-add" class="demo-svg-icon" />
|
|
|
+ </div>
|
|
|
+ <p class="section-description"
|
|
|
+ >Displaying 'icon-home', 'icon-user', 'icon-system', 'icon-add'.</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">SelectRangeDatetime Component</h2>
|
|
|
+ <SelectRangeDatetime
|
|
|
+ v-model:start-time="startTime"
|
|
|
+ v-model:end-time="endTime"
|
|
|
+ @change="handleDatetimeChange"
|
|
|
+ />
|
|
|
+ <p class="section-description"
|
|
|
+ >Selected Start: {{ startTime }}, End: {{ endTime }}</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">SelectRangeTime Component</h2>
|
|
|
+ <SelectRangeTime
|
|
|
+ v-model:start-time="startTimeStr"
|
|
|
+ v-model:end-time="endTimeStr"
|
|
|
+ format="HH:mm:ss"
|
|
|
+ @change="handleTimeChange"
|
|
|
+ />
|
|
|
+ <p class="section-description"
|
|
|
+ >Selected Start: {{ startTimeStr }}, End: {{ endTimeStr }} (Format:
|
|
|
+ HH:mm:ss)</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">SelectTask Component</h2>
|
|
|
+ <SelectTask
|
|
|
+ v-model="selectedTask"
|
|
|
+ placeholder="Select a task"
|
|
|
+ clearable
|
|
|
+ @change="handleTaskChange"
|
|
|
+ />
|
|
|
+ <p class="section-description"
|
|
|
+ >Selected Task ID: {{ selectedTask }}. (Note: Options are mocked or need
|
|
|
+ API integration)</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">SelectTeaching Component</h2>
|
|
|
+ <SelectTeaching
|
|
|
+ v-model="selectedTeaching"
|
|
|
+ placeholder="Select a teaching point"
|
|
|
+ clearable
|
|
|
+ prefix
|
|
|
+ @change="handleTeachingChange"
|
|
|
+ />
|
|
|
+ <p class="section-description"
|
|
|
+ >Selected Teaching ID: {{ selectedTeaching }}. (Note: Options are mocked
|
|
|
+ or need API integration)</p
|
|
|
+ >
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="component-section">
|
|
|
+ <h2 class="section-title">Footer Component</h2>
|
|
|
+ <Footer />
|
|
|
+ </section>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+ import { ref } from 'vue';
|
|
|
+ import { ElMessage, ElButton } from 'element-plus';
|
|
|
+
|
|
|
+ // Assuming components are globally registered or imported locally as needed
|
|
|
+ // For this demo, we'll rely on global registration or you'd add imports here:
|
|
|
+ import FileUpload from '@/components/file-upload/index.vue';
|
|
|
+ import ImportDialog from '@/components/import-dialog/index.vue';
|
|
|
+ // UploadButton is globally registered based on provided context
|
|
|
+ // SvgIcon is globally registered
|
|
|
+ // SelectRangeDatetime is globally registered
|
|
|
+ // SelectRangeTime is globally registered
|
|
|
+ import SelectTask from '@/components/select-task/index.vue';
|
|
|
+ import SelectTeaching from '@/components/select-teaching/index.vue';
|
|
|
+ import Footer from '@/components/footer/index.vue';
|
|
|
+
|
|
|
+ defineOptions({
|
|
|
+ name: 'CompTest',
|
|
|
+ });
|
|
|
+
|
|
|
+ const importDialogRef = ref<InstanceType<typeof ImportDialog> | null>(null);
|
|
|
+
|
|
|
+ const handleUploadSuccess = (data: any) => {
|
|
|
+ ElMessage.success(`FileUpload Success: ${data.filename}`);
|
|
|
+ console.log('Upload success:', data);
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleUploadError = (err: any) => {
|
|
|
+ ElMessage.error('FileUpload Error');
|
|
|
+ console.error('Upload error:', err);
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleValidError = (err: any) => {
|
|
|
+ ElMessage.warning(`FileUpload Validation Error: ${err.message}`);
|
|
|
+ console.warn('Validation error:', err);
|
|
|
+ };
|
|
|
+
|
|
|
+ const openImportDialog = () => {
|
|
|
+ importDialogRef.value?.open();
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleImportSuccess = (data: any) => {
|
|
|
+ ElMessage.success(`ImportDialog Success: ${data.filename}`);
|
|
|
+ console.log('Import success:', data);
|
|
|
+ importDialogRef.value?.close();
|
|
|
+ };
|
|
|
+
|
|
|
+ // For SelectRangeDatetime
|
|
|
+ const startTime = ref<number | undefined>(
|
|
|
+ Date.now() - 7 * 24 * 60 * 60 * 1000
|
|
|
+ ); // Default to 7 days ago
|
|
|
+ const endTime = ref<number | undefined>(Date.now()); // Default to now
|
|
|
+ const handleDatetimeChange = (values: any) => {
|
|
|
+ console.log('Datetime changed:', values);
|
|
|
+ ElMessage.info(
|
|
|
+ `Datetime range selected: ${new Date(
|
|
|
+ values[0]
|
|
|
+ ).toLocaleString()} - ${new Date(values[1]).toLocaleString()}`
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ // For SelectRangeTime
|
|
|
+ const startTimeStr = ref<string | undefined>('09:00:00');
|
|
|
+ const endTimeStr = ref<string | undefined>('17:00:00');
|
|
|
+ const handleTimeChange = (values: any) => {
|
|
|
+ console.log('Time changed:', values);
|
|
|
+ ElMessage.info(`Time range selected: ${values[0]} - ${values[1]}`);
|
|
|
+ };
|
|
|
+
|
|
|
+ // For SelectTask
|
|
|
+ const selectedTask = ref<number | null>(null);
|
|
|
+ const handleTaskChange = (task: any) => {
|
|
|
+ console.log('Task changed:', task);
|
|
|
+ if (task) {
|
|
|
+ ElMessage.info(`Task selected: ${task.label} (ID: ${task.value})`);
|
|
|
+ } else {
|
|
|
+ ElMessage.info('Task cleared');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // For SelectTeaching
|
|
|
+ const selectedTeaching = ref<number | null>(null);
|
|
|
+ const handleTeachingChange = (teaching: any) => {
|
|
|
+ console.log('Teaching changed:', teaching);
|
|
|
+ if (teaching) {
|
|
|
+ ElMessage.info(
|
|
|
+ `Teaching point selected: ${teaching.label} (ID: ${teaching.value})`
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ ElMessage.info('Teaching point cleared');
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+ .comp-test-container {
|
|
|
+ padding: 20px;
|
|
|
+ max-width: 1000px;
|
|
|
+ margin: 0 auto;
|
|
|
+ background-color: #fff; /* White background for the content page */
|
|
|
+ border-radius: 8px; /* Rounded corners for the content container */
|
|
|
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); /* Softer shadow for the container */
|
|
|
+ }
|
|
|
+
|
|
|
+ .page-title {
|
|
|
+ font-size: 1.75rem; /* Larger page title */
|
|
|
+ font-weight: 600;
|
|
|
+ margin-bottom: 24px;
|
|
|
+ color: #343a40;
|
|
|
+ border-bottom: 1px solid #e9ecef; /* Separator line */
|
|
|
+ padding-bottom: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .component-section {
|
|
|
+ margin-bottom: 32px; /* Increased space between sections */
|
|
|
+ padding: 20px;
|
|
|
+ border: 1px solid #e9ecef; /* Lighter border for sections */
|
|
|
+ border-radius: 8px; /* Rounded corners for sections */
|
|
|
+ background-color: #f8f9fa; /* Slightly off-white background for sections */
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-title {
|
|
|
+ font-size: 1.3rem; /* Consistent section title size */
|
|
|
+ font-weight: 500;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ color: #007bff; /* Blue color for section titles */
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-description {
|
|
|
+ margin-top: 12px;
|
|
|
+ font-size: 0.9rem;
|
|
|
+ color: #6c757d; /* Gray color for descriptions */
|
|
|
+ line-height: 1.6;
|
|
|
+ }
|
|
|
+
|
|
|
+ .svg-icon-showcase {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 20px; /* Space between icons */
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .demo-svg-icon {
|
|
|
+ font-size: 28px; /* Larger demo icons */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Ensure Element Plus components like el-button integrate well */
|
|
|
+ .component-section .el-button {
|
|
|
+ margin-bottom: 10px; /* Space below buttons if needed */
|
|
|
+ }
|
|
|
+</style>
|