feat: award表单页面

This commit is contained in:
2026-01-19 17:07:05 +08:00
parent a0a751c661
commit a48e517e76
10 changed files with 2658 additions and 1971 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 913 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -427,10 +427,15 @@ const routes: Array<RouteRecordRaw> = [
component: () => import("@/views/AwardPage/container.vue"), component: () => import("@/views/AwardPage/container.vue"),
children:[ children:[
{ {
path:'index', path:'',
name:'AwardIndex', name:'AwardIndex',
component:()=>import('@/views/AwardPage/index.vue') component:()=>import('@/views/AwardPage/index.vue')
}, },
{
path:'index',
name:'AwardIndexAlt',
component:()=>import('@/views/AwardPage/index.vue')
},
{ {
path:'apply', path:'apply',
name:'Apply', name:'Apply',

View File

@@ -327,7 +327,8 @@ export const Https = {
searchAllSubscribePlan: '/api/subscription_plan/searchByPage', // 分页查询所有订阅计划 searchAllSubscribePlan: '/api/subscription_plan/searchByPage', // 分页查询所有订阅计划
searchSubscribeByOrg: '/api/subscription_plan/searchByOrganizationIdAndStatus', // 不分页查询 searchSubscribeByOrg: '/api/subscription_plan/searchByOrganizationIdAndStatus', // 不分页查询
switchSubscribePlan: '/api/subscription_plan/switchSubscriptionPlan', // 切换管理员订阅计划 switchSubscribePlan: '/api/subscription_plan/switchSubscriptionPlan', // 切换管理员订阅计划
switchSubAccountSubscribePlan: '/api/subscription_plan/switchSubAccSubscriptionPlan', // 切换子账号订阅计划 switchSubAccountSubscribePlan:
'/api/subscription_plan/switchSubAccSubscriptionPlan', // 切换子账号订阅计划
//云生成 //云生成
designCloud: `/api/design/designCloud`, //创建云生成 designCloud: `/api/design/designCloud`, //创建云生成
@@ -443,7 +444,12 @@ export const Https = {
refreshMinioUrl: `/api/third/party/refreshMinioUrl`, //获取可以使用的minio地址 refreshMinioUrl: `/api/third/party/refreshMinioUrl`, //获取可以使用的minio地址
// 画布 // 画布
segAnything: `/api/python/segAnything`,//分割Anything segAnything: `/api/python/segAnything`, //分割Anything
// award页面
uploadPDF: '/api/global-award/uploads/pdf', // 上传pdf
uploadVideo: '/api/global-award/uploads/video', // 上传video
}, },
axiosGet(url, config) { axiosGet(url, config) {

View File

@@ -1,7 +1,9 @@
<template> <template>
<div class="apply-container"> <div class="apply-container">
<div class="banner"> <div class="banner">
<div class="slogan">BLOOM YOUR CREATIVITY AiDA GLOBAL FASHION AWARD 2026</div> <div class="slogan">
BLOOM YOUR CREATIVITY AiDA GLOBAL FASHION AWARD 2026
</div>
<div class="title poppins-medium">Application Form</div> <div class="title poppins-medium">Application Form</div>
<div class="form-header"> <div class="form-header">
<div class="form-title poppins-bold">Email Verification</div> <div class="form-title poppins-bold">Email Verification</div>
@@ -16,17 +18,33 @@
layout="vertical" layout="vertical"
:model="form" :model="form"
:rules="rulesRef" :rules="rulesRef"
autocomplete="off"> autocomplete="off"
>
<div class="email-box full-row"> <div class="email-box full-row">
<a-form-item name="email" required label="Email Address"> <a-form-item
name="email"
required
label="Email Address"
>
<div class="email-wrapper flex align-center"> <div class="email-wrapper flex align-center">
<a-input v-model:value="form.email" /> <a-input v-model:value="form.email" />
<div <div
class="code-btn" class="code-btn"
:class="{ disabled: isCountingDown }" :class="{ disabled: isCountingDown }"
@click="handleSendCode"> @click="handleSendCode"
{{ isCountingDown ? formatCountdown(countdown) : 'Send Code' }} >
{{
isCountingDown
? formatCountdown(countdown)
: 'Send Code'
}}
</div> </div>
<img
v-if="hasValidEmail"
src="@/assets/images/award/checked.png"
alt=""
class="checked-icon"
/>
</div> </div>
<div class="tips"> <div class="tips">
Please use the email address you registered with AiDA. Please use the email address you registered with AiDA.
@@ -38,12 +56,16 @@
<div class="desc">Tell us about yourself</div> <div class="desc">Tell us about yourself</div>
</div> </div>
<div class="user-info flex"> <div class="user-info flex">
<template v-for="item in formKeys" :key="item.key"> <template
v-for="item in formKeys"
:key="item.key"
>
<a-form-item <a-form-item
v-if="item.key !== 'email'" v-if="item.key !== 'email'"
:required="item.required" :required="item.required"
:label="item.label" :label="item.label"
:name="item.key"> :name="item.key"
>
<a-input v-model:value="form[item.key]" /> <a-input v-model:value="form[item.key]" />
</a-form-item> </a-form-item>
</template> </template>
@@ -52,12 +74,25 @@
<div class="form-title poppins-bold">Design Information</div> <div class="form-title poppins-bold">Design Information</div>
<div class="desc">Share your creative vision</div> <div class="desc">Share your creative vision</div>
</div> </div>
<a-form-item class="full-row design-title" name="designTitle" label="Design Title" required> <a-form-item
class="full-row design-title"
name="designTitle"
label="Design Title"
required
>
<a-input v-model:value="form.designTitle" /> <a-input v-model:value="form.designTitle" />
</a-form-item> </a-form-item>
<a-form-item class="full-row design-desc" name="description" label="Design description" required> <a-form-item
<a-textarea class="textarea" v-model:value="form.description" class="full-row design-desc"
placeholder="Briefly describe your design concept, inspiration, and creative direction..." /> name="description"
label="Design description"
required
>
<a-textarea
class="textarea"
v-model:value="form.description"
placeholder="Briefly describe your design concept, inspiration, and creative direction..."
/>
</a-form-item> </a-form-item>
<div class="form-row full-row"> <div class="form-row full-row">
<div class="form-title poppins-bold">Submission Files</div> <div class="form-title poppins-bold">Submission Files</div>
@@ -87,52 +122,184 @@
</ul> </ul>
</div> </div>
<div class="upload-container full-row"> <div class="upload-container full-row">
<a-form-item class="full-row" name="pdfFile" required label="How will you use AiDA in your design process?"> <a-form-item
<a-upload-dragger v-model:fileList="pdfList" name="file" action="" class="full-row"
@change="info => handleFileChange(info, 'pdf')"> name="pdfPath"
<img src="@/assets/images/award/upload.png" alt="" class="upload-icon" /> required
label="How will you use AiDA in your design process?"
>
<div
v-if="
pdfUploadStatus === 'idle' ||
pdfUploadStatus === 'error'
"
>
<a-upload-dragger
v-model:fileList="pdfList"
:showUploadList="false"
@change="info => handleFileChange(info, 'pdf')"
:customRequest="handleUploadPdf"
:beforeUpload="beforeUploadPdf"
accept=".pdf"
>
<img
src="@/assets/images/award/upload.png"
alt=""
class="upload-icon"
/>
<p class="desc">Click to upload or drag and drop</p> <p class="desc">Click to upload or drag and drop</p>
<p class="limit">PDF file, max 20MB</p> <p class="limit">PDF file, max 20MB</p>
</a-upload-dragger> </a-upload-dragger>
</div>
<div
v-else
class="uploading-container"
>
<UploadStatus
:status="pdfUploadStatus"
type="pdf"
/>
</div>
<div
class="progress-bar-container"
v-if="pdfUploadStatus === 'uploading'"
>
<div
class="progress-bar"
:style="{ width: `${uploadProgressPdf}%` }"
></div>
</div>
</a-form-item> </a-form-item>
</div> </div>
<div class="upload-container full-row"> <div class="upload-container full-row">
<a-form-item class="full-row" name="videoFile" required <a-form-item
label="How will you use AiDA in your design process?"> class="full-row"
<a-upload-dragger v-model:fileList="videoList" name="file" action="" name="videoPath"
@change="info => handleFileChange(info, 'video')"> required
<img src="@/assets/images/award/upload.png" alt="" class="upload-icon" /> label="How will you use AiDA in your design process?"
>
<div
v-if="
videoUploadStatus === 'idle' ||
videoUploadStatus === 'error'
"
>
<a-upload-dragger
v-model:fileList="videoList"
:showUploadList="false"
@change="info => handleFileChange(info, 'video')"
:customRequest="handleUploadVideo"
:beforeUpload="beforeUploadVideo"
accept=".mp4,.mov"
>
<img
src="@/assets/images/award/upload.png"
alt=""
class="upload-icon"
/>
<p class="desc">Click to upload or drag and drop</p> <p class="desc">Click to upload or drag and drop</p>
<p class="limit">Video file(MP4, MOV), max 20MB</p> <p class="limit">
Video file (MP4, MOV), 1080p, max 100MB
</p>
</a-upload-dragger> </a-upload-dragger>
</div>
<div
v-else
class="uploading-container"
>
<UploadStatus
:status="videoUploadStatus"
type="video"
/>
</div>
<div
class="progress-bar-container"
v-if="videoUploadStatus === 'uploading'"
>
<div
class="progress-bar"
:style="{ width: `${uploadProgressVideo}%` }"
></div>
</div>
</a-form-item> </a-form-item>
</div> </div>
</a-form> </a-form>
<div class="conditions"> <div class="conditions">
<div class="confitions-title poppins-bold">Terms & Conditions</div> <div class="confitions-title poppins-bold">Terms & Conditions</div>
<div class="condition-list flex flex-col"> <div class="condition-list flex flex-col">
<div class="condition-item flex align-center" v-for="item in conditionsList" :key="item.id"> <div
class="condition-item flex align-center"
v-for="item in conditionsList"
:key="item.id"
>
<a-checkbox v-model:checked="item.check" /> <a-checkbox v-model:checked="item.check" />
<span>{{ item.text }}</span> <span>
{{ item.text }}
<span
class="required"
v-if="item.required"
>
*
</span>
</span>
</div>
</div>
</div>
<div class="submit-container">
<div
class="submit-btn poppins-bold"
@click="handleSubmitForm"
>
Submit your Design
</div>
<div class="desc">
The link in the AiDA in-platform message will save your unfinished
form.
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> <a-modal
<a-modal v-model:visible="showModal" :footer="null" :maskClosable="false" :closable="false" v-model:visible="showModal"
:footer="null"
:maskClosable="false"
:closable="false"
wrapClassName="code-modal" wrapClassName="code-modal"
forceRender :keyboard="false" :style="{ top: '29.3rem' }"> forceRender
:keyboard="false"
:style="{ top: '29.3rem' }"
>
<div class="verify-container flex flex-col align-center"> <div class="verify-container flex flex-col align-center">
<img src="@/assets/images/award/close.svg" class="close-icon" @click="handleCloseModal" /> <img
src="@/assets/images/award/close.svg"
class="close-icon"
@click="handleCloseModal"
/>
<div class="title poppins-bold">Check your email</div> <div class="title poppins-bold">Check your email</div>
<div class="desc">Enter the 6-digital code sent to</div> <div class="desc">Enter the 6-digital code sent to</div>
<div class="email">{{ form.email }}</div> <div class="email">{{ form.email }}</div>
<div class="code-box"> <div class="code-box">
<VerifycationCodeInput :ct="emailCode" @sendCaptcha="setVerifyCode" /> <VerifycationCodeInput
:ct="emailCode"
@sendCaptcha="setVerifyCode"
/>
</div> </div>
<div class="verify-btn" @click="handleVerifyCode">Verify</div> <div
<div class="cutdown" :class="{ disabled: isCountingDown }" @click="handleSendCode"> class="verify-btn"
{{ isCountingDown ? `Resend Code in ${formatCountdown(countdown)}` : 'Resend' }} @click="handleVerifyCode"
>
Verify
</div>
<div
class="cutdown"
:class="{ disabled: isCountingDown }"
@click="handleSendCode"
>
{{
isCountingDown
? `Resend Code in ${formatCountdown(countdown)}`
: 'Resend'
}}
</div> </div>
</div> </div>
</a-modal> </a-modal>
@@ -140,16 +307,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onUnmounted } from 'vue' import { ref, reactive, onUnmounted } from 'vue'
import { debounce } from 'lodash-es' import { debounce } from 'lodash-es'
import type { Rule } from 'ant-design-vue/es/form' import type { Rule } from 'ant-design-vue/es/form'
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import type { UploadChangeParam } from 'ant-design-vue' import type { UploadChangeParam } from 'ant-design-vue'
// import VerificationCodeInput from './components/VerificationCodeInput.vue' import VerifycationCodeInput from './components/verificationCodeInput.vue'
import VerifycationCodeInput from './components/verificationCodeInput.vue' import { Https } from '@/tool/https'
import UploadStatus from './components/UploadStatus.vue'
const formRef = ref(null) const hasValidEmail = ref(true)
const form = ref({ const formRef = ref(null)
const form = ref({
email: '', email: '',
firstName: '', firstName: '',
lastName: '', lastName: '',
@@ -162,19 +331,19 @@ const form = ref({
// code: '', // code: '',
designTitle: '', designTitle: '',
description: '', description: '',
pdfFile: null, pdfPath: null,
videoFile: null videoPath: null
}) })
// 验证码输入组件引用 // 验证码输入组件引用
const codeInputRef = ref() const codeInputRef = ref()
const emailCode = ref(['', '', '', '', '', '']) const emailCode = ref(['', '', '', '', '', ''])
const isValidEmail = email => { const isValidEmail = email => {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
return emailRegex.test(email) return emailRegex.test(email)
} }
const validEmail = (rule: Rule, value: string) => { const validEmail = (rule: Rule, value: string) => {
if (!value) { if (!value) {
return Promise.reject('Please input the email address') return Promise.reject('Please input the email address')
} }
@@ -182,8 +351,8 @@ const validEmail = (rule: Rule, value: string) => {
return Promise.reject('Please input a valid email address') return Promise.reject('Please input a valid email address')
} }
return Promise.resolve() return Promise.resolve()
} }
const validateNumber = async (_rule: Rule, value: string) => { const validateNumber = async (_rule: Rule, value: string) => {
if (value === '') { if (value === '') {
return Promise.reject('Please fill in this section.') return Promise.reject('Please fill in this section.')
} }
@@ -191,9 +360,9 @@ const validateNumber = async (_rule: Rule, value: string) => {
return Promise.reject('Please input digits') return Promise.reject('Please input digits')
} }
return Promise.resolve() return Promise.resolve()
} }
const validatePhone = async (_rule: Rule, value: string) => { const validatePhone = async (_rule: Rule, value: string) => {
if (value === '') { if (value === '') {
return Promise.reject('Please enter your phone number.') return Promise.reject('Please enter your phone number.')
} }
@@ -202,9 +371,9 @@ const validatePhone = async (_rule: Rule, value: string) => {
return Promise.reject('Please enter a valid phone number.') return Promise.reject('Please enter a valid phone number.')
} }
return Promise.resolve() return Promise.resolve()
} }
const validateVerificationCode = async (_rule: Rule, value: string) => { const validateVerificationCode = async (_rule: Rule, value: string) => {
if (value === '') { if (value === '') {
return Promise.reject('Please enter the verification code.') return Promise.reject('Please enter the verification code.')
} }
@@ -213,16 +382,18 @@ const validateVerificationCode = async (_rule: Rule, value: string) => {
return Promise.reject('Please enter a 6-digit verification code.') return Promise.reject('Please enter a 6-digit verification code.')
} }
return Promise.resolve() return Promise.resolve()
} }
const rulesRef = { const rulesRef = {
email: [{ required: true, validator: validEmail }], email: [{ required: true, validator: validEmail }],
firstName: [ firstName: [
{ required: true, message: 'Please input your first name', trigger: 'blur' } { required: true, message: 'Please input your first name', trigger: 'blur' }
], ],
lastName: [{ required: true, message: 'Please input your last name', trigger: 'blur' }] lastName: [
} { required: true, message: 'Please input your last name', trigger: 'blur' }
]
}
const formKeys = ref([ const formKeys = ref([
{ {
label: 'First Name', label: 'First Name',
required: true, required: true,
@@ -272,22 +443,22 @@ const formKeys = ref([
type: 'input', type: 'input',
key: 'portfoilo' key: 'portfoilo'
} }
]) ])
const showModal = ref(false) const showModal = ref(false)
// 倒计时相关状态 // 倒计时相关状态
const countdown = ref(0) const countdown = ref(0)
const countdownTimer = ref<NodeJS.Timeout | null>(null) const countdownTimer = ref<NodeJS.Timeout | null>(null)
const isCountingDown = ref(false) const isCountingDown = ref(false)
const formatCountdown = (seconds: number) => { const formatCountdown = (seconds: number) => {
const minutes = Math.floor(seconds / 60) const minutes = Math.floor(seconds / 60)
const remainingSeconds = seconds % 60 const remainingSeconds = seconds % 60
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds return `${minutes.toString().padStart(2, '0')}:${remainingSeconds
.toString() .toString()
.padStart(2, '0')}` .padStart(2, '0')}`
} }
const startCountdown = () => { const startCountdown = () => {
countdown.value = 60 countdown.value = 60
isCountingDown.value = true isCountingDown.value = true
@@ -297,18 +468,18 @@ const startCountdown = () => {
clearCountdown() clearCountdown()
} }
}, 1000) }, 1000)
} }
const clearCountdown = () => { const clearCountdown = () => {
if (countdownTimer.value) { if (countdownTimer.value) {
clearInterval(countdownTimer.value) clearInterval(countdownTimer.value)
countdownTimer.value = null countdownTimer.value = null
} }
countdown.value = 0 countdown.value = 0
isCountingDown.value = false isCountingDown.value = false
} }
const handleSendCode = debounce(async () => { const handleSendCode = debounce(async () => {
// 如果正在倒计时,不允许再次发送 // 如果正在倒计时,不允许再次发送
if (isCountingDown.value) { if (isCountingDown.value) {
return return
@@ -324,19 +495,35 @@ const handleSendCode = debounce(async () => {
showModal.value = true showModal.value = true
} catch (error) {} } catch (error) {}
}, 300) }, 300)
const verifyCode = ref(null) const verifyCode = ref(null)
const setVerifyCode = value => { const setVerifyCode = value => {
verifyCode.value = value verifyCode.value = value
} }
const handleCloseModal = () => { const handleCloseModal = () => {
showModal.value = false showModal.value = false
} }
const handleVerifyCode = () => { const handleSubmitForm = () => {
const validCondition = conditionsList.value.filter(
item => item.required && !item.check
)
if (validCondition.length > 0) {
message.error('Please check the terms and conditions')
return
}
formRef.value.validate().then(res => {
console.log(res)
}).catch(err => {
console.log(err)
message.error('Please fill in all the required fields')
})
}
const handleVerifyCode = () => {
if (verifyCode.value.length !== 6) { if (verifyCode.value.length !== 6) {
message.error('Please enter the complete 6-digit verification code') message.error('Please enter the complete 6-digit verification code')
return return
@@ -346,40 +533,216 @@ const handleVerifyCode = () => {
// 关闭模态框 // 关闭模态框
showModal.value = false showModal.value = false
}
const pdfList = ref([])
const videoList = ref([])
type FileType = 'pdf' | 'video'
const handleFileChange = (info: UploadChangeParam, type: FileType) => {
console.log('change---------')
const status = info.file.status
if (status !== 'uploading') {
console.log('file:', info.file)
} }
const pdfList = ref([])
const videoList = ref([])
const isUploadingPdf = ref(false)
const uploadProgressPdf = ref(0)
const isUploadingVideo = ref(false)
const uploadProgressVideo = ref(0)
const pdfUploadStatus = ref<'idle' | 'uploading' | 'success' | 'error'>('idle')
const videoUploadStatus = ref<'idle' | 'uploading' | 'success' | 'error'>('idle')
// 统一的文件上传前验证
const beforeUploadFile = (type: FileType, file: File) => {
if (!hasValidEmail.value) {
message.error('Please verify your email first')
return false
}
let maxSize: number
let allowedExtensions: string[]
let allowedMimeTypes: string[]
let errorMessage: string
if (type === 'pdf') {
maxSize = 20 * 1024 * 1024 // 20MB
allowedExtensions = ['pdf']
allowedMimeTypes = ['application/pdf']
errorMessage = 'Please upload a PDF file only.'
} else if (type === 'video') {
maxSize = 100 * 1024 * 1024 // 100MB
allowedExtensions = ['mp4', 'mov']
allowedMimeTypes = ['video/mp4', 'video/quicktime']
errorMessage = 'Please upload a MP4 or MOV file only.'
} else {
return false
}
// 验证文件类型
const fileExtension = file.name.split('.').pop()?.toLowerCase()
const isValidType =
allowedExtensions.includes(fileExtension || '') ||
allowedMimeTypes.includes(file.type)
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 (file.size > maxSize) {
const sizeLimit = type === 'pdf' ? '20MB' : '100MB'
message.error(
`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 // 阻止上传
}
return true // 允许上传
}
// PDF文件上传前验证
const beforeUploadPdf = (file: File) => {
return beforeUploadFile('pdf', file)
}
// Video文件上传前验证
const beforeUploadVideo = (file: File) => {
return beforeUploadFile('video', file)
}
type FileType = 'pdf' | 'video'
const handleFileChange = (info: UploadChangeParam, type: FileType) => {
const status = info.file.status
if (status === 'done') { if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`) message.success(`${info.file.name} file uploaded successfully.`)
if (type === 'pdf') { if (type === 'pdf') {
isUploadingPdf.value = false
uploadProgressPdf.value = 0
pdfUploadStatus.value = 'success'
} else if (type === 'video') {
isUploadingVideo.value = false
uploadProgressVideo.value = 0
videoUploadStatus.value = 'success'
} }
} else if (status === 'error') { } else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`) message.error(`${info.file.name} file upload failed.`)
if (type === 'pdf') {
isUploadingPdf.value = false
uploadProgressPdf.value = 0
pdfUploadStatus.value = 'error'
} else if (type === 'video') {
isUploadingVideo.value = false
uploadProgressVideo.value = 0
videoUploadStatus.value = 'error'
}
}
} }
}
const conditionsList = ref([ // 统一的上传处理函数
const handleUploadFile = (option: any, type: FileType) => {
console.log(option, type)
const file = option.file
// 根据类型设置上传状态和进度
if (type === 'pdf') {
isUploadingPdf.value = true
uploadProgressPdf.value = 0
pdfUploadStatus.value = 'uploading'
} else if (type === 'video') {
isUploadingVideo.value = true
uploadProgressVideo.value = 0
videoUploadStatus.value = 'uploading'
}
const params = new FormData()
params.append('file', file)
params.append('email', form.value.email)
// 根据类型选择不同的上传接口
const uploadUrl = Https.httpUrls.uploadAvatar
// const uploadUrl =
// type === 'pdf' ? Https.httpUrls.uploadPDF : Https.httpUrls.uploadVideo
Https.axiosPost(uploadUrl, params, {
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: progressEvent => {
if (progressEvent.total) {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
)
if (type === 'pdf') {
uploadProgressPdf.value = percentCompleted
} else if (type === 'video') {
uploadProgressVideo.value = percentCompleted
}
}
}
})
.then(res => {
console.log(res)
if (type === 'pdf') pdfUploadStatus.value = 'success'
if (type === 'video') videoUploadStatus.value = 'success'
option.onSuccess(res, option.file)
})
.catch(error => {
console.error('Upload error:', error)
option.onError(error)
if (type === 'pdf') {
isUploadingPdf.value = false
uploadProgressPdf.value = 0
pdfUploadStatus.value = 'error'
} else if (type === 'video') {
isUploadingVideo.value = false
uploadProgressVideo.value = 0
videoUploadStatus.value = 'error'
}
})
}
// PDF上传处理
const handleUploadPdf = (option: any) => {
return handleUploadFile(option, 'pdf')
}
// Video上传处理
const handleUploadVideo = (option: any) => {
return handleUploadFile(option, 'video')
}
const conditionsList = ref([
{ {
check: false, check: false,
required: true,
text: 'I confirm that all submitted work is original and created by me.', text: 'I confirm that all submitted work is original and created by me.',
id: 'first' id: 'first'
}, },
{ {
check: false, check: false,
required: true,
text: 'I understand that Code-Create has marketing and promotional rights to all submitted designs and videos.', text: 'I understand that Code-Create has marketing and promotional rights to all submitted designs and videos.',
id: 'second' id: 'second'
}, },
{ {
check: false, check: false,
required: true,
text: 'I agree to participate in finalist activities if selected, including AiDA training and award ceremony.', text: 'I agree to participate in finalist activities if selected, including AiDA training and award ceremony.',
id: 'third' id: 'third'
}, },
@@ -388,30 +751,30 @@ const conditionsList = ref([
text: 'I would like to receive updates about AiDA products and future competitions. (Optional)', text: 'I would like to receive updates about AiDA products and future competitions. (Optional)',
id: 'forth' id: 'forth'
} }
]) ])
// 组件卸载时清理定时器 // 组件卸载时清理定时器
onUnmounted(() => { onUnmounted(() => {
clearCountdown() clearCountdown()
}) })
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.poppins-bold { .poppins-bold {
font-family: 'PoppinsBold'; font-family: 'PoppinsBold';
font-weight: 600; font-weight: 600;
} }
.poppins-medium { .poppins-medium {
font-family: 'PoppinsMedium'; font-family: 'PoppinsMedium';
font-weight: 500; font-weight: 500;
} }
.full-row { .full-row {
width: 100%; width: 100%;
} }
.banner { .banner {
height: 54.8rem; height: 54.8rem;
background: url('@/assets/images/award/apply_bg.png') no-repeat; background: url('@/assets/images/award/apply_bg.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
@@ -458,9 +821,9 @@ onUnmounted(() => {
font-size: 2.4rem; font-size: 2.4rem;
} }
} }
} }
.form-row { .form-row {
margin-top: 12rem; margin-top: 12rem;
margin-bottom: 6rem; margin-bottom: 6rem;
@@ -477,9 +840,9 @@ onUnmounted(() => {
font-weight: 500; font-weight: 500;
font-size: 2.4rem; font-size: 2.4rem;
} }
} }
.form-container { .form-container {
padding: 0 21.4rem 12rem; padding: 0 21.4rem 12rem;
background-color: #f5f5f5; background-color: #f5f5f5;
@@ -552,6 +915,13 @@ onUnmounted(() => {
.email-wrapper { .email-wrapper {
border-radius: 0.8rem; border-radius: 0.8rem;
border: 0.2rem solid #d5d5d5; border: 0.2rem solid #d5d5d5;
position: relative;
.checked-icon {
position: absolute;
right: -6rem;
width: 4rem;
height: 4rem;
}
} }
.code-btn { .code-btn {
@@ -581,13 +951,13 @@ onUnmounted(() => {
margin-top: 1rem; margin-top: 1rem;
} }
} }
} }
:deep(.ant-form-item-label) { :deep(.ant-form-item-label) {
padding: 0 0 1rem; padding: 0 0 1rem;
} }
.information { .information {
padding-left: 2.4rem; padding-left: 2.4rem;
.information-title { .information-title {
@@ -619,9 +989,9 @@ onUnmounted(() => {
white-space: pre-line; white-space: pre-line;
} }
} }
} }
.upload-container { .upload-container {
margin-top: 6rem; margin-top: 6rem;
:deep(.ant-upload-drag) { :deep(.ant-upload-drag) {
@@ -655,9 +1025,44 @@ onUnmounted(() => {
} }
} }
} }
}
.conditions { .uploading-container {
height: 32rem;
display: flex;
align-items: center;
justify-content: center;
border: 0.2rem solid #d5d5d5;
border-radius: 0.8rem;
background-color: #fafafa;
.uploading-text {
color: #585858;
font-family: 'Arial';
font-weight: 400;
font-size: 2.4rem;
}
}
.progress-bar-container {
width: 100%;
height: 1rem;
background-color: #f0f0f0;
border-radius: 0.8rem;
margin-top: 2rem;
overflow: hidden;
position: absolute;
bottom: 0;
.progress-bar {
height: 100%;
background-color: #c7342c;
border-radius: 0.8rem;
transition: width 0.3s ease;
}
}
}
.conditions {
margin-top: 12rem; margin-top: 12rem;
&-title { &-title {
@@ -680,32 +1085,68 @@ onUnmounted(() => {
font-size: 1.8rem; font-size: 1.8rem;
padding-left: 1.5rem; padding-left: 1.5rem;
column-gap: 2.5rem; column-gap: 2.5rem;
.required {
color: #c7342c;
}
} }
:deep(.ant-checkbox-inner) { :deep(.ant-checkbox-wrapper) {
border: 0.2rem solid #585858; .ant-checkbox-inner {
//修改边框的颜色
width: 2rem;
height: 2rem;
border: 0.2rem solid #585858 !important;
border-radius: 0.4rem;
} }
:deep(.ant-checkbox-wrapper:hover .ant-checkbox-inner, .ant-checkbox-checked .ant-checkbox-inner {
.ant-checkbox:hover .ant-checkbox-inner, //修改选中框的背景颜色
.ant-checkbox-input:focus + .ant-checkbox-inner) { background-color: #fff !important;
/* 将背景颜色修改为白色 */
//修改边框颜色
border-color: #585858 !important; border-color: #585858 !important;
/* 将边框颜色修改为黑色 */
} }
:deep(.ant-checkbox-wrapper:hover .ant-checkbox-inner, .ant-checkbox-checked .ant-checkbox-inner::after {
.ant-checkbox:hover .ant-checkbox-inner, //antd的checkbox组件的选中框里面的透明的钩子是通过设置底部边框和右边框的颜色再旋转得到的钩子
.ant-checkbox-input:focus+.ant-checkbox-inner) { // 所以设置底部边框和右边框的样式就可以修改钩子的样式
border-color: #585858 !important; border-bottom: 0.2rem solid #585858;
border-right: 0.2rem solid #585858;
width: 0.65rem;
height: 1rem;
left: 21.895%;
}
}
}
} }
:deep(.ant-checkbox-checked .ant-checkbox-inner) { .submit-container {
border-color: #000 !important; margin-top: 12rem;
background-color: #000 !important;
}
}
}
.verify-container { .submit-btn {
height: 5rem;
background-color: #454545;
border-radius: 0.8rem;
color: #fff;
line-height: 5rem;
text-align: center;
font-size: 1.6rem;
cursor: pointer;
}
.desc {
// font-family: 'instrument';
font-family: revert-layer;
font-weight: 400;
font-size: 1.6rem;
color: #6d6d6d;
text-align: center;
margin-top: 2rem;
}
}
.verify-container {
width: 60rem; width: 60rem;
height: 49.4rem; height: 49.4rem;
padding: 6rem 8.6rem; padding: 6rem 8.6rem;
@@ -779,13 +1220,13 @@ onUnmounted(() => {
cursor: not-allowed; cursor: not-allowed;
} }
} }
} }
</style> </style>
<style lang="less"> <style lang="less">
.code-modal { .code-modal {
.ant-modal-content .ant-modal-body { .ant-modal-content .ant-modal-body {
padding: 0; padding: 0;
// width: 60rem; // width: 60rem;
} }
} }
</style> </style>

