diff --git a/src/assets/icons/CFile.svg b/src/assets/icons/CFile.svg new file mode 100644 index 00000000..e824de6e --- /dev/null +++ b/src/assets/icons/CFile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/award/upload_video_icon.png b/src/assets/images/award/upload_video_icon.png new file mode 100644 index 00000000..dbc1ed68 Binary files /dev/null and b/src/assets/images/award/upload_video_icon.png differ diff --git a/src/views/AwardPage/apply.vue b/src/views/AwardPage/apply.vue index 9ed29bf7..ad2bea7b 100644 --- a/src/views/AwardPage/apply.vue +++ b/src/views/AwardPage/apply.vue @@ -13,7 +13,10 @@
AiDA Users Only
- +
-
+

Click to upload or drag and drop

PDF file, max 20MB

+
-
-
+ class="progress-bar-container" + v-if="pdfUploadStatus === 'uploading'" + > +
+
@@ -209,23 +232,19 @@ :validate-trigger="[]" label="How will you use AiDA in your design process?" > -
+
@@ -233,25 +252,48 @@

Video file (MP4, MOV), 1080p, max 100MB

+
-
-
+ class="progress-bar-container" + v-if="videoUploadStatus === 'uploading'" + > +
+
@@ -342,7 +384,7 @@ import { ref, onUnmounted, onMounted, computed } from 'vue' import { debounce } from 'lodash-es' import type { Rule } from 'ant-design-vue/es/form' - import { message } from 'ant-design-vue' + import { message, Upload } from 'ant-design-vue' import { Https } from '@/tool/https' import { useRoute } from 'vue-router' import type { UploadChangeParam } from 'ant-design-vue' @@ -359,7 +401,7 @@ const route = useRoute() const isCompleted = ref(false) - const hasValidEmail = ref(false) + const readOnly = computed(() => { if (route.query.id && !hasValidEmail.value) { return true @@ -369,7 +411,7 @@ }) const formRef = ref(null) const form = ref({ - email: '', + email: 'yhzhang@aidlab.hk', firstName: '', lastName: '', gender: '', @@ -383,7 +425,10 @@ designDescription: '', pdfPath: '', videoPath: '', - secureToken: null + secureToken: '' + }) + const hasValidEmail = computed(() => { + return !!form.value.secureToken }) // 验证码输入组件引用 @@ -620,7 +665,6 @@ console.log('coderes', res) form.value.secureToken = res.data.secureToken - hasValidEmail.value = true message.success('Verification successful!') showModal.value = false @@ -675,7 +719,7 @@ const beforeUploadFile = (type: FileType, file: File) => { if (!hasValidEmail.value) { message.error('Please verify your email first') - return false + return Upload.LIST_IGNORE } let maxSize: number let allowedExtensions: string[] @@ -693,7 +737,7 @@ allowedMimeTypes = ['video/mp4', 'video/quicktime'] errorMessage = 'Please upload a MP4 or MOV file only.' } else { - return false + return Upload.LIST_IGNORE } // 验证文件类型 @@ -705,18 +749,18 @@ if (!isValidType) { message.error(errorMessage) // 从文件列表中移除 - if (type === 'pdf') { - const index = pdfList.value.findIndex(item => item.uid === file.uid) - if (index > -1) { - pdfList.value.splice(index, 1) - } - } else { - const index = videoList.value.findIndex(item => item.uid === file.uid) - if (index > -1) { - videoList.value.splice(index, 1) - } - } - return false // 阻止上传 + // if (type === 'pdf') { + // const index = pdfList.value.findIndex(item => item.uid === file.uid) + // if (index > -1) { + // pdfList.value.splice(index, 1) + // } + // } else { + // const index = videoList.value.findIndex(item => item.uid === file.uid) + // if (index > -1) { + // videoList.value.splice(index, 1) + // } + // } + return Upload.LIST_IGNORE } // 验证文件大小 @@ -726,21 +770,21 @@ `File size exceeds ${sizeLimit} limit. Please upload a smaller file.` ) // 从文件列表中移除 - if (type === 'pdf') { - const index = pdfList.value.findIndex(item => item.uid === file.uid) - if (index > -1) { - pdfList.value.splice(index, 1) - } - } else { - const index = videoList.value.findIndex(item => item.uid === file.uid) - if (index > -1) { - videoList.value.splice(index, 1) - } - } - return false // 阻止上传 + // if (type === 'pdf') { + // const index = pdfList.value.findIndex(item => item.uid === file.uid) + // if (index > -1) { + // pdfList.value.splice(index, 1) + // } + // } else { + // const index = videoList.value.findIndex(item => item.uid === file.uid) + // if (index > -1) { + // videoList.value.splice(index, 1) + // } + // } + return Upload.LIST_IGNORE } - return true // 允许上传 + return true } // PDF文件上传前验证 @@ -822,18 +866,22 @@ } const completeChunkUpload = async (type: FileType, file: File) => { - const endpoint = - type === 'pdf' - ? Https.httpUrls.uploadPDFComplete - : Https.httpUrls.uploadVideoComplete + try { + const endpoint = + type === 'pdf' + ? Https.httpUrls.uploadPDFComplete + : Https.httpUrls.uploadVideoComplete - return Https.axiosPost(endpoint, { - uploadId: chunkUploadState[type].uploadId, - email: form.value.email, - fileName: file.name, - totalSize: file.size, - secureToken: form.value.secureToken - }) + return Https.axiosPost(endpoint, { + uploadId: chunkUploadState[type].uploadId, + email: form.value.email, + fileName: file.name, + totalSize: file.size, + secureToken: form.value.secureToken + }) + } catch (error) { + console.log('complete错误', error) + } } type FileType = 'pdf' | 'video' @@ -922,10 +970,12 @@ isUploadingPdf.value = false uploadProgressPdf.value = 0 pdfUploadStatus.value = 'error' + pdfList.value = [] } else { isUploadingVideo.value = false uploadProgressVideo.value = 0 videoUploadStatus.value = 'error' + videoList.value = [] } } } @@ -940,6 +990,18 @@ return handleUploadFile(option, 'video') } + const handleRemoveFile = (type: 'video' | 'pdf') => { + if (type === 'pdf') { + form.value.pdfPath = '' + pdfUploadStatus.value = 'idle' + uploadProgressPdf.value = 0 + } else if (type === 'video') { + form.value.videoPath = '' + videoUploadStatus.value = 'idle' + uploadProgressVideo.value = 0 + } + } + const conditionsList = ref([ { check: false, @@ -1238,9 +1300,10 @@ .upload-container { margin-top: 6rem; - + position: relative; :deep(.ant-upload-drag) { height: 32rem; + border-radius: 0.8rem; .ant-upload-btn { padding: 0; @@ -1276,9 +1339,13 @@ display: flex; align-items: center; justify-content: center; - border: 0.2rem solid #d5d5d5; + border: 0.2rem dashed #d5d5d5; border-radius: 0.8rem; background-color: #fafafa; + position: absolute; + top: 0; + left: 0; + width: 100%; .uploading-text { color: #585858; @@ -1306,7 +1373,20 @@ } } } - + .custom-upload-list { + padding: 0.4rem 1rem; + margin-top: 1rem; + &:hover { + background-color: #f5f5f5; + border-radius: 0.4rem; + } + .c-svg { + width: fit-content; + } + .delete-file { + cursor: pointer; + } + } .conditions { margin-top: 12rem; @@ -1462,9 +1542,12 @@ diff --git a/src/views/AwardPage/components/Success.vue b/src/views/AwardPage/components/Success.vue index 4c42df4c..aee43d9e 100644 --- a/src/views/AwardPage/components/Success.vue +++ b/src/views/AwardPage/components/Success.vue @@ -35,7 +35,7 @@ return { icon: expiredIcon, title: 'Application Deadline Passed', - desc: 'The submission deadline for AIDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications. ' + desc: 'The submission deadline for AiDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications. ' } } else { return {