feat: 参赛表单页面i18n
This commit is contained in:
102
src/lang/cn.ts
102
src/lang/cn.ts
@@ -1850,14 +1850,108 @@ export default {
|
|||||||
awardCeremonyDesc: '颁奖盛典与设计师社\n群聚会 – Soho House',
|
awardCeremonyDesc: '颁奖盛典与设计师社\n群聚会 – Soho House',
|
||||||
submissionSuccessful: '提交成功',
|
submissionSuccessful: '提交成功',
|
||||||
submissionSuccessfulDesc:
|
submissionSuccessfulDesc:
|
||||||
'请在AiDA平台消息中查看您提交的信息。\n如需要,您可以编辑。竞赛更新和结果将通过邮件发送。',
|
'请在 AiDA 平台内的消息中查看您提交的信息。如有需要,您可以进行修改。\n比赛的最新消息和结果将通过邮箱发送。',
|
||||||
deadlinePassed: '申请截止日期已过',
|
deadlinePassed: '申请截止日期已过',
|
||||||
deadlinePassedDesc:
|
deadlinePassedDesc:
|
||||||
'AiDA全球时尚大奖2026的提交截止日期已结束。\n我们不再接受新的申请。',
|
'AiDA 全球设计奖 2026 的作品提交已截止。\n我们不再接受新的报名。',
|
||||||
uploadInProgress: '上传中…',
|
uploadInProgress: '上传中…',
|
||||||
uploadSuccess: '上传成功',
|
uploadSuccess: '上传成功',
|
||||||
uploadFailed: '上传失败',
|
uploadFailed: '上传失败',
|
||||||
pdfFileTip: 'PDF文件,最大20MB',
|
pdfFileTip: 'PDF文件,不超过20MB',
|
||||||
videoFileTip: '视频文件(MP4, MOV),1080p,最大100MB'
|
videoFileTip: '视频文件(MP4, MOV),1080p,不超过100MB'
|
||||||
|
},
|
||||||
|
AwardApply: {
|
||||||
|
// 页面主标题区域
|
||||||
|
applicationForm: '参赛表格',
|
||||||
|
emailVerification: '邮箱验证',
|
||||||
|
aidaUsersOnly: '仅限 AiDA 用户',
|
||||||
|
slogan: '绽放你的创意 • AiDA 全球时设计奖 2026',
|
||||||
|
// 邮箱验证部分
|
||||||
|
emailAddress: '邮箱',
|
||||||
|
sendCode: '发送验证码',
|
||||||
|
pleaseUseRegisteredEmail: '请使用您在 AiDA 注册的邮箱',
|
||||||
|
// 个人信息部分
|
||||||
|
personalInformation: '个人信息',
|
||||||
|
tellUsAboutYourself: '自我介绍',
|
||||||
|
firstName: '名',
|
||||||
|
lastName: '姓',
|
||||||
|
gender: '性别',
|
||||||
|
occupation: '职业',
|
||||||
|
age: '年龄',
|
||||||
|
countryRegionCity: '国家或地区及城市',
|
||||||
|
phoneNumber: '电话号码',
|
||||||
|
portfolioUrl: '作品集网址或Instagram(可选)',
|
||||||
|
// 性别选项
|
||||||
|
male: '男',
|
||||||
|
female: '女',
|
||||||
|
other: '其他',
|
||||||
|
// 设计信息部分
|
||||||
|
designInformation: '作品信息',
|
||||||
|
shareYourCreativeVision: '分享您的创意构想',
|
||||||
|
designTitle: '作品标题',
|
||||||
|
designDescription: '设计说明',
|
||||||
|
designDescriptionPlaceholder: '请简要描述您的设计理念、灵感和创意方向...',
|
||||||
|
// 提交文件部分
|
||||||
|
submissionFiles: '作品上传',
|
||||||
|
uploadYourDesignMaterials: '上传你的设计材料',
|
||||||
|
submissionRequirements: '提交要求',
|
||||||
|
pdfRequirement: `单独PDF文件\n 作品标题、灵感板及情绪板,设计说明\n+ 4套服装设计及材料说明(页数:最多15页)`,
|
||||||
|
rightContent: {
|
||||||
|
format: '格式:单个 PDF 文件,最多15页,最大 20MB',
|
||||||
|
video: `视频:创作过程,分辨率1080×1920 像素(9:16 纵向比例),最长 60 秒`
|
||||||
|
},
|
||||||
|
// PDF 上传
|
||||||
|
uploadPdfTitle: '您在设计过程中如何使用 AiDA?',
|
||||||
|
clickToUploadPdf: '点击选择或拖拽文件上传',
|
||||||
|
pdfFileLimit: 'PDF 文件,不超过 20MB',
|
||||||
|
// 视频上传
|
||||||
|
uploadVideoTitle: '您在设计过程中如何使用 AiDA?',
|
||||||
|
clickToUploadVideo: '点击选择或拖拽文件上传',
|
||||||
|
videoFileLimit: '视频文件(MP4, MOV),1080P,不超过100MB',
|
||||||
|
// 条款与条件
|
||||||
|
termsAndConditions: '参赛条款',
|
||||||
|
conditionFirst: '我确认所提交的作品均为原创,且由我本人独立创作。',
|
||||||
|
conditionSecond:
|
||||||
|
'我知悉 Code-Create 对提交的所有设计及视频享有市场宣传和推广权利。',
|
||||||
|
conditionThird: '我同意在入围决赛后参加相关活动,包括 AiDA 培训及颁奖典礼。',
|
||||||
|
conditionFourth: '我希望接收有关 AiDA 产品及未来比赛的最新信息。(可选)',
|
||||||
|
// 提交按钮
|
||||||
|
submitYourDesign: '提交作品',
|
||||||
|
unfinishedFormTip: 'AiDA 平台内消息中的链接可保存您未完成的表单。',
|
||||||
|
// 验证码弹窗
|
||||||
|
checkYourEmail: '请查看您的邮箱',
|
||||||
|
enterSixDigitCode: '请输入发送到邮箱的 6 位验证码',
|
||||||
|
verify: '验证',
|
||||||
|
resendCode: '重新发送',
|
||||||
|
resendCodeIn: '重新发送',
|
||||||
|
// 验证消息
|
||||||
|
verificationSuccess: '验证成功!',
|
||||||
|
pleaseVerifyEmailFirst: '请先验证您的邮箱',
|
||||||
|
pleaseCheckTerms: '请勾选条款与条件',
|
||||||
|
pleaseFillRequiredFields: '请填写所有必填项',
|
||||||
|
pleaseEnterCompleteCode: '请输入完整的6位验证码',
|
||||||
|
// 上传状态
|
||||||
|
fileUploadedSuccess: '文件上传成功。',
|
||||||
|
fileUploadFailed: '文件上传失败。',
|
||||||
|
// 验证器消息
|
||||||
|
pleaseInputEmail: '请输入邮箱地址',
|
||||||
|
pleaseInputValidEmail: '请输入有效的邮箱地址',
|
||||||
|
pleaseInputFirstName: '请输入您的名',
|
||||||
|
pleaseInputLastName: '请输入您的姓',
|
||||||
|
pleaseSelectGender: '请选择您的性别',
|
||||||
|
pleaseInputOccupation: '请输入您的职业',
|
||||||
|
pleaseInputAge: '请输入您的年龄',
|
||||||
|
pleaseInputCountry: '请输入您的国家/地区及城市',
|
||||||
|
pleaseInputPhoneNumber: '请输入您的电话号码',
|
||||||
|
pleaseInputValidPhone: '请输入有效的电话号码',
|
||||||
|
pleaseInputDigits: '请输入数字',
|
||||||
|
pleaseInputDesignTitle: '请输入您的作品标题',
|
||||||
|
pleaseInputDesignDescription: '请输入您的设计说明',
|
||||||
|
pleaseUploadPdf: '请上传您的PDF文件',
|
||||||
|
pleaseUploadVideo: '请上传您的视频文件',
|
||||||
|
uploadPdfOnly: '请仅上传 PDF 文件。',
|
||||||
|
uploadVideoOnly: '请仅上传 MP4 或 MOV 文件。',
|
||||||
|
fileSizeExceeds: '文件大小超过 {sizeLimit} 限制。请上传较小的文件。',
|
||||||
|
uploadFailed: '上传失败'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1927,5 +1927,98 @@ export default {
|
|||||||
uploadFailed: 'Upload failed',
|
uploadFailed: 'Upload failed',
|
||||||
pdfFileTip: 'PDF file, max 20MB',
|
pdfFileTip: 'PDF file, max 20MB',
|
||||||
videoFileTip: 'Video file (MP4, MOV), 1080p, max 100MB'
|
videoFileTip: 'Video file (MP4, MOV), 1080p, max 100MB'
|
||||||
|
},
|
||||||
|
AwardApply: {
|
||||||
|
// 页面主标题区域
|
||||||
|
applicationForm: 'Application Form',
|
||||||
|
emailVerification: 'Email Verification',
|
||||||
|
aidaUsersOnly: 'AiDA Users Only',
|
||||||
|
slogan: 'BLOOM YOUR CREATIVITY • AiDA GLOBAL FASHION AWARD 2026',
|
||||||
|
// 邮箱验证部分
|
||||||
|
emailAddress: 'Email Address',
|
||||||
|
sendCode: 'Send Code',
|
||||||
|
pleaseUseRegisteredEmail: 'Please use the email address you registered with AiDA.',
|
||||||
|
// 个人信息部分
|
||||||
|
personalInformation: 'Personal Information',
|
||||||
|
tellUsAboutYourself: 'Tell us about yourself',
|
||||||
|
firstName: 'First Name',
|
||||||
|
lastName: 'Last Name',
|
||||||
|
gender: 'Gender',
|
||||||
|
occupation: 'Occupation',
|
||||||
|
age: 'Age',
|
||||||
|
countryRegionCity: 'Country/Region and City',
|
||||||
|
phoneNumber: 'Phone Number',
|
||||||
|
portfolioUrl: 'Portfolio Website/Instagram (Optional)',
|
||||||
|
// 性别选项
|
||||||
|
male: 'Male',
|
||||||
|
female: 'Female',
|
||||||
|
other: 'Other',
|
||||||
|
// 设计信息部分
|
||||||
|
designInformation: 'Design Information',
|
||||||
|
shareYourCreativeVision: 'Share your creative vision',
|
||||||
|
designTitle: 'Design Title',
|
||||||
|
designDescription: 'Design description',
|
||||||
|
designDescriptionPlaceholder: 'Briefly describe your design concept, inspiration, and creative direction...',
|
||||||
|
// 提交文件部分
|
||||||
|
submissionFiles: 'Submission Files',
|
||||||
|
uploadYourDesignMaterials: 'Upload your design materials',
|
||||||
|
submissionRequirements: 'Submission Requirements',
|
||||||
|
pdfRequirement: `Single PDF file\n Title, mood board, elaboration\n+ 4 outfit design with materials (max 15 pages)`,
|
||||||
|
rightContent: {
|
||||||
|
format: 'Format: Single PDF file, 15 pages, maximum 20MB',
|
||||||
|
video: `Video: Design process, 1080×1920 pixels (9:16 ratio), maximum 60 seconds`
|
||||||
|
},
|
||||||
|
// PDF 上传
|
||||||
|
uploadPdfTitle: 'How will you use AiDA in your design process?',
|
||||||
|
clickToUploadPdf: 'Click to upload or drag and drop',
|
||||||
|
pdfFileLimit: 'PDF file, max 20MB',
|
||||||
|
// 视频上传
|
||||||
|
uploadVideoTitle: 'How will you use AiDA in your design process?',
|
||||||
|
clickToUploadVideo: 'Click to upload or drag and drop',
|
||||||
|
videoFileLimit: 'Video file (MP4, MOV), 1080p, max 100MB',
|
||||||
|
// 条款与条件
|
||||||
|
termsAndConditions: 'Terms & Conditions',
|
||||||
|
conditionFirst: 'I confirm that all submitted work is original and created by me.',
|
||||||
|
conditionSecond: 'I understand that Code-Create has marketing and promotional rights to all submitted designs and videos.',
|
||||||
|
conditionThird: 'I agree to participate in finalist activities if selected, including AiDA training and award ceremony.',
|
||||||
|
conditionFourth: 'I would like to receive updates about AiDA products and future competitions. (Optional)',
|
||||||
|
// 提交按钮
|
||||||
|
submitYourDesign: 'Submit your Design',
|
||||||
|
unfinishedFormTip: 'The link in the AiDA in-platform message will save your unfinished form.',
|
||||||
|
// 验证码弹窗
|
||||||
|
checkYourEmail: 'Check your email',
|
||||||
|
enterSixDigitCode: 'Enter the 6-digit code sent to',
|
||||||
|
verify: 'Verify',
|
||||||
|
resendCode: 'Resend',
|
||||||
|
resendCodeIn: 'Resend Code in',
|
||||||
|
// 验证消息
|
||||||
|
verificationSuccess: 'Verification successful!',
|
||||||
|
pleaseVerifyEmailFirst: 'Please verify your email first',
|
||||||
|
pleaseCheckTerms: 'Please check the terms and conditions',
|
||||||
|
pleaseFillRequiredFields: 'Please fill in all the required fields',
|
||||||
|
pleaseEnterCompleteCode: 'Please enter the complete 6-digit verification code',
|
||||||
|
// 上传状态
|
||||||
|
fileUploadedSuccess: '{fileName} file uploaded successfully.',
|
||||||
|
fileUploadFailed: '{fileName} file upload failed.',
|
||||||
|
// 验证器消息
|
||||||
|
pleaseInputEmail: 'Please input the email address',
|
||||||
|
pleaseInputValidEmail: 'Please input a valid email address',
|
||||||
|
pleaseInputFirstName: 'Please input your first name',
|
||||||
|
pleaseInputLastName: 'Please input your last name',
|
||||||
|
pleaseSelectGender: 'Please select your gender',
|
||||||
|
pleaseInputOccupation: 'Please input your occupation',
|
||||||
|
pleaseInputAge: 'Please input your age',
|
||||||
|
pleaseInputCountry: 'Please input your country/region and city',
|
||||||
|
pleaseInputPhoneNumber: 'Please enter your phone number.',
|
||||||
|
pleaseInputValidPhone: 'Please enter a valid phone number.',
|
||||||
|
pleaseInputDigits: 'Please enter digits only',
|
||||||
|
pleaseInputDesignTitle: 'Please input your design title',
|
||||||
|
pleaseInputDesignDescription: 'Please input your design description',
|
||||||
|
pleaseUploadPdf: 'Please upload your PDF',
|
||||||
|
pleaseUploadVideo: 'Please upload your video',
|
||||||
|
uploadPdfOnly: 'Please upload a PDF file only.',
|
||||||
|
uploadVideoOnly: 'Please upload a MP4 or MOV file only.',
|
||||||
|
fileSizeExceeds: 'File size exceeds {sizeLimit} limit. Please upload a smaller file.',
|
||||||
|
uploadFailed: 'Upload failed'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
<div class="apply-container">
|
<div class="apply-container">
|
||||||
<div class="banner">
|
<div class="banner">
|
||||||
<div class="slogan">
|
<div class="slogan">
|
||||||
BLOOM YOUR CREATIVITY • AiDA GLOBAL FASHION AWARD 2026
|
{{ t('AwardApply.slogan') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="title poppins-medium">Application Form</div>
|
<div class="title poppins-medium">{{ t('AwardApply.applicationForm') }}</div>
|
||||||
<div
|
<div
|
||||||
class="form-header"
|
class="form-header"
|
||||||
v-if="!isCompleted && !isExpired"
|
v-if="!isCompleted && !isExpired"
|
||||||
>
|
>
|
||||||
<div class="form-title poppins-bold">Email Verification</div>
|
<div class="form-title poppins-bold">{{ t('AwardApply.emailVerification') }}</div>
|
||||||
<div class="desc">AiDA Users Only</div>
|
<div class="desc">{{ t('AwardApply.aidaUsersOnly') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Success
|
<Success
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<a-form-item
|
<a-form-item
|
||||||
name="email"
|
name="email"
|
||||||
required
|
required
|
||||||
label="Email Address"
|
:label="t('AwardApply.emailAddress')"
|
||||||
>
|
>
|
||||||
<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" />
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
{{
|
{{
|
||||||
isCountingDown
|
isCountingDown
|
||||||
? formatCountdown(countdown)
|
? formatCountdown(countdown)
|
||||||
: 'Send Code'
|
: t('AwardApply.sendCode')
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
@@ -58,13 +58,13 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="tips">
|
<div class="tips">
|
||||||
Please use the email address you registered with AiDA.
|
{{ t('AwardApply.pleaseUseRegisteredEmail') }}
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row full-row">
|
<div class="form-row full-row">
|
||||||
<div class="form-title poppins-bold">Personal Information</div>
|
<div class="form-title poppins-bold">{{ t('AwardApply.personalInformation') }}</div>
|
||||||
<div class="desc">Tell us about yourself</div>
|
<div class="desc">{{ t('AwardApply.tellUsAboutYourself') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="user-info flex">
|
<div class="user-info flex">
|
||||||
<template
|
<template
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
<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="getFieldLabel(item.key)"
|
||||||
:name="item.key"
|
:name="item.key"
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
<a-select
|
<a-select
|
||||||
:disabled="readOnly"
|
:disabled="readOnly"
|
||||||
v-model:value="form[item.key]"
|
v-model:value="form[item.key]"
|
||||||
:options="genderOptions"
|
:options="getGenderOptions()"
|
||||||
>
|
>
|
||||||
<template #suffixIcon>
|
<template #suffixIcon>
|
||||||
<!-- <img
|
<!-- <img
|
||||||
@@ -109,13 +109,13 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row full-row">
|
<div class="form-row full-row">
|
||||||
<div class="form-title poppins-bold">Design Information</div>
|
<div class="form-title poppins-bold">{{ t('AwardApply.designInformation') }}</div>
|
||||||
<div class="desc">Share your creative vision</div>
|
<div class="desc">{{ t('AwardApply.shareYourCreativeVision') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<a-form-item
|
<a-form-item
|
||||||
class="full-row design-title"
|
class="full-row design-title"
|
||||||
name="designTitle"
|
name="designTitle"
|
||||||
label="Design Title"
|
:label="t('AwardApply.designTitle')"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<a-input
|
<a-input
|
||||||
@@ -126,24 +126,24 @@
|
|||||||
<a-form-item
|
<a-form-item
|
||||||
class="full-row design-desc"
|
class="full-row design-desc"
|
||||||
name="designDescription"
|
name="designDescription"
|
||||||
label="Design description"
|
:label="t('AwardApply.designDescription')"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<a-textarea
|
<a-textarea
|
||||||
class="textarea"
|
class="textarea"
|
||||||
:disabled="readOnly"
|
:disabled="readOnly"
|
||||||
v-model:value="form.designDescription"
|
v-model:value="form.designDescription"
|
||||||
placeholder="Briefly describe your design concept, inspiration, and creative direction..."
|
:placeholder="t('AwardApply.designDescriptionPlaceholder')"
|
||||||
/>
|
/>
|
||||||
</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">{{ t('AwardApply.submissionFiles') }}</div>
|
||||||
<div class="desc">Upload your design materials</div>
|
<div class="desc">{{ t('AwardApply.uploadYourDesignMaterials') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="information full-row">
|
<div class="information full-row">
|
||||||
<div class="information-title flex align-center">
|
<div class="information-title flex align-center">
|
||||||
<div class="point"></div>
|
<div class="point"></div>
|
||||||
<div class="text poppins-bold">Submission Requirements</div>
|
<div class="text poppins-bold">{{ t('AwardApply.submissionRequirements') }}</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="information-list flex space-between">
|
<ul class="information-list flex space-between">
|
||||||
<li class="information-item">
|
<li class="information-item">
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
name="pdfPath"
|
name="pdfPath"
|
||||||
required
|
required
|
||||||
:validate-trigger="[]"
|
:validate-trigger="[]"
|
||||||
label="How will you use AiDA in your design process?"
|
:label="t('AwardApply.uploadPdfTitle')"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<a-upload-dragger
|
<a-upload-dragger
|
||||||
@@ -187,8 +187,8 @@
|
|||||||
alt=""
|
alt=""
|
||||||
class="upload-icon"
|
class="upload-icon"
|
||||||
/>
|
/>
|
||||||
<p class="desc">Click to upload or drag and drop</p>
|
<p class="desc">{{ t('AwardApply.clickToUploadPdf') }}</p>
|
||||||
<p class="limit">PDF file, max 20MB</p>
|
<p class="limit">{{ t('AwardApply.pdfFileLimit') }}</p>
|
||||||
<template #itemRender="{ file, actions }">
|
<template #itemRender="{ file, actions }">
|
||||||
<div
|
<div
|
||||||
class="custom-upload-list flex align-center space-between"
|
class="custom-upload-list flex align-center space-between"
|
||||||
@@ -240,7 +240,7 @@
|
|||||||
name="videoPath"
|
name="videoPath"
|
||||||
required
|
required
|
||||||
:validate-trigger="[]"
|
:validate-trigger="[]"
|
||||||
label="How will you use AiDA in your design process?"
|
:label="t('AwardApply.uploadVideoTitle')"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<a-upload-dragger
|
<a-upload-dragger
|
||||||
@@ -258,9 +258,9 @@
|
|||||||
alt=""
|
alt=""
|
||||||
class="upload-icon"
|
class="upload-icon"
|
||||||
/>
|
/>
|
||||||
<p class="desc">Click to upload or drag and drop</p>
|
<p class="desc">{{ t('AwardApply.clickToUploadVideo') }}</p>
|
||||||
<p class="limit">
|
<p class="limit">
|
||||||
Video file (MP4, MOV), 1080p, max 100MB
|
{{ t('AwardApply.videoFileLimit') }}
|
||||||
</p>
|
</p>
|
||||||
<template #itemRender="{ file, actions }">
|
<template #itemRender="{ file, actions }">
|
||||||
<div
|
<div
|
||||||
@@ -308,40 +308,39 @@
|
|||||||
</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">{{ t('AwardApply.termsAndConditions') }}</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"
|
|
||||||
>
|
|
||||||
<a-checkbox v-model:checked="item.check" />
|
|
||||||
<span>
|
|
||||||
{{ item.text }}
|
|
||||||
<span
|
|
||||||
class="required"
|
|
||||||
v-if="item.required"
|
|
||||||
>
|
|
||||||
*
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="submit-container">
|
|
||||||
<div
|
<div
|
||||||
class="submit-btn poppins-bold"
|
class="condition-item flex align-center"
|
||||||
@click="handleSubmitForm"
|
v-for="item in conditionsList"
|
||||||
|
:key="item.id"
|
||||||
>
|
>
|
||||||
Submit your Design
|
<a-checkbox v-model:checked="item.check" />
|
||||||
</div>
|
<span>
|
||||||
<div class="desc">
|
{{ t('AwardApply.' + item.translationKey) }}
|
||||||
The link in the AiDA in-platform message will save your unfinished
|
<span
|
||||||
form.
|
class="required"
|
||||||
|
v-if="item.required"
|
||||||
|
>
|
||||||
|
*
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="submit-container">
|
||||||
|
<div
|
||||||
|
class="submit-btn poppins-bold"
|
||||||
|
@click="handleSubmitForm"
|
||||||
|
>
|
||||||
|
{{ t('AwardApply.submitYourDesign') }}
|
||||||
|
</div>
|
||||||
|
<div class="desc">
|
||||||
|
{{ t('AwardApply.unfinishedFormTip') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="showModal"
|
v-model:visible="showModal"
|
||||||
@@ -359,9 +358,8 @@
|
|||||||
class="close-icon"
|
class="close-icon"
|
||||||
@click="handleCloseModal"
|
@click="handleCloseModal"
|
||||||
/>
|
/>
|
||||||
<div class="title poppins-bold">Check your email</div>
|
<div class="title poppins-bold">{{ t('AwardApply.checkYourEmail') }}</div>
|
||||||
<div class="desc">Enter the 6-digital code sent to</div>
|
<div class="desc">{{ t('AwardApply.enterSixDigitCode') }} {{ form.email }}</div>
|
||||||
<div class="email">{{ form.email }}</div>
|
|
||||||
<div class="code-box">
|
<div class="code-box">
|
||||||
<VerifycationCodeInput
|
<VerifycationCodeInput
|
||||||
:ct="emailCode"
|
:ct="emailCode"
|
||||||
@@ -372,7 +370,7 @@
|
|||||||
class="verify-btn"
|
class="verify-btn"
|
||||||
@click="handleVerifyCode"
|
@click="handleVerifyCode"
|
||||||
>
|
>
|
||||||
Verify
|
{{ t('AwardApply.verify') }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="cutdown"
|
class="cutdown"
|
||||||
@@ -381,8 +379,8 @@
|
|||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
isCountingDown
|
isCountingDown
|
||||||
? `Resend Code in ${formatCountdown(countdown)}`
|
? `${t('AwardApply.resendCodeIn')} ${formatCountdown(countdown)}`
|
||||||
: 'Resend'
|
: t('AwardApply.resendCode')
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -392,6 +390,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onUnmounted, onMounted, computed } from 'vue'
|
import { ref, onUnmounted, onMounted, computed } from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
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, Upload } from 'ant-design-vue'
|
import { message, Upload } from 'ant-design-vue'
|
||||||
@@ -402,13 +401,15 @@
|
|||||||
import UploadStatus from './components/UploadStatus.vue'
|
import UploadStatus from './components/UploadStatus.vue'
|
||||||
import Success from './components/Success.vue'
|
import Success from './components/Success.vue'
|
||||||
|
|
||||||
// 是否晚于2026年7月22日
|
// 是否晚于2026年7月15日
|
||||||
const isExpired = computed(() => {
|
const isExpired = computed(() => {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const targetDate = new Date('2026-03-15')
|
const targetDate = new Date('2026-07-15')
|
||||||
return now > targetDate
|
return now > targetDate
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const isCompleted = ref(false)
|
const isCompleted = ref(false)
|
||||||
|
|
||||||
@@ -451,41 +452,41 @@
|
|||||||
}
|
}
|
||||||
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(t('AwardApply.pleaseInputEmail'))
|
||||||
}
|
}
|
||||||
if (!isValidEmail(value)) {
|
if (!isValidEmail(value)) {
|
||||||
return Promise.reject('Please input a valid email address')
|
return Promise.reject(t('AwardApply.pleaseInputValidEmail'))
|
||||||
}
|
}
|
||||||
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(t('AwardApply.pleaseInputAge'))
|
||||||
}
|
}
|
||||||
if (!Number.isInteger(value)) {
|
if (!Number.isInteger(Number(value))) {
|
||||||
return Promise.reject('Please input digits')
|
return Promise.reject(t('AwardApply.pleaseInputDigits'))
|
||||||
}
|
}
|
||||||
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(t('AwardApply.pleaseInputPhoneNumber'))
|
||||||
}
|
}
|
||||||
const phoneRegex = /^[\+]?[1-9][\d]{0,15}$/
|
const phoneRegex = /^[\+]?[1-9][\d]{0,15}$/
|
||||||
if (!phoneRegex.test(value)) {
|
if (!phoneRegex.test(value)) {
|
||||||
return Promise.reject('Please enter a valid phone number.')
|
return Promise.reject(t('AwardApply.pleaseInputValidPhone'))
|
||||||
}
|
}
|
||||||
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(t('AwardApply.pleaseEnterCompleteCode'))
|
||||||
}
|
}
|
||||||
const codeRegex = /^\d{6}$/
|
const codeRegex = /^\d{6}$/
|
||||||
if (!codeRegex.test(value)) {
|
if (!codeRegex.test(value)) {
|
||||||
return Promise.reject('Please enter a 6-digit verification code.')
|
return Promise.reject(t('AwardApply.pleaseEnterCompleteCode'))
|
||||||
}
|
}
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
}
|
}
|
||||||
@@ -596,6 +597,39 @@
|
|||||||
])
|
])
|
||||||
|
|
||||||
const showModal = ref(false)
|
const showModal = ref(false)
|
||||||
|
// 获取表单标签的翻译
|
||||||
|
const getFieldLabel = (key: string) => {
|
||||||
|
const labelMap: Record<string, string> = {
|
||||||
|
firstName: t('AwardApply.firstName'),
|
||||||
|
lastName: t('AwardApply.lastName'),
|
||||||
|
gender: t('AwardApply.gender'),
|
||||||
|
occupation: t('AwardApply.occupation'),
|
||||||
|
age: t('AwardApply.age'),
|
||||||
|
countryRegionCity: t('AwardApply.countryRegionCity'),
|
||||||
|
phoneNumber: t('AwardApply.phoneNumber'),
|
||||||
|
portfolioUrl: t('AwardApply.portfolioUrl')
|
||||||
|
}
|
||||||
|
return labelMap[key] || key
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取性别选项的翻译
|
||||||
|
const getGenderOptions = () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t('AwardApply.male'),
|
||||||
|
value: 'Male'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('AwardApply.female'),
|
||||||
|
value: 'Female'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('AwardApply.other'),
|
||||||
|
value: 'Other'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
// 倒计时相关状态
|
// 倒计时相关状态
|
||||||
const countdown = ref(0)
|
const countdown = ref(0)
|
||||||
const countdownTimer = ref<NodeJS.Timeout | null>(null)
|
const countdownTimer = ref<NodeJS.Timeout | null>(null)
|
||||||
@@ -662,7 +696,7 @@
|
|||||||
console.log(verifyCode.value)
|
console.log(verifyCode.value)
|
||||||
|
|
||||||
if (verifyCode.value.length !== 6) {
|
if (verifyCode.value.length !== 6) {
|
||||||
message.error('Please enter the complete 6-digit verification code')
|
message.error(t('AwardApply.pleaseEnterCompleteCode'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Https.axiosGet(Https.httpUrls.checkOTP, {
|
Https.axiosGet(Https.httpUrls.checkOTP, {
|
||||||
@@ -676,21 +710,21 @@
|
|||||||
|
|
||||||
form.value.secureToken = res.data.secureToken
|
form.value.secureToken = res.data.secureToken
|
||||||
|
|
||||||
message.success('Verification successful!')
|
message.success(t('AwardApply.verificationSuccess'))
|
||||||
showModal.value = false
|
showModal.value = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmitForm = () => {
|
const handleSubmitForm = () => {
|
||||||
if (!hasValidEmail.value) {
|
if (!hasValidEmail.value) {
|
||||||
message.error('Please verify your email first')
|
message.error(t('AwardApply.pleaseVerifyEmailFirst'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const validCondition = conditionsList.value.filter(
|
const validCondition = conditionsList.value.filter(
|
||||||
item => item.required && !item.check
|
item => item.required && !item.check
|
||||||
)
|
)
|
||||||
if (validCondition.length > 0) {
|
if (validCondition.length > 0) {
|
||||||
message.error('Please check the terms and conditions')
|
message.error(t('AwardApply.pleaseCheckTerms'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
formRef.value
|
formRef.value
|
||||||
@@ -704,7 +738,7 @@
|
|||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
message.error('Please fill in all the required fields')
|
message.error(t('AwardApply.pleaseFillRequiredFields'))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,7 +762,7 @@
|
|||||||
// 统一的文件上传前验证
|
// 统一的文件上传前验证
|
||||||
const beforeUploadFile = (type: FileType, file: File) => {
|
const beforeUploadFile = (type: FileType, file: File) => {
|
||||||
if (!hasValidEmail.value) {
|
if (!hasValidEmail.value) {
|
||||||
message.error('Please verify your email first')
|
message.error(t('AwardApply.pleaseVerifyEmailFirst'))
|
||||||
return Upload.LIST_IGNORE
|
return Upload.LIST_IGNORE
|
||||||
}
|
}
|
||||||
let maxSize: number
|
let maxSize: number
|
||||||
@@ -740,12 +774,12 @@
|
|||||||
maxSize = 20 * 1024 * 1024 // 20MB
|
maxSize = 20 * 1024 * 1024 // 20MB
|
||||||
allowedExtensions = ['pdf']
|
allowedExtensions = ['pdf']
|
||||||
allowedMimeTypes = ['application/pdf']
|
allowedMimeTypes = ['application/pdf']
|
||||||
errorMessage = 'Please upload a PDF file only.'
|
errorMessage = t('AwardApply.uploadPdfOnly')
|
||||||
} else if (type === 'video') {
|
} else if (type === 'video') {
|
||||||
maxSize = 100 * 1024 * 1024 // 100MB
|
maxSize = 100 * 1024 * 1024 // 100MB
|
||||||
allowedExtensions = ['mp4', 'mov']
|
allowedExtensions = ['mp4', 'mov']
|
||||||
allowedMimeTypes = ['video/mp4', 'video/quicktime']
|
allowedMimeTypes = ['video/mp4', 'video/quicktime']
|
||||||
errorMessage = 'Please upload a MP4 or MOV file only.'
|
errorMessage = t('AwardApply.uploadVideoOnly')
|
||||||
} else {
|
} else {
|
||||||
return Upload.LIST_IGNORE
|
return Upload.LIST_IGNORE
|
||||||
}
|
}
|
||||||
@@ -777,7 +811,7 @@
|
|||||||
if (file.size > maxSize) {
|
if (file.size > maxSize) {
|
||||||
const sizeLimit = type === 'pdf' ? '20MB' : '100MB'
|
const sizeLimit = type === 'pdf' ? '20MB' : '100MB'
|
||||||
message.error(
|
message.error(
|
||||||
`File size exceeds ${sizeLimit} limit. Please upload a smaller file.`
|
t('AwardApply.fileSizeExceeds', { sizeLimit })
|
||||||
)
|
)
|
||||||
// 从文件列表中移除
|
// 从文件列表中移除
|
||||||
// if (type === 'pdf') {
|
// if (type === 'pdf') {
|
||||||
@@ -899,7 +933,7 @@
|
|||||||
const status = info.file.status
|
const status = info.file.status
|
||||||
|
|
||||||
if (status === 'done') {
|
if (status === 'done') {
|
||||||
message.success(`${info.file.name} file uploaded successfully.`)
|
message.success(t('AwardApply.fileUploadedSuccess', { fileName: info.file.name }))
|
||||||
if (type === 'pdf') {
|
if (type === 'pdf') {
|
||||||
isUploadingPdf.value = false
|
isUploadingPdf.value = false
|
||||||
uploadProgressPdf.value = 0
|
uploadProgressPdf.value = 0
|
||||||
@@ -910,7 +944,7 @@
|
|||||||
videoUploadStatus.value = 'success'
|
videoUploadStatus.value = 'success'
|
||||||
}
|
}
|
||||||
} else if (status === 'error') {
|
} else if (status === 'error') {
|
||||||
message.error(`${info.file.name} file upload failed.`)
|
message.error(t('AwardApply.fileUploadFailed', { fileName: info.file.name }))
|
||||||
if (type === 'pdf') {
|
if (type === 'pdf') {
|
||||||
isUploadingPdf.value = false
|
isUploadingPdf.value = false
|
||||||
uploadProgressPdf.value = 0
|
uploadProgressPdf.value = 0
|
||||||
@@ -928,7 +962,7 @@
|
|||||||
const file = option.file as File
|
const file = option.file as File
|
||||||
|
|
||||||
if (!form.value.email) {
|
if (!form.value.email) {
|
||||||
message.error('Please input the email address first')
|
message.error(t('AwardApply.pleaseInputEmail'))
|
||||||
option.onError?.(new Error('Email required'))
|
option.onError?.(new Error('Email required'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -973,7 +1007,7 @@
|
|||||||
option.onSuccess?.({ uploadId }, option.file)
|
option.onSuccess?.({ uploadId }, option.file)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('Upload error:', error)
|
console.error('Upload error:', error)
|
||||||
message.error(error?.message || 'Upload failed')
|
message.error(error?.message || t('AwardApply.uploadFailed'))
|
||||||
option.onError?.(error)
|
option.onError?.(error)
|
||||||
|
|
||||||
if (type === 'pdf') {
|
if (type === 'pdf') {
|
||||||
@@ -1017,23 +1051,27 @@
|
|||||||
check: false,
|
check: false,
|
||||||
required: true,
|
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.',
|
||||||
|
translationKey: 'conditionFirst',
|
||||||
id: 'first'
|
id: 'first'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
check: false,
|
check: false,
|
||||||
required: true,
|
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.',
|
||||||
|
translationKey: 'conditionSecond',
|
||||||
id: 'second'
|
id: 'second'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
check: false,
|
check: false,
|
||||||
required: true,
|
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.',
|
||||||
|
translationKey: 'conditionThird',
|
||||||
id: 'third'
|
id: 'third'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
check: false,
|
check: false,
|
||||||
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)',
|
||||||
|
translationKey: 'conditionFourth',
|
||||||
id: 'forth'
|
id: 'forth'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
alt=""
|
alt=""
|
||||||
class="icon-img"
|
class="icon-img"
|
||||||
/>
|
/>
|
||||||
<div class="title">{{ info.title }}</div>
|
<div class="title">{{ $t(info.title) }}</div>
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
{{ info.desc }}
|
{{ $t(info.desc) }}
|
||||||
<!-- <div>
|
<!-- <div>
|
||||||
Please review your submitted information in the AiDA in-platform message.
|
Please review your submitted information in the AiDA in-platform message.
|
||||||
</div>
|
</div>
|
||||||
@@ -37,14 +37,14 @@
|
|||||||
if (props.isExpired) {
|
if (props.isExpired) {
|
||||||
return {
|
return {
|
||||||
icon: expiredIcon,
|
icon: expiredIcon,
|
||||||
title: t('AwardsPage.deadlinePassed'),
|
title: 'AwardsPage.deadlinePassed',
|
||||||
desc: t('AwardsPage.deadlinePassedDesc')
|
desc: 'AwardsPage.deadlinePassedDesc'
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
icon: successIcon,
|
icon: successIcon,
|
||||||
title: t('AwardsPage.submissionSuccessful'),
|
title: 'AwardsPage.submissionSuccessful',
|
||||||
desc: t('AwardsPage.submissionSuccessfulDesc')
|
desc: 'AwardsPage.submissionSuccessfulDesc'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -15,8 +15,8 @@
|
|||||||
class="progress-icon successful-icon"
|
class="progress-icon successful-icon"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="text">{{ text }}</div>
|
<div class="text">{{ $t(text) }}</div>
|
||||||
<div class="tips">{{ tips }}</div>
|
<div class="tips">{{ $t(tips) }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -32,16 +32,16 @@
|
|||||||
|
|
||||||
const textMap: Record<string, string> = {
|
const textMap: Record<string, string> = {
|
||||||
idle: '',
|
idle: '',
|
||||||
uploading: computed(() => t('AwardsPage.uploadInProgress')).value,
|
uploading: 'AwardsPage.uploadInProgress',
|
||||||
success: computed(() => t('AwardsPage.uploadSuccess')).value,
|
success:'AwardsPage.uploadSuccess',
|
||||||
error: computed(() => t('AwardsPage.uploadFailed')).value
|
error: 'AwardsPage.fileUploadFailed'
|
||||||
}
|
}
|
||||||
|
|
||||||
const tips = computed(() => {
|
const tips = computed(() => {
|
||||||
if (props.type === 'pdf') {
|
if (props.type === 'pdf') {
|
||||||
return t('AwardsPage.pdfFileTip')
|
return 'AwardsPage.pdfFileTip'
|
||||||
} else if (props.type === 'video') {
|
} else if (props.type === 'video') {
|
||||||
return t('AwardsPage.videoFileTip')
|
return 'AwardsPage.videoFileTip'
|
||||||
}
|
}
|
||||||
return ''
|
return ''
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user