View File

@@ -0,0 +1,79 @@
<template>
<div class="upload-status">
<div class="upload-status-item">
<div class="upload-status-item-icon">
<img
v-if="status === 'uploading'"
src="@/assets/images/award/progress.png"
alt=""
class="progress-icon"
/>
<img
v-if="status === 'success'"
src="@/assets/images/award/successful.png"
alt=""
class="progress-icon successful-icon"
/>
</div>
<div class="text">{{ text }}</div>
<div class="tips">{{ tips }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, watch } from 'vue'
const props = defineProps<{
status: string
type: 'pdf' | 'video'
}>()
const textMap: Record<string, string> = {
idle: '',
uploading: 'Upload in progress…',
success: 'Uploaded Successfully',
error: 'Upload failed'
}
const tips = computed(() => {
if (props.type === 'pdf') {
return 'PDF file, max 20MB'
} else if (props.type === 'video') {
return 'Video file (MP4, MOV), 1080p, max 100MB'
}
return ''
})
const text = computed(() => {
return textMap[props.status] ?? textMap.uploading
})
</script>
<style scoped lang="less">
.upload-status {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.upload-status-item {
display: flex;
flex-direction: column;
align-items: center;
.progress-icon {
width: 12rem;
height: 12rem;
}
.text {
font-family: Arial;
font-weight: 400;
color: #585858;
font-size: 2.4rem;
}
.tips{
font-family: Arial;
font-weight: 400;
font-size: 1.8rem;
color: #aaa;
}
}
}
</style>

View File

@@ -2,41 +2,103 @@
<div class="award-container"> <div class="award-container">
<div class="header flex align-center space-between"> <div class="header flex align-center space-between">
<div class="header-left"> <div class="header-left">
<img src="@/assets/images/award/code_create_logo.png" class="logo" /> <img
src="@/assets/images/award/code_create_logo.png"
class="logo"
/>
</div> </div>
<div class="header-right flex align-center"> <div class="header-right flex align-center">
<div class="text">Submit your Application</div> <div class="text">Submit your Application</div>
<img src="@/assets/images/award/arrow.png" alt="" class="arrow" /> <img
src="@/assets/images/award/arrow.png"
alt=""
class="arrow"
/>
</div> </div>
</div> </div>
<RouterView /> <router-view />
<div class="footer flex space-between align-center"> <div class="footer flex space-between align-center">
<div class="social-list flex"> <div class="social-list flex">
<a href="https://xhslink.com/m/5Ony2FapizV" target="_blank"> <a
<img src="@/assets/images/award/xiaohongshu.svg" alt="" /> href="https://xhslink.com/m/5Ony2FapizV"
target="_blank"
>
<img
src="@/assets/images/award/xiaohongshu.svg"
alt=""
/>
</a> </a>
<a href="https://www.linkedin.com/company/code-create-limited" target="_blank"> <a
<img src="@/assets/images/award/linkdin.svg" alt="" /> href="https://www.linkedin.com/company/code-create-limited"
target="_blank"
>
<img
src="@/assets/images/award/linkdin.svg"
alt=""
/>
</a> </a>
<a href="https://www.facebook.com/CodeCreateAI" target="_blank"> <a
<img src="@/assets/images/award/facebook.svg" alt="" /> href="https://www.facebook.com/CodeCreateAI"
target="_blank"
>
<img
src="@/assets/images/award/facebook.svg"
alt=""
/>
</a> </a>
<a href="https://www.tiktok.com/@aida_codecreate" target="_blank"> <a
<img src="@/assets/images/award/tiktok.svg" alt="" /> href="https://www.tiktok.com/@aida_codecreate"
target="_blank"
>
<img
src="@/assets/images/award/tiktok.svg"
alt=""
/>
</a> </a>
<a href="https://www.tiktok.com/@aida_codecreate" target="_blank"> <a
<img src="@/assets/images/award/weichat.svg" alt="" /> href="javascript:void(0)"
@click="showQRcode = true"
>
<img
src="@/assets/images/award/weichat.svg"
alt=""
/>
</a> </a>
</div> </div>
<div class="copyright">© Code-Create 2026</div> <div class="copyright">© Code-Create 2026</div>
</div> </div>
<div
class="qrcode-mask flex flex-center"
v-if="showQRcode"
>
<div class="code-wrapper flex flex-col align-center">
<img
src="@/assets/images/award/close.svg"
class="close-icon"
@click="handleCloseQRcode"
/>
<div class="code-title">WeChat Official Account</div>
<img
src="@/assets/images/award/qrcode.jpg"
class="qrcode"
/>
<div class="tips">Scan the QR code in WeChat</div>
</div>
</div>
</div> </div>
</template> </template>
<script setup lang="ts"></script> <script setup lang="ts">
import { ref } from 'vue'
const showQRcode = ref(false)
const handleCloseQRcode = () => {
showQRcode.value = false
}
</script>
<style lang="less" scoped> <style lang="less" scoped>
.award-container { .award-container {
overflow: auto; overflow: auto;
height: 100vh; height: 100vh;
// 隐藏滚动条箭头,只显示滚动条本体 // 隐藏滚动条箭头,只显示滚动条本体
@@ -47,8 +109,8 @@
} }
scrollbar-width: none; scrollbar-width: none;
-ms-overflow-style: none; -ms-overflow-style: none;
} }
.header { .header {
height: 8rem; height: 8rem;
background-color: #232323; background-color: #232323;
padding-left: 21.5rem; padding-left: 21.5rem;
@@ -70,8 +132,8 @@
height: 2.4rem; height: 2.4rem;
} }
} }
} }
.footer { .footer {
height: 10rem; height: 10rem;
padding-left: 21.5rem; padding-left: 21.5rem;
padding-right: 22rem; padding-right: 22rem;
@@ -89,5 +151,46 @@
font-weight: 400; font-weight: 400;
font-size: 1.2rem; font-size: 1.2rem;
} }
} }
.qrcode-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.45);
.code-wrapper {
width: 60rem;
height: 49.4rem;
background-color: #fff;
position: relative;
border-radius: 0.8rem;
padding-top: 6rem;
.close-icon {
width: 2.4rem;
height: 2.4rem;
position: absolute;
top: 2rem;
right: 2rem;
cursor: pointer;
}
.code-title {
font-family: 'PoppinsBold';
font-weight: 600;
font-size: 3rem;
color: #232323;
}
.qrcode {
width: 25.8rem;
height: 25.8rem;
margin: 3rem 0 1rem;
}
.tips {
font-family: Arial;
font-weight: 400;
font-size: 1.4rem;
color: #585858;
}
}
}
</style> </style>

View File

@@ -1,9 +1,16 @@
<template> <template>
<div class="award-page"> <div class="award-page">
<div class="banner"> <div class="banner">
<div class="submit-btn flex flex-center" @click="handleSubmitApplication"> <div
class="submit-btn flex flex-center"
@click="handleSubmitApplication"
>
<div>Submit your Application</div> <div>Submit your Application</div>
<img src="@/assets/images/award/arrow_right.png" alt="" class="arrow" /> <img
src="@/assets/images/award/arrow_right.png"
alt=""
class="arrow"
/>
<div class="ddl">Application Deadline:15th March 2026</div> <div class="ddl">Application Deadline:15th March 2026</div>
</div> </div>
</div> </div>
@@ -19,40 +26,58 @@
</div> </div>
<div class="block-item flex flex-col flex-center"> <div class="block-item flex flex-col flex-center">
<div class="number"> <div class="number">
<img src="@/assets/images/award/∞.png" alt="" class="infinity" /> <img
src="@/assets/images/award/∞.png"
alt=""
class="infinity"
/>
</div> </div>
<div class="label">Possibilites</div> <div class="label">Possibilites</div>
</div> </div>
</div> </div>
<div class="bloom container flex flex-col align-center"> <div class="bloom container flex flex-col align-center">
<div class="title">Bloom Your Creativity</div> <div class="title">Bloom Your Creativity</div>
<img src="@/assets/images/award/bloom_logo.png" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
class="logo"
/>
<div class="season">Theme of 2026</div> <div class="season">Theme of 2026</div>
<div class="desc"> <div class="desc">
Where imagination meets innovation, creativity blooms. This theme celebrates AI as Where imagination meets innovation, creativity blooms. This theme
a catalyst for fashion design, allowing your vision to flourish beyond traditional celebrates AI as a catalyst for fashion design, allowing your vision to
boundaries. Let your ideas blossom into extraordinary designs that merge human flourish beyond traditional boundaries. Let your ideas blossom into
artistry with artificial intelligence. extraordinary designs that merge human artistry with artificial
intelligence.
</div> </div>
</div> </div>
<div class="design-container container"> <div class="design-container container">
<div class="design-title limit">Design Without Borders</div> <div class="design-title limit">Design Without Borders</div>
<div class="limit"> <div class="limit">
<img src="@/assets/images/award/bloom_logo.png" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
class="logo"
/>
</div> </div>
<div class="global limit">Global Opportunity</div> <div class="global limit">Global Opportunity</div>
<div class="desc"> <div class="desc">
Open to visionary designers across the globe. From Seoul to Singapore, New York to Open to visionary designers across the globe. From Seoul to Singapore, New
Shanghai, we're seeking the next generation of fashion innovators who dare to York to Shanghai, we're seeking the next generation of fashion innovators
reimagine the future of design. who dare to reimagine the future of design.
</div> </div>
</div> </div>
<div class="timeline-container container flex flex-col align-center"> <div class="timeline-container container flex flex-col align-center">
<div class="timeline-title">Competition Timeline</div> <div class="timeline-title">Competition Timeline</div>
<img src="@/assets/images/award/bloom_logo.png" alt="" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
alt=""
class="logo"
/>
<div class="desc">Shaping the Future</div> <div class="desc">Shaping the Future</div>
<div class="timeline-point"> <div class="timeline-point">
<img src="@/assets/images/award/timeline_line.png" class="line-bg" /> <img
src="@/assets/images/award/timeline_line.png"
class="line-bg"
/>
<div class="labels-row flex align-center"> <div class="labels-row flex align-center">
<div <div
class="item-label flex flex-col" class="item-label flex flex-col"
@@ -60,7 +85,12 @@
:key="'label-' + item.time" :key="'label-' + item.time"
> >
<div class="main-label">{{ item.label }}</div> <div class="main-label">{{ item.label }}</div>
<div class="sub-label" v-if="item.subLabel">{{ item.subLabel }}</div> <div
class="sub-label"
v-if="item.subLabel"
>
{{ item.subLabel }}
</div>
</div> </div>
</div> </div>
<!-- Icons row --> <!-- Icons row -->
@@ -76,7 +106,11 @@
<!-- Times row --> <!-- Times row -->
<div class="times-row flex align-center"> <div class="times-row flex align-center">
<div class="item-time" v-for="item in points" :key="'time-' + item.time"> <div
class="item-time"
v-for="item in points"
:key="'time-' + item.time"
>
{{ item.time }} {{ item.time }}
</div> </div>
</div> </div>
@@ -97,7 +131,10 @@
<div class="prizes-container container flex align-center"> <div class="prizes-container container flex align-center">
<div class="left flex flex-col flex-center"> <div class="left flex flex-col flex-center">
<div class="title">Award & Prizes</div> <div class="title">Award & Prizes</div>
<img src="@/assets/images/award/bloom_logo.png" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
class="logo"
/>
<div class="desc">Recongnition</div> <div class="desc">Recongnition</div>
</div> </div>
<div class="right"> <div class="right">
@@ -109,7 +146,12 @@
<div class="prize-money">{{ item.money }}</div> <div class="prize-money">{{ item.money }}</div>
<div class="prize-name">{{ item.name }}</div> <div class="prize-name">{{ item.name }}</div>
<div class="prize-desc flex flex-col flex-center"> <div class="prize-desc flex flex-col flex-center">
<div class="desc-item" v-for="el in item.desc">{{ el }}</div> <div
class="desc-item"
v-for="el in item.desc"
>
{{ el }}
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -119,22 +161,42 @@
<div class="sub-title">Requirments</div> <div class="sub-title">Requirments</div>
<div class="requirments-list flex"> <div class="requirments-list flex">
<div class="left flex flex-col space-between"> <div class="left flex flex-col space-between">
<div class="item-box" v-for="item in leftRequirment" :key="item.type"> <div
class="item-box"
v-for="item in leftRequirment"
:key="item.type"
>
<div class="item-header flex align-center"> <div class="item-header flex align-center">
<img src="@/assets/images/award/bloom_logo.png" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
class="logo"
/>
<div class="item-title">{{ item.type }}</div> <div class="item-title">{{ item.type }}</div>
</div> </div>
<div class="context" v-for="el in item.desc">{{ el }}</div> <div
class="context"
v-for="el in item.desc"
>
{{ el }}
</div>
</div> </div>
</div> </div>
<div class="right"> <div class="right">
<div class="item-box"> <div class="item-box">
<div class="item-box"> <div class="item-box">
<div class="item-header flex align-center"> <div class="item-header flex align-center">
<img src="@/assets/images/award/bloom_logo.png" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
class="logo"
/>
<div class="item-title">{{ rightRequirment.type }}</div> <div class="item-title">{{ rightRequirment.type }}</div>
</div> </div>
<div class="context" v-for="el in rightRequirment.desc">{{ el }}</div> <div
class="context"
v-for="el in rightRequirment.desc"
>
{{ el }}
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -142,7 +204,10 @@
</div> </div>
<div class="selection-container container flex flex-col align-center"> <div class="selection-container container flex flex-col align-center">
<div class="title">Selection Criteria</div> <div class="title">Selection Criteria</div>
<img src="@/assets/images/award/bloom_logo.png" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
class="logo"
/>
<div class="sub-title">Evaluation</div> <div class="sub-title">Evaluation</div>
<div class="criteria-list flex"> <div class="criteria-list flex">
<div <div
@@ -150,7 +215,11 @@
v-for="item in criteriaList" v-for="item in criteriaList"
:key="item.name" :key="item.name"
> >
<img :src="item.icon" class="icon" :style="item.style" /> <img
:src="item.icon"
class="icon"
:style="item.style"
/>
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
<div class="desc">{{ item.desc }}</div> <div class="desc">{{ item.desc }}</div>
</div> </div>
@@ -158,7 +227,10 @@
</div> </div>
<div class="judges-container flex flex-col align-center"> <div class="judges-container flex flex-col align-center">
<div class="title">Panel of Judges</div> <div class="title">Panel of Judges</div>
<img src="@/assets/images/award/bloom_logo.png" class="logo" /> <img
src="@/assets/images/award/bloom_logo.png"
class="logo"
/>
<div class="sub-title">Expertise</div> <div class="sub-title">Expertise</div>
<div class="judgement-list"> <div class="judgement-list">
<div <div
@@ -166,7 +238,10 @@
v-for="item in judgements" v-for="item in judgements"
:key="item.name" :key="item.name"
> >
<img :src="item.picture" class="picture" /> <img
:src="item.picture"
class="picture"
/>
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
<div class="desc">{{ item.desc }}</div> <div class="desc">{{ item.desc }}</div>
</div> </div>
@@ -176,27 +251,27 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import criteria1 from '@/assets/images/award/criteria_1.png' import criteria1 from '@/assets/images/award/criteria_1.png'
import criteria2 from '@/assets/images/award/criteria_2.png' import criteria2 from '@/assets/images/award/criteria_2.png'
import criteria3 from '@/assets/images/award/criteria_3.png' import criteria3 from '@/assets/images/award/criteria_3.png'
import criteria4 from '@/assets/images/award/criteria_4.png' import criteria4 from '@/assets/images/award/criteria_4.png'
import jae from '@/assets/images/award/jae.png' import jae from '@/assets/images/award/jae.png'
import diego from '@/assets/images/award/diego.png' import diego from '@/assets/images/award/diego.png'
import gregory from '@/assets/images/award/gregory.png' import gregory from '@/assets/images/award/gregory.png'
import vincenzo from '@/assets/images/award/vincenzo.png' import vincenzo from '@/assets/images/award/vincenzo.png'
import tim from '@/assets/images/award/tim.png' import tim from '@/assets/images/award/tim.png'
import desmond from '@/assets/images/award/desmond.png' import desmond from '@/assets/images/award/desmond.png'
const router = useRouter() const router = useRouter()
const handleSubmitApplication = () => { const handleSubmitApplication = () => {
router.push('/award/apply') router.push('/award/apply')
} }
const blocksList = ref([ const blocksList = ref([
{ {
number: '100', number: '100',
label: 'Semi-finalists' label: 'Semi-finalists'
@@ -209,9 +284,9 @@ const blocksList = ref([
number: '3', number: '3',
label: 'Winners' label: 'Winners'
} }
]) ])
const points = ref([ const points = ref([
{ {
label: 'Select Top 20', label: 'Select Top 20',
time: 'May', time: 'May',
@@ -234,9 +309,9 @@ const points = ref([
time: 'November', time: 'November',
desc: 'Winners revealed with media coverage and live showcase.' desc: 'Winners revealed with media coverage and live showcase.'
} }
]) ])
const prizes = ref([ const prizes = ref([
{ {
money: '$3000', money: '$3000',
name: 'First Runner-Up', name: 'First Runner-Up',
@@ -257,9 +332,9 @@ const prizes = ref([
name: 'Finalists', name: 'Finalists',
desc: ['Award Ceritificate', 'Global Media Exposure'] desc: ['Award Ceritificate', 'Global Media Exposure']
} }
]) ])
const leftRequirment = ref([ const leftRequirment = ref([
{ {
type: 'Video', type: 'Video',
desc: ['The process of doing design'] desc: ['The process of doing design']
@@ -271,8 +346,8 @@ const leftRequirment = ref([
'Design sketch: Maximum 4 outfit design with proposed materials' 'Design sketch: Maximum 4 outfit design with proposed materials'
] ]
} }
]) ])
const rightRequirment = ref({ const rightRequirment = ref({
type: 'Submission Format', type: 'Submission Format',
desc: [ desc: [
'Naming as AiDA global award 2026_applicantname', 'Naming as AiDA global award 2026_applicantname',
@@ -280,9 +355,9 @@ const rightRequirment = ref({
'Single PDF file\n(within 15 pages, maximum 20mb)', 'Single PDF file\n(within 15 pages, maximum 20mb)',
'English or native language\nwith English translation' 'English or native language\nwith English translation'
] ]
}) })
const criteriaList = ref([ const criteriaList = ref([
{ {
icon: criteria1, icon: criteria1,
name: 'Originality', name: 'Originality',
@@ -307,9 +382,9 @@ const criteriaList = ref([
desc: 'Quality of presentation and technical craftsmanship', desc: 'Quality of presentation and technical craftsmanship',
style: { width: '18.8rem', height: '18rem' } style: { width: '18.8rem', height: '18rem' }
} }
]) ])
const judgements = [ const judgements = [
{ {
picture: jae, picture: jae,
name: 'Jae Hyuk Lim', name: 'Jae Hyuk Lim',
@@ -340,42 +415,19 @@ const judgements = [
name: 'Desmond Lim', name: 'Desmond Lim',
desc: 'Cheif Editor of Vogue\n(Singapore)' desc: 'Cheif Editor of Vogue\n(Singapore)'
} }
] ]
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.container {
.container {
height: 97rem; height: 97rem;
} }
// .header {
// height: 8rem; .logo {
// background-color: #232323;
// padding-left: 21.5rem;
// padding-right: 8.6rem;
// .header-left {
// .logo {
// width: 13rem;
// height: 5rem;
// }
// }
// .header-right {
// column-gap: 1rem;
// .text {
// font-size: 1.6rem;
// color: #fff;
// }
// .arrow {
// width: 2.4rem;
// height: 2.4rem;
// }
// }
// }
.logo {
width: 2.4rem; width: 2.4rem;
height: 2.4rem; height: 2.4rem;
} }
.banner { .banner {
height: 108rem; height: 108rem;
background: url('@/assets/images/award/banner.png') no-repeat; background: url('@/assets/images/award/banner.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
@@ -415,8 +467,8 @@ const judgements = [
line-height: 2.2rem; line-height: 2.2rem;
} }
} }
} }
.blocks-list { .blocks-list {
height: 31.4rem; height: 31.4rem;
background: linear-gradient(98.55deg, #232323 18.22%, #898989 101.1%); background: linear-gradient(98.55deg, #232323 18.22%, #898989 101.1%);
@@ -444,8 +496,8 @@ const judgements = [
background-color: #8d8d8d; background-color: #8d8d8d;
} }
} }
} }
.bloom { .bloom {
padding-top: 12.8rem; padding-top: 12.8rem;
font-family: 'Poppins'; font-family: 'Poppins';
background: url('@/assets/images/award/bloom_bg.png') no-repeat; background: url('@/assets/images/award/bloom_bg.png') no-repeat;
@@ -472,8 +524,8 @@ const judgements = [
line-height: 4.5rem; line-height: 4.5rem;
margin-bottom: 12.3rem; margin-bottom: 12.3rem;
} }
} }
.design-container { .design-container {
background: url('@/assets/images/award/design_bg.png') no-repeat; background: url('@/assets/images/award/design_bg.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
padding-left: 21.5rem; padding-left: 21.5rem;
@@ -508,8 +560,8 @@ const judgements = [
color: #e0e0e0; color: #e0e0e0;
width: 54rem; width: 54rem;
} }
} }
.timeline-container { .timeline-container {
background: url('@/assets/images/award/timeline_bg.png') no-repeat; background: url('@/assets/images/award/timeline_bg.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
position: relative; position: relative;
@@ -624,8 +676,8 @@ const judgements = [
} }
} }
} }
} }
.prizes-container { .prizes-container {
background: url('@/assets/images/award/prizes_bg.png') no-repeat; background: url('@/assets/images/award/prizes_bg.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
padding: 0 21.4rem 0 33.4rem; padding: 0 21.4rem 0 33.4rem;
@@ -671,7 +723,8 @@ const judgements = [
background-size: 100% 100%; background-size: 100% 100%;
} }
&:nth-of-type(4) { &:nth-of-type(4) {
background: url('@/assets/images/award/certification_bg.png') no-repeat; background: url('@/assets/images/award/certification_bg.png')
no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
} }
.prize-money { .prize-money {
@@ -694,8 +747,8 @@ const judgements = [
} }
} }
} }
} }
.apply-container { .apply-container {
flex: 1; flex: 1;
background: url('@/assets/images/award/timeline_bg.png') no-repeat; background: url('@/assets/images/award/timeline_bg.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
@@ -747,8 +800,8 @@ const judgements = [
} }
} }
} }
} }
.selection-container { .selection-container {
background: url('@/assets/images/award/selection_bg.png') no-repeat; background: url('@/assets/images/award/selection_bg.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
padding-top: 9.3rem; padding-top: 9.3rem;
@@ -798,8 +851,8 @@ const judgements = [
} }
} }
} }
} }
.judges-container { .judges-container {
height: 147.4rem; height: 147.4rem;
background: url('@/assets/images/award/judges_bg.png') no-repeat; background: url('@/assets/images/award/judges_bg.png') no-repeat;
background-size: 100% 100%; background-size: 100% 100%;
@@ -849,8 +902,8 @@ const judgements = [
} }
} }
} }
} }
.footer { .footer {
height: 10rem; height: 10rem;
padding-left: 21.5rem; padding-left: 21.5rem;
padding-right: 22rem; padding-right: 22rem;
@@ -868,5 +921,5 @@ const judgements = [
font-weight: 400; font-weight: 400;
font-size: 1.2rem; font-size: 1.2rem;
} }
} }
</style> </style>