feat: award页面迁移
@@ -7,7 +7,7 @@
|
||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
|
||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> -->
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
|
||||
<link rel="stylesheet" href="/css/woff/fontFamily.css">
|
||||
<link rel="stylesheet" href="/css/fonts/fontFamily.css">
|
||||
<title>FiDA</title>
|
||||
</head>
|
||||
|
||||
|
||||
448
package-lock.json
generated
@@ -9,6 +9,7 @@
|
||||
"version": "0.0.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.3.6",
|
||||
"crypto-js": "^4.2.0",
|
||||
"gsap": "^3.13.0",
|
||||
@@ -46,6 +47,34 @@
|
||||
"vue-tsc": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ant-design/colors": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz",
|
||||
"integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ant-design/icons-svg": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz",
|
||||
"integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@ant-design/icons-vue": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz",
|
||||
"integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-svg": "^4.2.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">=3.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/utils": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.2.tgz",
|
||||
@@ -85,6 +114,15 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
|
||||
"integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz",
|
||||
@@ -98,6 +136,27 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ctrl/tinycolor": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
|
||||
"integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@emotion/hash": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
|
||||
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@emotion/unitless": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
||||
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.17.18",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.17.18.tgz",
|
||||
@@ -688,6 +747,16 @@
|
||||
"integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@simonwep/pickr": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz",
|
||||
"integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"core-js": "^3.15.1",
|
||||
"nanopop": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@@ -1434,6 +1503,46 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ant-design-vue": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.6.tgz",
|
||||
"integrity": "sha512-t7eX13Yj3i9+i5g9lqFyYneoIb3OzTvQjq9Tts1i+eiOd3Eva/6GagxBSXM1fOCjqemIu0FYVE1ByZ/38epR3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-vue": "^7.0.0",
|
||||
"@babel/runtime": "^7.10.5",
|
||||
"@ctrl/tinycolor": "^3.5.0",
|
||||
"@emotion/hash": "^0.9.0",
|
||||
"@emotion/unitless": "^0.8.0",
|
||||
"@simonwep/pickr": "~1.8.0",
|
||||
"array-tree-filter": "^2.1.0",
|
||||
"async-validator": "^4.0.0",
|
||||
"csstype": "^3.1.1",
|
||||
"dayjs": "^1.10.5",
|
||||
"dom-align": "^1.12.1",
|
||||
"dom-scroll-into-view": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.15",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"scroll-into-view-if-needed": "^2.2.25",
|
||||
"shallow-equal": "^1.0.0",
|
||||
"stylis": "^4.1.3",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"vue-types": "^3.0.0",
|
||||
"warning": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.22.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ant-design-vue"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">=3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
|
||||
@@ -1496,6 +1605,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/array-tree-filter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
|
||||
"integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/array-union": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz",
|
||||
@@ -1603,6 +1718,12 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/async-validator": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
|
||||
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@@ -2019,6 +2140,12 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/compute-scroll-into-view": {
|
||||
"version": "1.0.20",
|
||||
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
|
||||
"integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -2053,6 +2180,17 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.48.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz",
|
||||
"integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
|
||||
@@ -2272,6 +2410,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.19",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
|
||||
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/de-indent": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz",
|
||||
@@ -2388,6 +2532,18 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-align": {
|
||||
"version": "1.12.4",
|
||||
"resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz",
|
||||
"integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dom-scroll-into-view": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz",
|
||||
"integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
@@ -4350,6 +4506,12 @@
|
||||
"integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
@@ -4652,7 +4814,12 @@
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz",
|
||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
|
||||
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.merge": {
|
||||
@@ -4733,6 +4900,18 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"loose-envify": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
@@ -5104,6 +5283,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanopop": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz",
|
||||
"integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
@@ -6179,6 +6364,12 @@
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz",
|
||||
@@ -6427,6 +6618,15 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/scroll-into-view-if-needed": {
|
||||
"version": "2.2.31",
|
||||
"resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz",
|
||||
"integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"compute-scroll-into-view": "^1.0.20"
|
||||
}
|
||||
},
|
||||
"node_modules/scule": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.0.0.tgz",
|
||||
@@ -6509,6 +6709,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/shallow-equal": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@@ -7106,6 +7312,12 @@
|
||||
"acorn": "^8.8.2"
|
||||
}
|
||||
},
|
||||
"node_modules/stylis": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz",
|
||||
"integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
||||
@@ -7399,6 +7611,15 @@
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/throttle-debounce": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
|
||||
"integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.22"
|
||||
}
|
||||
},
|
||||
"node_modules/through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmmirror.com/through/-/through-2.3.8.tgz",
|
||||
@@ -8267,6 +8488,39 @@
|
||||
"typescript": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-types": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz",
|
||||
"integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-plain-object": "3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.15.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-types/node_modules/is-plain-object": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
|
||||
"integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
@@ -8481,6 +8735,28 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/colors": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz",
|
||||
"integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
|
||||
"requires": {
|
||||
"@ctrl/tinycolor": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"@ant-design/icons-svg": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz",
|
||||
"integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA=="
|
||||
},
|
||||
"@ant-design/icons-vue": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-7.0.1.tgz",
|
||||
"integrity": "sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==",
|
||||
"requires": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-svg": "^4.2.1"
|
||||
}
|
||||
},
|
||||
"@antfu/utils": {
|
||||
"version": "0.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.2.tgz",
|
||||
@@ -8505,6 +8781,11 @@
|
||||
"@babel/types": "^7.29.0"
|
||||
}
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
|
||||
"integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.29.0",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.29.0.tgz",
|
||||
@@ -8514,6 +8795,21 @@
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
}
|
||||
},
|
||||
"@ctrl/tinycolor": {
|
||||
"version": "3.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
|
||||
"integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA=="
|
||||
},
|
||||
"@emotion/hash": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
|
||||
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="
|
||||
},
|
||||
"@emotion/unitless": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
|
||||
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
|
||||
},
|
||||
"@esbuild/android-arm": {
|
||||
"version": "0.17.18",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.17.18.tgz",
|
||||
@@ -8836,6 +9132,15 @@
|
||||
"integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==",
|
||||
"dev": true
|
||||
},
|
||||
"@simonwep/pickr": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@simonwep/pickr/-/pickr-1.8.2.tgz",
|
||||
"integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==",
|
||||
"requires": {
|
||||
"core-js": "^3.15.1",
|
||||
"nanopop": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@@ -9373,6 +9678,35 @@
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"ant-design-vue": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-4.2.6.tgz",
|
||||
"integrity": "sha512-t7eX13Yj3i9+i5g9lqFyYneoIb3OzTvQjq9Tts1i+eiOd3Eva/6GagxBSXM1fOCjqemIu0FYVE1ByZ/38epR3Q==",
|
||||
"requires": {
|
||||
"@ant-design/colors": "^6.0.0",
|
||||
"@ant-design/icons-vue": "^7.0.0",
|
||||
"@babel/runtime": "^7.10.5",
|
||||
"@ctrl/tinycolor": "^3.5.0",
|
||||
"@emotion/hash": "^0.9.0",
|
||||
"@emotion/unitless": "^0.8.0",
|
||||
"@simonwep/pickr": "~1.8.0",
|
||||
"array-tree-filter": "^2.1.0",
|
||||
"async-validator": "^4.0.0",
|
||||
"csstype": "^3.1.1",
|
||||
"dayjs": "^1.10.5",
|
||||
"dom-align": "^1.12.1",
|
||||
"dom-scroll-into-view": "^2.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.15",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"scroll-into-view-if-needed": "^2.2.25",
|
||||
"shallow-equal": "^1.0.0",
|
||||
"stylis": "^4.1.3",
|
||||
"throttle-debounce": "^5.0.0",
|
||||
"vue-types": "^3.0.0",
|
||||
"warning": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"anymatch": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
|
||||
@@ -9417,6 +9751,11 @@
|
||||
"is-array-buffer": "^3.0.5"
|
||||
}
|
||||
},
|
||||
"array-tree-filter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
|
||||
"integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw=="
|
||||
},
|
||||
"array-union": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz",
|
||||
@@ -9490,6 +9829,11 @@
|
||||
"integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
|
||||
"dev": true
|
||||
},
|
||||
"async-validator": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
|
||||
"integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@@ -9813,6 +10157,11 @@
|
||||
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
|
||||
"dev": true
|
||||
},
|
||||
"compute-scroll-into-view": {
|
||||
"version": "1.0.20",
|
||||
"resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
|
||||
"integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg=="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@@ -9840,6 +10189,11 @@
|
||||
"integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
|
||||
"dev": true
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.48.0",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz",
|
||||
"integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ=="
|
||||
},
|
||||
"cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz",
|
||||
@@ -9993,6 +10347,11 @@
|
||||
"is-data-view": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"dayjs": {
|
||||
"version": "1.11.19",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
|
||||
"integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="
|
||||
},
|
||||
"de-indent": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz",
|
||||
@@ -10074,6 +10433,16 @@
|
||||
"esutils": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"dom-align": {
|
||||
"version": "1.12.4",
|
||||
"resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.4.tgz",
|
||||
"integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw=="
|
||||
},
|
||||
"dom-scroll-into-view": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz",
|
||||
"integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w=="
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/dom-serializer/-/dom-serializer-0.2.2.tgz",
|
||||
@@ -11541,6 +11910,11 @@
|
||||
"integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
|
||||
"dev": true
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
@@ -11773,8 +12147,12 @@
|
||||
"lodash": {
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.23.tgz",
|
||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="
|
||||
},
|
||||
"lodash-es": {
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
|
||||
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="
|
||||
},
|
||||
"lodash.merge": {
|
||||
"version": "4.6.2",
|
||||
@@ -11841,6 +12219,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
|
||||
"requires": {
|
||||
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||
}
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
@@ -12119,6 +12505,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"nanopop": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/nanopop/-/nanopop-2.4.2.tgz",
|
||||
"integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw=="
|
||||
},
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
@@ -12917,6 +13308,11 @@
|
||||
"integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
|
||||
"dev": true
|
||||
},
|
||||
"resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.2.tgz",
|
||||
@@ -13108,6 +13504,14 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"scroll-into-view-if-needed": {
|
||||
"version": "2.2.31",
|
||||
"resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz",
|
||||
"integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==",
|
||||
"requires": {
|
||||
"compute-scroll-into-view": "^1.0.20"
|
||||
}
|
||||
},
|
||||
"scule": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.0.0.tgz",
|
||||
@@ -13172,6 +13576,11 @@
|
||||
"split-string": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"shallow-equal": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
|
||||
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
@@ -13641,6 +14050,11 @@
|
||||
"acorn": "^8.8.2"
|
||||
}
|
||||
},
|
||||
"stylis": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz",
|
||||
"integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ=="
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
||||
@@ -13876,6 +14290,11 @@
|
||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"throttle-debounce": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
|
||||
"integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A=="
|
||||
},
|
||||
"through": {
|
||||
"version": "2.3.8",
|
||||
"resolved": "https://registry.npmmirror.com/through/-/through-2.3.8.tgz",
|
||||
@@ -14494,6 +14913,29 @@
|
||||
"semver": "^7.3.8"
|
||||
}
|
||||
},
|
||||
"vue-types": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-types/-/vue-types-3.0.2.tgz",
|
||||
"integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==",
|
||||
"requires": {
|
||||
"is-plain-object": "3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-plain-object": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
|
||||
"integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"postinstall": "husky install"
|
||||
},
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^4.2.6",
|
||||
"axios": "^1.3.6",
|
||||
"crypto-js": "^4.2.0",
|
||||
"gsap": "^3.13.0",
|
||||
|
||||
BIN
public/css/fonts/ARIAL.ttf
Normal file
BIN
public/css/fonts/ARIALBD.ttf
Normal file
BIN
public/css/fonts/ArialMdm.ttf
Normal file
BIN
public/css/fonts/InstrumentSans-Bold.ttf
Normal file
BIN
public/css/fonts/InstrumentSans-Regular.ttf
Normal file
BIN
public/css/fonts/Poppins-Medium.ttf
Normal file
BIN
public/css/fonts/Poppins-Regular.ttf
Normal file
BIN
public/css/fonts/Poppins-SemiBold.ttf
Normal file
41
public/css/fonts/fontFamily.css
Normal file
@@ -0,0 +1,41 @@
|
||||
/* 字体定义 */
|
||||
@font-face {
|
||||
font-family: 'Arial';
|
||||
src: url('./ARIAL.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ArialBold';
|
||||
src: url('./ARIALBD.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'ArialMedium';
|
||||
src: url('./ArialMdm.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Poppins';
|
||||
src: url('./Poppins-Regular.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PoppinsMedium';
|
||||
src: url('./Poppins-Medium.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'PoppinsBold';
|
||||
src: url('./Poppins-SemiBold.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Instrument';
|
||||
src: url('./InstrumentSans-Regular.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'InstrumentBold';
|
||||
src: url('./InstrumentSans-Bold.ttf') format('truetype');
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'satoshiRegular';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./Satoshi/Satoshi-Regular.ttf") format('woff2'), url("./Satoshi/Satoshi-Regular.woff") format('woff2');
|
||||
/* unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; */
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'satoshiBold';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./Satoshi/Satoshi-Bold.ttf") format('woff2'), url("./Satoshi/Satoshi-Bold.woff") format('woff2');
|
||||
/* unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; */
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'satoshiMedium';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./Satoshi/Satoshi-Medium.ttf") format('woff2'), url("./Satoshi/Satoshi-Medium.woff") format('woff2');
|
||||
/* unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; */
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'mazzardHRegular';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./Mazzard/MazzardH-Regular.otf") format('opentype');
|
||||
/* unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; */
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'robotoBold';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./Roboto/Roboto-Bold.ttf") format('woff2');
|
||||
/* unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; */
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'robotoRegular';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./Roboto/Roboto-Regular.ttf") format('woff2');
|
||||
/* unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; */
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'boskaRegular';
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
src: url("./Boska/Boska-Regular.ttf") format('woff2'), url("./Boska/Boska-Regular.woff") format('woff2');
|
||||
/* unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; */
|
||||
}
|
||||
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 71 KiB |
|
Before Width: | Height: | Size: 1.6 MiB |
|
Before Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 57 KiB |
1
src/assets/icons/CDelete.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746501838166" class="icon" viewBox="0 0 1029 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14477" xmlns:xlink="http://www.w3.org/1999/xlink" width="200.9765625" height="200"><path d="M133.076426 1013.469886c-1.621429-1.358835-3.271525-3.124748-4.892955-4.891808 1.79458 1.765913 3.271525 3.532972 4.892955 4.891808z m-10.939485-6.270137c-1.724632-1.574414-3.427476-3.147682-5.039732-4.892954 1.590468 1.745272 3.313953 3.31854 5.039732 4.892954zM1017.567032 158.745227c-7.794096-7.79295-19.126898-12.137783-30.123717-12.137782H776.022289V80.738903c0-44.54572-36.192036-80.738903-80.738903-80.738903H334.387028c-44.54572 0-80.738903 36.193183-80.738903 80.738903v65.868542H41.151498c-22.553227 0-41.008161 18.319624-41.008161 41.007014s18.32077 41.008161 41.008161 41.008161h36.192036v713.661492c0 44.546867 36.193183 80.738903 80.738903 80.738903h725.017227c44.546867 0 80.738903-36.192036 80.738903-80.738903V228.62262h23.584107c22.553227 0 42.149124-18.32077 42.149124-41.008161 0.022934-10.884443-4.21067-21.075135-12.003619-28.868085zM334.252865 80.986589h360.671605v66.315754h-360.670459z m548.734423 861.18744H158.083583V228.62262H882.965501v713.550262zM514.29798 366.047319c-22.799767 0-41.231767 18.432-41.231767 41.231767v382.552869c0 22.799767 18.432 41.231767 41.231767 41.231767s41.231767-18.432 41.231767-41.231767V407.279086c0-22.776833-18.432-41.231767-41.231767-41.231767z m-223.337496 0c-22.799767 0-41.231767 18.432-41.231767 41.231767v382.552869c0 22.799767 18.432 41.231767 41.231767 41.231767s41.231767-18.432 41.231767-41.231767V407.279086c0-22.776833-18.453787-41.231767-41.231767-41.231767z m444.390772 0c-22.799767 0-41.232914 18.432-41.232913 41.231767v382.552869c0 22.799767 18.433147 41.231767 41.231767 41.231767s41.231767-18.432 41.231767-41.231767V407.279086c0-22.776833-18.432-41.231767-41.231767-41.231767z" p-id="14478"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
1
src/assets/icons/CFile.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg focusable="false" class="" data-icon="paper-clip" width="1em" height="1em" fill="#00000073" aria-hidden="true" viewBox="64 64 896 896"><path d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 00174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"></path></svg>
|
||||
|
After Width: | Height: | Size: 985 B |
BIN
src/assets/images/award/apply_bg.png
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
src/assets/images/award/arrow.png
Normal file
|
After Width: | Height: | Size: 198 B |
3
src/assets/images/award/arrow_down.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="22" height="12" viewBox="0 0 22 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 1L11 11L21 1" stroke="#585858" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 212 B |
BIN
src/assets/images/award/arrow_right.png
Normal file
|
After Width: | Height: | Size: 327 B |
BIN
src/assets/images/award/banner.mp4
Normal file
BIN
src/assets/images/award/banner_chinese.mp4
Normal file
BIN
src/assets/images/award/bloom_bg.png
Normal file
|
After Width: | Height: | Size: 492 KiB |
BIN
src/assets/images/award/bloom_logo.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/images/award/certification_bg.png
Normal file
|
After Width: | Height: | Size: 231 KiB |
BIN
src/assets/images/award/checked.png
Normal file
|
After Width: | Height: | Size: 913 B |
4
src/assets/images/award/close.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.6144 18.7388L5.16736 4.29184C4.95412 4.0786 4.60838 4.0786 4.39514 4.29184C4.18189 4.50509 4.18189 4.85082 4.39514 5.06407L18.8421 19.5111C19.0554 19.7243 19.4011 19.7243 19.6144 19.5111C19.8276 19.2978 19.8276 18.9521 19.6144 18.7388Z" fill="#232323"/>
|
||||
<path d="M5.15908 19.5378L19.6061 5.09079C19.8193 4.87755 19.8193 4.53181 19.6061 4.31857C19.3928 4.10533 19.0471 4.10533 18.8339 4.31857L4.38685 18.7656C4.17361 18.9788 4.17361 19.3246 4.38685 19.5378C4.6001 19.751 4.94583 19.751 5.15908 19.5378Z" fill="#232323"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 636 B |
BIN
src/assets/images/award/code_create_logo.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
src/assets/images/award/criteria_1.png
Normal file
|
After Width: | Height: | Size: 339 KiB |
BIN
src/assets/images/award/criteria_2.png
Normal file
|
After Width: | Height: | Size: 443 KiB |
BIN
src/assets/images/award/criteria_3.png
Normal file
|
After Width: | Height: | Size: 184 KiB |
BIN
src/assets/images/award/criteria_4.png
Normal file
|
After Width: | Height: | Size: 280 KiB |
BIN
src/assets/images/award/criteria_bg.png
Normal file
|
After Width: | Height: | Size: 400 KiB |
BIN
src/assets/images/award/design_bg.png
Normal file
|
After Width: | Height: | Size: 4.3 MiB |
BIN
src/assets/images/award/desmond.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/images/award/diego.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
BIN
src/assets/images/award/expired.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
9
src/assets/images/award/facebook.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<rect width="20" height="20" rx="2.79453" fill="url(#pattern0_226_198)"/>
|
||||
<defs>
|
||||
<pattern id="pattern0_226_198" patternContentUnits="objectBoundingBox" width="1" height="1">
|
||||
<use xlink:href="#image0_226_198" transform="scale(0.0104167)"/>
|
||||
</pattern>
|
||||
<image id="image0_226_198" width="96" height="96" preserveAspectRatio="none" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAKcUlEQVR4AeydSewlRR3H3xtHUXAZdz2YGQ+aeDDiCYgCMxwENFGMMdF4cDx48gB6VOOuiR4UPWlkGSAsBxK2BMI6wxYgLMOSEJYAQ9jXGbZh58/n0/Oq6ffmLd3Vr1/369f/1PfV0lW/qvr+flVdr7pe/9f1Cv6tra1tAseDU8FDYDdYVWffd9L584CcbCpIZy+3AqhgK9hOBQ+BE8FWYIUb8FfV2feD6fxxQE40SBXyU+K53EwFQPpmIOmnInEz6Nx0BlTINjkDMxUxUQEU3gDUqlavpU+vtrs6yoCcqYh/waMjZfR6Eh+rAApYWOKPT3J1H2UYOIHCTktySnDY7aeADPkOpeHcXSyWAcnfPuB2SMaQAsjgUNHyLTCUsYuUZkBOXS3JcSpsSAGk/gGYEa9zFTDgrPL7rNxUAVi/y8puzs+yU034BLhOV5OpAqhrSDPEO1cdAy7pE+mJAtCI1r86U0/S9Vo/3E1IviMkCqApqzj1rNHvebl3EFRUnkbfW4f1a/neHJDRuUgGipJvNe4wbHQEfM/YCmCUpP6gz1rvs4QfBXeDO8GN4HpwNdgxgiuJXwvM8zD+XvA+EOQRzO2OUwHpHTl3seXLOEp+tgevEbkX3ADOBaeD/4C/gz8O4PJc/I74b8Ffwb/BNeAZEOsOVgFOQbEClqGc5Gudwva+zccT4H5wIXBF8n/8k8Apot/vnw0uAtvBDnD1ANfi3wguBeeQ92LwJIh1m9uuAMkfJedVErT2M/G1dBXgtHI7ca35Zfy8bg8Z3wCxboMKGPpqHCupoeW0eqEiXqSNEn0G/n/B/7DiK8Gt4FHwNNgL3uTaRMeiRXnhugqYmj9knOAnCphwrVXJr9Abb6qn4Z8FbgLeePGKORSkMkOh9xPQiPHiXKnCcVVWXipLkCuc56jR6cZ53rn9Okh8EbxFeuJGrDpJy/nh6idn1vHZ2qiAbE93E7kMuLrZmSWdtNSRnlVamr6IwAIVUHl3AonO0Ya9mUr8yRB8BdgVWoDFN6bfjWlIICfSl/BsUW+4flnS+h/IXjCMMpyaDNaOtihAqxeB0FsInA0uhOys5WfzcLl+1xYFBCb9kuXUcx8JD0J+eqMl3iM+OlJMrhVtUECW1Kdh83JwPrgLJG6ecz6ysqNIhSd1xH60QQHZvr9E5A7ghpqbZAR7Wn5Vc74jrJTsNigga5H39Ho992ueZLqRHKL53IhlTyyE3OyI+xgZ/TKGF+faoAB7rhVq8Y8QeQEUcnnJHyP046R9AES7tijgeRi4DdwM0t3JPMSaR6sWlO0RPwB8AXwVHAGOBFuAD1AOxz8UHAN+TP5jwOdAtGuLAtzhfBwWJD/dnQykkj7WQWJ2+pJ8404r36TAT8BvgIcV/oQfng34LODXxH2MeyT+p0G0a4sCvPk6/wuXobkIUUEik/nrhH8AfgF+Dr4FtgAVcgS+4aPwDweHgI3gQOD9JntvIGmfm/XZFgVIgN9+heFZ/R66zkhw2vksiZJ67MD/BH5e56acoydv/jRfWxTgDfgxrHk3iNmfl3wt22nHeX19ytC+wCzrjiJf0W1RgFav9dunGDjvf42CXwGj5JPUiybYwtPQFgVo9bnn/jGEuJx0/nfaqYzsMfXm/4nSuMINSpM0Edsky5b6QhVbcVtGQGz/Qzl5yCpg1pwfypX2rbi0kBYIkHC/TYeuOCJCuFJ/mRUgaYGc6GXgQICEi0G0l5Ud0irxl1kBWUJcuZTpi+QrIytzIeEyja6igVpediqYVoekhesuQV0JhXhR32Ws36ZDuazskDbNt93Trk+81jQF2NCYznj6Id0D6imlGFSeSixW6r3cGk1Muxu3DNXynM89SOXJYw9Q+XD9KvrqjwfDSWXTPJ18Keme0bwE3404vChnWc95eopCmR5d9OBtqC/4tuEKavCQ1058z5h6uNc223aSirkmjgB74Kk1j4b7Q3F3Hz2R7K5k2JH0lLI7lV4zj3k912nZGPgoU3L/SeG/AevzNHSoL/jW607oP8jjQV6V4PFEonGuqQrQsi5hX+cc4EnkG/B90uVJ5YCrBmk34T8M9rKpth7ktkTy+gOV9ZR9BewC1nMNvrLDyehQn76n6m7muqeqt0G5I0FjIRjnmqoA52Tn9aK9ehtycs/F5HXujn2w7j3H+4ZtLdrONH9TFWDn0keLWGouq4bQ3OQHBmLKDNrjvF+4vlBv8JuqANuVbg3EkBQ6WJF/AHLdQRVpO0kr7Oxo4UILKKDFa2ELqCqqChXwGUoKwwTjXFMVENebxZXSOD5EdaLUN+hOAbAY4bT6T1LuU6A7lgIJi3ZhBHyQig3jxbk5joC4BixpKUeAx1GE4ehudAqIo06rP4iiwjDBONdUBbi+Tr8gDdbdcT2sppRLT+8BrR0BKsAt4mroi5A6YgQuk53/RStXQXbqI4GnvF/ERkgKxSf65ge5ZoGRNnwYoZ4lso2tnIIc4n7LpJ+FnJtrWmeRQkXzK9v1/0cNlEUu7ZetJKL85ylzLNb5Q3A0OAx4UtkTygFHkRZOK28kfCBWWnQzbs0ylD0IKOMQfGUqO5yItj7r/gbXTPe86Hdp35dBaddUBXhz8yDsr+ih++9/wXd/3mcCwtPKPgvwmYCnlD04axmyRTm/UHnS2Xd8hvp8BmBdwvCfkezzAOv8DmGNBK+ca5oC3B725uvyzre4HEr3JNdzmyrEV+sITyd77Wiu/wh8G5Q5py+ZHspVlmdDD0OedVhXgPWrJNvzJa47/7tSc8FANM41TQG2J+am5gtHymwJeM/xeGJRFm1vzD0krUcBaaQhgTwd0upEaLIKkMQQL+pbNnvTz8qeJqs/7WKea01UQJ52qyQR8vpUyukrxIv6Eq6MUC4rO6RV4i+rAkbJcC4eTSsSVwFlZRSpL83bFgWkHVq2QKeAmjXWKaBTQM0M1Fx9NwI6BdTMQM3VdyOgU0DNDNRc/XKOgJpJm2f1nQLmyWaErE4BEaTNs0ingHmyGSGrU0AEafMsogJK/cRmno1ZQVl7OgXUq/VdKsBfANbbjNWtPVGA/zlidSmot+c7HAEX1NuGla79gnX9ft+XW3fT0OLt4Ha5dwRYtf/aQ38KuktzZsAfmO97VQGa8EfHjoQ519GJm8CAPwpPjD6MAPP9zI8OC2HAY5ZJRakCGAXeB5JhkVzpPqpi4ES4TqzfClIFGAEeQu2WpRBRkXOal+NU/JAC0IzbEt/nqhnxOjdHBuR0y4DjVOyQAkwlQ5KRsD5eY52n2ULjYg70hrL6fT6yMrKyuVTaOatI/n6c7qcAqxoowReZLss9wZ80je2L/ckBFaCMHFkLZ5HDseQraWKjUcIe8EsyuTraT3Ok1+0kLbThKQK+uQovyr1OKV/ahJe4rOwkIeJDzjbLIXBqHytiogJCbgpvA18kriIcSgQb4zwRnby4mxb5PwTwopxlfUmUilBmlJBBIVeTW+UM+CavQfJ4b6YCQjGEqQinJZXhT3n8T0UqZKJ2Q9kKfa1ey3UESF5sVZb1lWe+/cp3FaVyZgTsu5buF1k52QRPTjfpMnNG+d67AAAA///vdBW6AAAABklEQVQDAJAXvRKwmZ6CAAAAAElFTkSuQmCC"/>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
BIN
src/assets/images/award/first_bg.png
Normal file
|
After Width: | Height: | Size: 340 KiB |
BIN
src/assets/images/award/form_bg.png
Normal file
|
After Width: | Height: | Size: 930 KiB |
BIN
src/assets/images/award/grand_bg.png
Normal file
|
After Width: | Height: | Size: 262 KiB |
BIN
src/assets/images/award/gregory.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
src/assets/images/award/jae.png
Normal file
|
After Width: | Height: | Size: 95 KiB |
BIN
src/assets/images/award/judges_bg.png
Normal file
|
After Width: | Height: | Size: 198 KiB |
10
src/assets/images/award/linkdin.svg
Normal file
@@ -0,0 +1,10 @@
|
||||
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_226_195)">
|
||||
<path d="M-0.00195312 1.4335C-0.00195312 0.641696 0.656004 0 1.46782 0H18.5422C19.354 0 20.0119 0.641696 20.0119 1.4335V18.5804C20.0119 19.3722 19.354 20.0139 18.5422 20.0139H1.46782C0.656004 20.0139 -0.00195312 19.3722 -0.00195312 18.5804V1.4335ZM6.18109 16.7541V7.71661H3.17776V16.7541H6.18109ZM4.68005 6.482C5.72703 6.482 6.37873 5.78902 6.37873 4.92092C6.35996 4.03405 5.72828 3.35983 4.70006 3.35983C3.67185 3.35983 3.00013 4.0353 3.00013 4.92092C3.00013 5.78902 3.65183 6.482 4.66003 6.482H4.68005ZM10.8193 16.7541V11.7069C10.8193 11.4367 10.8393 11.1665 10.9194 10.9739C11.1358 10.4347 11.6299 9.87561 12.4605 9.87561C13.5475 9.87561 13.9815 10.7037 13.9815 11.9195V16.7541H16.9848V11.5705C16.9848 8.79361 15.5038 7.50271 13.5274 7.50271C11.9338 7.50271 11.2196 8.37832 10.8193 8.995V9.02627H10.7993L10.8193 8.995V7.71661H7.81723C7.85475 8.5647 7.81723 16.7541 7.81723 16.7541H10.8193Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_226_195">
|
||||
<rect width="20.0139" height="20.0139" rx="1.55252" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/images/award/point.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
src/assets/images/award/prizes_bg.png
Normal file
|
After Width: | Height: | Size: 4.3 MiB |
BIN
src/assets/images/award/progress.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
src/assets/images/award/qrcode.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/images/award/second_bg.png
Normal file
|
After Width: | Height: | Size: 253 KiB |
BIN
src/assets/images/award/selection_bg.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
src/assets/images/award/successful.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
9
src/assets/images/award/tiktok.svg
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
BIN
src/assets/images/award/tim.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
BIN
src/assets/images/award/timeline_bg.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
src/assets/images/award/upload.png
Normal file
|
After Width: | Height: | Size: 225 KiB |
BIN
src/assets/images/award/upload_video_icon.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
src/assets/images/award/vincenzo.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
12
src/assets/images/award/weichat.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_226_203)">
|
||||
<path d="M20 17C20 18.6569 18.6569 20 17 20H3C1.34307 20 0 18.6569 0 17V3C0 1.34313 1.34313 0 3 0H17C18.6569 0 20 1.34313 20 3V17Z" fill="white"/>
|
||||
<path d="M13.3881 7.45803C11.7739 7.54236 10.3702 8.03169 9.2306 9.13723C8.0792 10.2542 7.55366 11.6228 7.69726 13.3195C7.06633 13.2414 6.49166 13.1554 5.91373 13.1067C5.71413 13.0899 5.47726 13.1138 5.3082 13.2092C4.747 13.5258 4.20906 13.8834 3.57133 14.282C3.68833 13.7528 3.76406 13.2894 3.89813 12.8437C3.99673 12.5161 3.95106 12.3338 3.64926 12.1204C1.71153 10.7523 0.894728 8.70496 1.50599 6.59703C2.07153 4.64703 3.46033 3.46443 5.3474 2.84796C7.92313 2.00663 10.8177 2.86483 12.3839 4.90976C12.9495 5.64843 13.2964 6.47749 13.3881 7.45803ZM5.95893 6.80123C5.9738 6.41569 5.63973 6.06836 5.24293 6.05676C4.83666 6.04483 4.50253 6.35529 4.49066 6.75563C4.47866 7.16136 4.789 7.48649 5.1982 7.49689C5.60386 7.50716 5.94393 7.19629 5.95893 6.80123ZM9.835 6.05649C9.43673 6.06383 9.1002 6.40303 9.10726 6.79009C9.11453 7.19129 9.44466 7.50516 9.8542 7.50023C10.2648 7.49529 10.5762 7.17809 10.5723 6.76843C10.5689 6.36629 10.2403 6.04909 9.835 6.05649Z" fill="#232323"/>
|
||||
<path d="M17.0146 17.5216C16.5035 17.294 16.0346 16.9525 15.5354 16.9004C15.0381 16.8484 14.5154 17.1353 13.9951 17.1885C12.4104 17.3506 10.9907 16.909 9.82001 15.8264C7.59355 13.767 7.91168 10.6094 10.4876 8.92184C12.777 7.42197 16.1345 7.92197 17.7487 10.0031C19.1573 11.8191 18.9917 14.2298 17.2721 15.7554C16.7745 16.1969 16.5955 16.5602 16.9148 17.1423C16.9737 17.2498 16.9804 17.3858 17.0146 17.5216ZM11.1963 11.8883C11.5217 11.8886 11.7897 11.634 11.802 11.3126C11.815 10.9723 11.5413 10.6869 11.2006 10.6855C10.8632 10.684 10.5806 10.9734 10.5924 11.3086C10.6035 11.6288 10.8733 11.8879 11.1963 11.8883ZM14.9471 10.6868C14.6314 10.6846 14.3631 10.9431 14.3502 11.2621C14.3365 11.6032 14.6017 11.8834 14.9393 11.8842C15.2658 11.8854 15.5239 11.6384 15.5357 11.3134C15.5483 10.9715 15.2831 10.6892 14.9471 10.6868Z" fill="#232323"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_226_203">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
4
src/assets/images/award/xiaohongshu.svg
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
247
src/lang/en.ts
@@ -1,3 +1,248 @@
|
||||
export default {
|
||||
|
||||
AwardsPage: {
|
||||
submitApplication: 'Submit your Application',
|
||||
applicationDeadline: 'Application Deadline:15th July 2026',
|
||||
howToApply: 'How to Apply',
|
||||
stepByStep: 'Step by step',
|
||||
step1Title: 'Step 1. Become an\nAiDA Subscriber',
|
||||
step1Desc:
|
||||
'All applicants must be active\nAiDA subscribers at the time of\nsubmission. You may subscribe\nunder either a monthly or yearly plan.',
|
||||
step2Title: 'Step 2. Create Your Design Using AiDA',
|
||||
step2Desc: 'Applicants must create their\ndesigns exclusively using the\nAiDA platform. ',
|
||||
step2ListTitle: 'Your work should clearly demonstrate:',
|
||||
step2List: [
|
||||
'· How AiDA is used as a creative tool',
|
||||
'· Your design concept and creative direction',
|
||||
'· The intergration of AI and human creativity'
|
||||
],
|
||||
step3Title: 'Step 3. Prepare Your Submission',
|
||||
processVideo: 'Process Video',
|
||||
processVideoDesc: 'Include a screen‑recorded video\nyour creative process\nusing AiDA.',
|
||||
videoRequirements: 'Video requirements:',
|
||||
videoFormat: 'Format: MP4',
|
||||
videoResolution: 'Resolution: 1080×1920 px',
|
||||
videoDuration: 'Duration: Maximum 1 minute',
|
||||
videoSize: 'File size: Maximum 20MB',
|
||||
fileName: 'File Name',
|
||||
fileNameDesc: 'AiDAGlobalDesignAward\n2026_[Your Full Name]',
|
||||
designPortfolio: 'Design Portfolio(PDF)',
|
||||
submitPdf: 'Submit one single PDF file that includes:',
|
||||
requiredStructure: 'Required structure:',
|
||||
pdfDesignTitle: 'Design title',
|
||||
pdfMoodboard: 'Moodboard',
|
||||
pdfConcept: 'Concept explanation',
|
||||
pdfConceptDesc: '(How to use AiDA to develop design)',
|
||||
pdfRequirements: 'PDF requirements:',
|
||||
pdfMaxPages: 'Maximum 15 pages',
|
||||
pdfMaxSize: 'Maximum file size: 20MB',
|
||||
pdfLanguage: 'Language: English or native language\nwith English translation',
|
||||
step4Title: 'Step 4. Finalist Requirement',
|
||||
step4Subtitle: '(for top 20 Designers)',
|
||||
step4Desc:
|
||||
'The 20 finalists will be required to\nsubmit physical garments for final\nevaluation',
|
||||
finalistPieces: 'Number of pieces: 1 full outfit',
|
||||
finalistBasedOn: 'Garments must be produced\nbased on the submitted\nAiDA-generated designs',
|
||||
finalistShipping: 'Shipping instructions will be provided by\nCode-create',
|
||||
bloomYourCreativity: 'Bloom Your Creativity',
|
||||
themeOf2026: 'Theme of 2026',
|
||||
bloomText: {
|
||||
desc1: {
|
||||
regular1: 'The',
|
||||
bold1: 'AiDA Global Design Award 2026',
|
||||
regular2: 'is an ',
|
||||
bold2: 'international design competition ',
|
||||
regular3: 'hosted by ',
|
||||
bold3: 'Code-create ',
|
||||
regular4: ', a globally leading\n',
|
||||
bold4: 'AI fashion solutions provider,',
|
||||
regular5:
|
||||
'celebrating the future of creativity powered by artificial intelligence.\nBringing together designers from around the world, AiDA empowers AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination.'
|
||||
},
|
||||
desc2: {
|
||||
regular1: 'Under the theme',
|
||||
bold1: '“Where Imagination Meets Innovation, Creativity Blooms,” ',
|
||||
regular2:
|
||||
'participants are invited to transform bold ideas into extraordinary designs, seamlessly merging human artistry with artificial intelligence to shape the next era of fashion.'
|
||||
}
|
||||
},
|
||||
bloomDesc1:
|
||||
'The AiDA Global Design Award 2026 is an\ninternational design competition hosted by\nCode‑Create, a globally leading AI fashion solutions provider,\ncelebrating the future of creativity powered by artificial intelligence.\nBringing together designers from around the world, AiDA empowers AI as a creative partner—pushing fashion beyond traditional boundaries and unlocking new possibilities where technology amplifies human imagination.',
|
||||
bloomDesc2:
|
||||
'Under the theme “Where Imagination Meets Innovation, Creativity Blooms,” participants are invited to transform bold ideas into extraordinary designs, seamlessly merging human artistry with artificial intelligence to shape the next era of fashion.',
|
||||
panelOfJudges: 'Panel of Judges',
|
||||
expertise: 'Expertise',
|
||||
judgesHat: {
|
||||
jae: 'Code-create\nKorea Branch Director\nBesfxxk creative director',
|
||||
diego: 'Co-founder & Chief Father\nOfficer of OnTheList\n(Hong Kong)',
|
||||
gregory: 'Senior Designer at\nGabriela Heasrst (Italy)',
|
||||
vincenzo: 'Cheif Editor of SCMP Style\n(Hong Kong)',
|
||||
tim: 'Group Fashion Direction of\n Modern Media Group\n(Shanghai)',
|
||||
desmond: 'Cheif Editor of Vogue\n(Singapore)'
|
||||
},
|
||||
awardPrizes: 'Award & Prizes',
|
||||
recognition: 'Recognition',
|
||||
grandMoney: 'US$5,000',
|
||||
goldMoney: 'US$3,000',
|
||||
silverMoney: 'US$1,000',
|
||||
grandAwards: 'Grand Awards',
|
||||
goldAwards: 'Gold Awards',
|
||||
silverAwards: 'Silver Awards',
|
||||
finalists: 'Finalists',
|
||||
cashAward: 'Cash Award',
|
||||
awardCertificate: 'Award Certificate',
|
||||
globalMediaExposure: 'Global Media Exposure',
|
||||
awardCertification: 'Award\nCertification',
|
||||
TravelAllowance: 'Travel Allowance',
|
||||
selectionCriteria: 'Selection Criteria',
|
||||
evaluation: 'Evaluation',
|
||||
originality: 'Originality',
|
||||
originalityDesc: 'Unique perspective and\ninnovative approach to\nfashion design',
|
||||
creativity: 'Creativity',
|
||||
creativityDesc: 'Artistic vision and exceptional\ndesign excellence',
|
||||
aidaIntegration: 'AiDA Integration',
|
||||
aidaIntegrationDesc: 'Effective application of\nAiDA functions',
|
||||
execution: 'Execution',
|
||||
executionDesc: 'Quality of presentation and\ntechnical craftsmanship',
|
||||
totalCashPrizes: 'UP TO\nUS$9000',
|
||||
totalCashPrizesLabel: 'In total cash prizes',
|
||||
globalMediaExpose: 'GLOBAL MEDIA\nEXPOSE',
|
||||
globalMediaExposeLabel: 'Showcased by top\ninternational media platforms',
|
||||
networkingOpportunities: 'NETWORKING\nOPPORTUNITIES',
|
||||
networkingOpportunitiesLabel: 'Build connections with\ndesigners and industry leaders',
|
||||
awardCeremonyHongKong: 'AWARD CEREMONY\nIN HONG KONG',
|
||||
awardCeremonyLabel: 'Travel allowance\nprovided for finalists',
|
||||
competitionTimeline: 'Competition Timeline',
|
||||
shapingTheFuture: 'Shaping the Future',
|
||||
timelineApplicationLabel: 'Application',
|
||||
timelineDeadlineLabel: 'Deadline',
|
||||
timeJul15: 'Jul 15',
|
||||
applicationDeadlineDesc: 'Application deadline and\nentry review process\nbegins.',
|
||||
twentyFinalistsAnnounced: '20 Finallists',
|
||||
announcedLabel: 'Announced',
|
||||
timeAug30: 'Aug 30',
|
||||
twentyFinalistsDesc: 'Announcement of 20\nfinalists entering final\nevaluation stage.',
|
||||
finalistSubmission: 'Finallist\nSubmission',
|
||||
submissionLabel: 'Deadline',
|
||||
timeSept30: 'Sept 30',
|
||||
finalistSubmissionDesc: 'Finalists submit\ncompleted outfits for\nfinal assessment.',
|
||||
receivingOutfits: 'Receiving Outfits',
|
||||
fromFinalistsLabel: 'from Finallists',
|
||||
timeOctober: 'October',
|
||||
receivingOutfitsDesc: 'AiDA receives physical\noutfits from all 20\nfinalists.',
|
||||
awardCeremony: 'Award',
|
||||
ceremonyLabel: 'Ceremony',
|
||||
timeNov12: 'Nov 12',
|
||||
awardCeremonyDesc: 'Award Ceremony &\nCommunity Gathering\n– Soho House.',
|
||||
submissionSuccessful: 'Submission Successful',
|
||||
submissionSuccessfulDesc:
|
||||
'Please review your submitted information in the AiDA in-platform message.\nYou may edit it if needed. Competition updates and results will be sent via email.',
|
||||
deadlinePassed: 'Application Deadline Passed',
|
||||
deadlinePassedDesc:
|
||||
'The submission deadline for AiDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications.',
|
||||
uploadInProgress: 'Upload in progress…',
|
||||
uploadSuccess: 'Uploaded Successfully',
|
||||
uploadFailed: 'Upload failed',
|
||||
pdfFileTip: 'PDF file, max 20MB',
|
||||
videoFileTip: 'Video file (MP4, MOV), 1080p, max 100MB',
|
||||
wechatTitle: 'WeChat Official Account',
|
||||
wechatDesc: 'Scan the QR code in WeChat'
|
||||
},
|
||||
AwardApply: {
|
||||
// 页面主标题区域
|
||||
applicationForm: 'Application Form',
|
||||
emailVerification: 'Email Verification',
|
||||
aidaUsersOnly: 'AiDA Users Only',
|
||||
slogan: 'BLOOM YOUR CREATIVITY • AIDA GLOBAL DESIGN AWARDS 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 agree to 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.',
|
||||
videoDurationExceeds: 'Video duration exceeds 60 seconds limit. Please upload a shorter video.',
|
||||
uploadFailed: 'Upload failed'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,95 +1,234 @@
|
||||
export default {
|
||||
Login: {
|
||||
Login: '登录',
|
||||
SignUp: '注册',
|
||||
LoginTo: '登录到',
|
||||
LoginTitle: '一个多智能体画布,用于快速、趋势驱动的设计迭代。',
|
||||
name: '姓名',
|
||||
email: '邮箱',
|
||||
password: '密码',
|
||||
enterName: '请输入姓名',
|
||||
enterEmail: '请输入邮箱',
|
||||
enterPassword: '请输入密码',
|
||||
forgetPassword: '忘记密码?',
|
||||
pleaseInputName: '请输入姓名',
|
||||
nameLengthError: '姓名长度必须在 {min} 到 {max} 个字符之间',
|
||||
pleaseInputEmail: '请输入邮箱',
|
||||
emailFormatError: '请输入正确的邮箱',
|
||||
pleaseInputPassword: '请输入密码',
|
||||
passwordLengthError: '密码长度必须在 {min} 到 {max} 个字符之间',
|
||||
pleaseTermsPolicy: '请同意条款、政策和费用',
|
||||
agreeTermsPolicy: '我同意 <span onclick="onClickPrivacy()">条款、政策</span> 和费用。',
|
||||
noAccountToSignUp: `还没有账号? <span onclick="onClickRegister()">注册</span>`,
|
||||
registerFor: '注册账号',
|
||||
registerTip: '一个多智能体画布,用于快速、趋势驱动的设计迭代。',
|
||||
havenAccountToLogin: `已经有账号? <span onclick="onClickLogin()">登录</span>`,
|
||||
verifyEmail: '验证您的邮箱地址',
|
||||
verifyCodeHasSent: '已发送验证码到 <span>{email}</span>',
|
||||
verifyCode: '请输入验证码',
|
||||
AwardsPage: {
|
||||
submitApplication: '提交申请',
|
||||
applicationDeadline: '申请期限:2026年7月15日',
|
||||
howToApply: '申请方法',
|
||||
stepByStep: '步骤指南',
|
||||
step1Title: '1. 成为 AiDA 订阅用户',
|
||||
step1Desc: '所有申请者在提交时必须是\n活跃的AiDA 订阅用户。\n您可以选择按月或按年订阅。',
|
||||
step2Title: '2. 通过 AiDA 设计您的作品',
|
||||
step2Desc: '申请者必须仅使用AiDA\n平台完成设计作品。',
|
||||
step2ListTitle: '您的作品应清楚体现以下内容:',
|
||||
step2List: ['· AiDA在创作中的应用方式', '· 您的设计理念和创意方向', '· AI与人类创意的融合'],
|
||||
step3Title: '3. 准备提交材料',
|
||||
processVideo: '创作过程视频',
|
||||
processVideoDesc: '请提供一段屏幕录制视频,展示您\n使用AiDA的创作过程。',
|
||||
videoRequirements: '视频要求:',
|
||||
videoFormat: '格式:MP4',
|
||||
videoResolution: '分辨率:1080×1920px',
|
||||
videoDuration: '时长:最长1分钟',
|
||||
videoSize: '文件大小:不超过20MB',
|
||||
fileName: '文件命名',
|
||||
fileNameDesc: 'AiDAGlobalDesignAward\n2026_[你的名字]',
|
||||
designPortfolio: '设计作品集(PDF)',
|
||||
submitPdf: '提交一份包含以下内容的单一PDF文件:',
|
||||
requiredStructure: '',
|
||||
pdfDesignTitle: '设计标题',
|
||||
pdfMoodboard: '灵感板,情绪板',
|
||||
pdfConcept: '概念说明',
|
||||
pdfConceptDesc: '(说明如何使用AiDA进行设计创作)',
|
||||
pdfRequirements: 'PDF要求:',
|
||||
pdfMaxPages: '最多15页',
|
||||
pdfMaxSize: '最大文件大小:不超过20MB',
|
||||
pdfLanguage: '语言:英文,或本国语言附带英文翻译',
|
||||
step4Title: '4. 决赛入围选手提交要求',
|
||||
step4Subtitle: '(前20名设计师)',
|
||||
step4Desc: '入围的20名决赛选手需提交实体服装以供最终评审。',
|
||||
finalistPieces: '件数:1件套装',
|
||||
finalistBasedOn: '服装要求:必须根据提交的AiDA生成设计制作',
|
||||
finalistShipping: '运输说明:\n将由Code-create提供',
|
||||
bloomYourCreativity: '绽放你的创造力',
|
||||
themeOf2026: '赛事主题',
|
||||
bloomText: {
|
||||
desc1: {
|
||||
regular1: '',
|
||||
bold1: 'AiDA全球设计奖2026',
|
||||
regular2: '是由全球领先的AI时尚解决方案提供商',
|
||||
bold2: ' Code-create ',
|
||||
regular3: '主办的',
|
||||
bold3: '国际设计竞赛,\n',
|
||||
regular4:
|
||||
'旨在庆祝人工只能赋能下的未来创意。该赛事汇聚来自世界各地的设计师,\n将AI视为创意伙伴,突破传统时尚边界,探索技术与人类想象力结合的无限可能。',
|
||||
bold4: '',
|
||||
regular5: ''
|
||||
},
|
||||
desc2: {
|
||||
regular1: '本届大赛以',
|
||||
bold1: '"想象遇见创新,创意绽放"',
|
||||
regular2:
|
||||
'为主题,邀请参赛者将大胆创意转化为非凡设计,\n在 AI 辅助下实现艺术与科技的完美融合。AiDA 鼓励设计师突破常规,挑战时尚边界,\n并通过平台展示才华,与全球同行、行业领袖及 AI 专家建立深度联系,共同探索未来设计的可能。'
|
||||
}
|
||||
},
|
||||
panelOfJudges: '终审评委团',
|
||||
expertise: '权威阵容',
|
||||
judgesHat: {
|
||||
jae: 'Code‑Create 韩国分公司总监\nBesfxxk 创意总监',
|
||||
diego: 'OnTheList(香港)\n联合创始人兼首席执行官',
|
||||
gregory: 'Gabriela Hearst\n(意大利)高级设计师',
|
||||
vincenzo: '《南华早报》Style 杂志\n(香港)主编',
|
||||
tim: '现代传播集团\n(上海)时尚总监',
|
||||
desmond: '《Vogue》\n(新加坡)主编'
|
||||
},
|
||||
awardPrizes: '奖项与奖金',
|
||||
recognition: '荣誉认可',
|
||||
grandMoney: '5,000美元',
|
||||
goldMoney: '3,000美元',
|
||||
silverMoney: '1,000美元',
|
||||
grandAwards: '最高奖项',
|
||||
goldAwards: '金奖',
|
||||
silverAwards: '银奖',
|
||||
finalists: '决赛选手',
|
||||
cashAward: '现金奖励',
|
||||
awardCertificate: '获奖证书',
|
||||
globalMediaExposure: '全球媒体曝光',
|
||||
awardCertification: '获奖认证',
|
||||
TravelAllowance: '差旅补贴',
|
||||
selectionCriteria: '作品评选',
|
||||
evaluation: '考量标准',
|
||||
originality: '原创性',
|
||||
originalityDesc: '作品应体现设计师的独到视角与创新方法,展现突破常规的创意与实验性设计。',
|
||||
creativity: '创造力',
|
||||
creativityDesc: '作品应展现设计师的艺术视野与卓越设计水准,体现高水平的创意表达与专业执行力。',
|
||||
aidaIntegration: 'AiDA 创意整合程度',
|
||||
aidaIntegrationDesc:
|
||||
'作品应充分利用 AiDA 功能, 展现 AI 辅助创作在设计中的 有效应用与创新整合。',
|
||||
execution: '样衣做工',
|
||||
executionDesc: '作品应具备高水平的呈现质量与精湛的技术工艺,体现专业执行力与细节把控能力。',
|
||||
totalCashPrizes: '最高可达9,000美元',
|
||||
totalCashPrizesLabel: '现金奖励总额',
|
||||
globalMediaExpose: '全球媒体曝光',
|
||||
globalMediaExposeLabel: '由国际顶级媒体平台展示',
|
||||
networkingOpportunities: '链接全球行业人脉',
|
||||
networkingOpportunitiesLabel: '对接设计师与行业领军人物',
|
||||
awardCeremonyHongKong: '香港颁奖盛会',
|
||||
awardCeremonyLabel: '入围者享有差旅支持',
|
||||
competitionTimeline: '赛事时间表',
|
||||
shapingTheFuture: '重要节点',
|
||||
timelineApplicationLabel: '申请期限',
|
||||
timelineDeadlineLabel: '',
|
||||
timeJul15: '7月15日',
|
||||
applicationDeadlineDesc: '申请截止日期及\n作品审核流程开始',
|
||||
twentyFinalistsAnnounced: '20名入围者揭晓',
|
||||
announcedLabel: '',
|
||||
timeAug30: '8月30日',
|
||||
twentyFinalistsDesc: '公布进入终评阶段的 20 名入围者',
|
||||
finalistSubmission: '入围设计作品',
|
||||
submissionLabel: '提交最后期限',
|
||||
timeSept30: '9月30日',
|
||||
finalistSubmissionDesc: '入围者上传完成的设计\n作品以进行终评',
|
||||
receivingOutfits: '入围者',
|
||||
fromFinalistsLabel: '提交成衣',
|
||||
timeOctober: '10月',
|
||||
receivingOutfitsDesc: 'AiDA 接收每位入围\n的1套实物服装',
|
||||
awardCeremony: '奖项颁发仪式',
|
||||
ceremonyLabel: '',
|
||||
timeNov12: '11月12日',
|
||||
awardCeremonyDesc: '颁奖盛典与设计师社\n群聚会 – Soho House',
|
||||
submissionSuccessful: '提交成功',
|
||||
submissionSuccessfulDesc:
|
||||
'请在 AiDA 平台内的消息中查看您提交的信息。如有需要,您可以进行修改。\n比赛的最新消息和结果将通过邮箱发送。',
|
||||
deadlinePassed: '申请截止日期已过',
|
||||
deadlinePassedDesc: 'AiDA 全球设计奖 2026 的作品提交已截止。\n我们不再接受新的报名。',
|
||||
uploadInProgress: '上传中…',
|
||||
uploadSuccess: '上传成功',
|
||||
uploadFailed: '上传失败',
|
||||
pdfFileTip: 'PDF文件,不超过20MB',
|
||||
videoFileTip: '视频文件(MP4, MOV),1080p,不超过100MB',
|
||||
wechatTitle: '微信公众号',
|
||||
wechatDesc: '请使用微信扫描二维码'
|
||||
},
|
||||
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 像素\n(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: '重新发送验证码倒计时 {time}',
|
||||
orContinueWith: '或者使用',
|
||||
googleLogin: '使用 Google 登录',
|
||||
wechatLogin: '使用微信登录',
|
||||
},
|
||||
Nuic: {
|
||||
hiName: '你好,{name}。',
|
||||
nuic1Title: `帮助 Fiphant 发现您空间中的 <b>'YOU'</b>。`,
|
||||
nuic1Tip: `让我们设置您的个人资料。几个快速的细节将帮助 Fiphant 理解您的需求并找到您正在寻找的内容。`,
|
||||
letsGo: '让我们开始,Fiphant!',
|
||||
skip: '跳过',
|
||||
next: '下一步',
|
||||
nuic2Title: `您理想中 <b>家的氛围</b> 是什么?`,
|
||||
loadMore: '加载更多',
|
||||
nuic3Title: `您在哪里 <b>工作</b> ?您从事什么 <b>工作</b> ?`,
|
||||
basedIn: '公司',
|
||||
role: '角色',
|
||||
allSet: '准备好了!',
|
||||
},
|
||||
Home: {
|
||||
creditsNum: '积分: {num}',
|
||||
newProject: '新建项目',
|
||||
home: '首页',
|
||||
history: '历史记录',
|
||||
today: '今天',
|
||||
yesterday: '昨天',
|
||||
earlierChat: '更早的',
|
||||
},
|
||||
Input: {
|
||||
placeholder: '请输入',
|
||||
selectPlaceholder: '请选择',
|
||||
type: '类型',
|
||||
area: '地区',
|
||||
style: '风格',
|
||||
types: {
|
||||
sofa: '沙发',
|
||||
desk: '书桌',
|
||||
chair: '椅子'
|
||||
},
|
||||
styles: {
|
||||
modern: '现代',
|
||||
classic: '古典'
|
||||
},
|
||||
chooseStyle: '选择风格',
|
||||
setting: 'Setting',
|
||||
settingOptions: {
|
||||
creativity: '创意度',
|
||||
diversity: '多样性',
|
||||
relevance: '相关度'
|
||||
},
|
||||
confirm: '确认'
|
||||
},
|
||||
area: {
|
||||
unitedStates: '美国',
|
||||
singapore: '新加坡',
|
||||
australia: '澳大利亚',
|
||||
southKorea: '韩国',
|
||||
china: '中国',
|
||||
italy: '意大利',
|
||||
france: '法国',
|
||||
japan: '日本',
|
||||
canada: '加拿大',
|
||||
germany: '德国'
|
||||
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} 限制。请上传较小的文件。',
|
||||
videoDurationExceeds: '视频时长不可超过60秒',
|
||||
uploadFailed: '上传失败'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,14 +12,22 @@ const router = createRouter({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/index'
|
||||
name:'award',
|
||||
component:()=>import('@/views/AwardPage/container.vue'),
|
||||
children:[
|
||||
{
|
||||
path:'',
|
||||
name:'AwardIndex',
|
||||
component:()=>import('@/views/AwardPage/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/index',
|
||||
name: 'index',
|
||||
component: () => import('../views/home/index.vue')
|
||||
path:'contestants',
|
||||
component:()=>import('@/views/AwardPage/apply.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
{
|
||||
path: '/:pathMatch(.*)',
|
||||
name: '404',
|
||||
|
||||
35
src/utils/cookie.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
const setCookie = (name, value) => {
|
||||
var Days = 100
|
||||
var exp = new Date()
|
||||
exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000)
|
||||
document.cookie = name + '=' + escape(value) + ';expires=' + exp.toGMTString() + ';Path=/'
|
||||
// document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString()+ ";Path=/home";
|
||||
}
|
||||
|
||||
const getCookie = (name) => {
|
||||
var arr,
|
||||
reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)')
|
||||
if ((arr = document.cookie.match(reg))) return unescape(arr[2])
|
||||
else return null
|
||||
}
|
||||
|
||||
function WriteCookie(name) {
|
||||
var now = new Date()
|
||||
now.setMonth(now.getMonth() - 1)
|
||||
// cookievalue = escape(document.myform.customer.value) + ";"
|
||||
|
||||
document.cookie = name + '=' + '' + ';Path=/'
|
||||
document.cookie = 'expires=' + now.toUTCString() + ';Path=/'
|
||||
// document.write("Setting Cookies : " + "name=" + cookievalue );
|
||||
}
|
||||
function clonAllCookie() {
|
||||
var cookies = document.cookie.split(';')
|
||||
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = cookies[i]
|
||||
var eqPos = cookie.indexOf('=')
|
||||
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie
|
||||
document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'
|
||||
}
|
||||
}
|
||||
export { setCookie, getCookie, WriteCookie, clonAllCookie }
|
||||
1686
src/views/AwardPage/apply.vue
Normal file
529
src/views/AwardPage/components/ApplySection.vue
Normal file
@@ -0,0 +1,529 @@
|
||||
<template>
|
||||
<div
|
||||
class="apply-container flex flex-col"
|
||||
id="apply"
|
||||
ref="applyRef"
|
||||
>
|
||||
<div
|
||||
class="title animation-element"
|
||||
ref="applyTitleRef"
|
||||
>
|
||||
{{ $t('AwardsPage.howToApply') }}
|
||||
</div>
|
||||
<div
|
||||
class="sub-title animation-element"
|
||||
ref="applySubTitleRef"
|
||||
>
|
||||
{{ $t('AwardsPage.stepByStep') }}
|
||||
</div>
|
||||
<div
|
||||
class="requirments-list flex flex-col"
|
||||
ref="reqListRef"
|
||||
>
|
||||
<div class="top flex">
|
||||
<div
|
||||
class="item-box animation-element"
|
||||
v-for="(item, index) in leftRequirment"
|
||||
:key="item.type"
|
||||
:ref="el => { if(el) itemRefs[index] = el }"
|
||||
:style="{ background: item.background || '#fff' }"
|
||||
>
|
||||
<div class="item-header flex flex-center">
|
||||
<div class="item-title">{{ $t(item.type) }}</div>
|
||||
</div>
|
||||
<div class="context-container flex flex-center">
|
||||
<div
|
||||
class="context"
|
||||
v-for="el in item.desc"
|
||||
>
|
||||
{{ $t(el) }}
|
||||
</div>
|
||||
<div
|
||||
class="list"
|
||||
v-if="item.listTitle"
|
||||
>
|
||||
<div class="list-title">{{ $t(item.listTitle) }}</div>
|
||||
<ul class="list-items">
|
||||
<li
|
||||
class="list-item"
|
||||
v-for="el in item.list"
|
||||
>
|
||||
{{ $t(el) }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom flex">
|
||||
<div class="step-3 flex flex-col animation-element" ref="step3Ref">
|
||||
<div class="header">{{ $t('AwardsPage.step3Title') }}</div>
|
||||
<div class="content flex">
|
||||
<div class="content-left flex flex-col space-between">
|
||||
<div class="content-item">
|
||||
<div class="item-header flex align-center">
|
||||
<div class="point"></div>
|
||||
<div>{{ $t('AwardsPage.processVideo') }}</div>
|
||||
</div>
|
||||
<div class="desc-wrapper flex flex-col space-between">
|
||||
<div class="item-desc">
|
||||
{{ $t('AwardsPage.processVideoDesc') }}
|
||||
</div>
|
||||
<ul class="desc-lists">
|
||||
<div class="desc-lists-title">
|
||||
{{ $t('AwardsPage.videoRequirements') }}
|
||||
</div>
|
||||
<li>{{ $t('AwardsPage.videoFormat') }}</li>
|
||||
<li>{{ $t('AwardsPage.videoResolution') }}</li>
|
||||
<li>{{ $t('AwardsPage.videoDuration') }}</li>
|
||||
<li>{{ $t('AwardsPage.videoSize') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-item">
|
||||
<div class="item-header flex align-center">
|
||||
<div class="point"></div>
|
||||
<div>{{ $t('AwardsPage.fileName') }}</div>
|
||||
</div>
|
||||
<div class="item-desc indent">
|
||||
{{ $t('AwardsPage.fileNameDesc') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-right">
|
||||
<div class="content-item flex flex-col">
|
||||
<div class="item-header flex align-center">
|
||||
<div class="point"></div>
|
||||
<div>{{ $t('AwardsPage.designPortfolio') }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="desc-wrapper flex-1 flex flex-col space-between"
|
||||
>
|
||||
<ul class="desc-lists">
|
||||
<div class="desc-lists-title">
|
||||
<p>
|
||||
{{ $t('AwardsPage.submitPdf') }}
|
||||
</p>
|
||||
<p>{{ $t('AwardsPage.requiredStructure') }}</p>
|
||||
</div>
|
||||
<li>{{ $t('AwardsPage.pdfDesignTitle') }}</li>
|
||||
<li>{{ $t('AwardsPage.pdfMoodboard') }}</li>
|
||||
<li>{{ $t('AwardsPage.pdfConcept') }}</li>
|
||||
<div>{{ $t('AwardsPage.pdfConceptDesc') }}</div>
|
||||
</ul>
|
||||
<ul class="desc-lists">
|
||||
<div class="desc-lists-title">
|
||||
<p>{{ $t('AwardsPage.pdfRequirements') }}</p>
|
||||
</div>
|
||||
<li>{{ $t('AwardsPage.pdfMaxPages') }}</li>
|
||||
<li>{{ $t('AwardsPage.pdfMaxSize') }}</li>
|
||||
<li>
|
||||
{{ $t('AwardsPage.pdfLanguage') }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-4 animation-element" ref="step4Ref">
|
||||
<div class="header flex flex-col flex-center">
|
||||
<p>{{ $t('AwardsPage.step4Title') }}</p>
|
||||
<p class="sub-title">{{ $t('AwardsPage.step4Subtitle') }}</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="content-item">
|
||||
<div class="desc-wrapper flex-1 flex flex-col space-between">
|
||||
<ul class="desc-lists">
|
||||
<div class="desc-lists-title">
|
||||
{{ $t('AwardsPage.step4Desc') }}
|
||||
</div>
|
||||
<li>{{ $t('AwardsPage.finalistPieces') }}</li>
|
||||
<li>
|
||||
{{ $t('AwardsPage.finalistBasedOn') }}
|
||||
</li>
|
||||
<li>
|
||||
{{ $t('AwardsPage.finalistShipping') }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { gsap } from 'gsap'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const leftRequirment = ref([
|
||||
{
|
||||
type: 'AwardsPage.step1Title',
|
||||
desc: ['AwardsPage.step1Desc']
|
||||
},
|
||||
{
|
||||
type: 'AwardsPage.step2Title',
|
||||
desc: ['AwardsPage.step2Desc'],
|
||||
listTitle: 'AwardsPage.step2ListTitle',
|
||||
list: [
|
||||
'AwardsPage.step2List[0]',
|
||||
'AwardsPage.step2List[1]',
|
||||
'AwardsPage.step2List[2]'
|
||||
],
|
||||
background: '#F9F9F9'
|
||||
}
|
||||
])
|
||||
|
||||
const applyRef = ref()
|
||||
const applyTitleRef = ref()
|
||||
const applySubTitleRef = ref()
|
||||
const reqListRef = ref()
|
||||
const itemRefs = ref<HTMLElement[]>([])
|
||||
const step3Ref = ref()
|
||||
const step4Ref = ref()
|
||||
|
||||
const hasPlayedAnim = ref(false)
|
||||
let timeline: gsap.core.Timeline | null = null
|
||||
|
||||
let observer: IntersectionObserver | null = null
|
||||
|
||||
const setupApplyInitialState = () => {
|
||||
// 设置标题和副标题的初始状态
|
||||
const titleEls = [applyTitleRef.value, applySubTitleRef.value].filter(
|
||||
Boolean
|
||||
) as HTMLElement[]
|
||||
if (titleEls.length) {
|
||||
gsap.set(titleEls, {
|
||||
opacity: 0,
|
||||
scale: 0,
|
||||
transformOrigin: '50% 50%'
|
||||
})
|
||||
}
|
||||
|
||||
// 设置步骤元素的初始状态
|
||||
const allStepElements: HTMLElement[] = []
|
||||
if (itemRefs.value && itemRefs.value.length > 0) {
|
||||
allStepElements.push(...itemRefs.value)
|
||||
}
|
||||
if (step3Ref.value) {
|
||||
allStepElements.push(step3Ref.value as HTMLElement)
|
||||
}
|
||||
if (step4Ref.value) {
|
||||
allStepElements.push(step4Ref.value as HTMLElement)
|
||||
}
|
||||
|
||||
if (allStepElements.length > 0) {
|
||||
gsap.set(allStepElements, {
|
||||
opacity: 0,
|
||||
y: 50
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const initAnimations = () => {
|
||||
if (hasPlayedAnim.value) return
|
||||
|
||||
timeline = gsap.timeline({
|
||||
defaults: { ease: 'back.out(1.7)' }
|
||||
})
|
||||
|
||||
if (applyTitleRef.value && applySubTitleRef.value) {
|
||||
timeline.to([applyTitleRef.value, applySubTitleRef.value], {
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
duration: 0.6,
|
||||
stagger: 0.1
|
||||
})
|
||||
}
|
||||
|
||||
const allStepElements: HTMLElement[] = []
|
||||
if (itemRefs.value && itemRefs.value.length > 0) {
|
||||
allStepElements.push(...itemRefs.value)
|
||||
}
|
||||
if (step3Ref.value) {
|
||||
allStepElements.push(step3Ref.value as HTMLElement)
|
||||
}
|
||||
if (step4Ref.value) {
|
||||
allStepElements.push(step4Ref.value as HTMLElement)
|
||||
}
|
||||
|
||||
if (allStepElements.length > 0) {
|
||||
timeline.to(allStepElements, {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
duration: 0.6,
|
||||
stagger: 0.2
|
||||
}, '>')
|
||||
}
|
||||
|
||||
hasPlayedAnim.value = true
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
setupApplyInitialState()
|
||||
observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
initAnimations()
|
||||
observer?.disconnect()
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
threshold: 0.3,
|
||||
rootMargin: '0px 0px -100px 0px'
|
||||
}
|
||||
)
|
||||
|
||||
// Start observing the component root element
|
||||
if (applyRef.value) {
|
||||
observer.observe(applyRef.value)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
// Cleanup animation timeline
|
||||
if (timeline) {
|
||||
timeline.kill()
|
||||
}
|
||||
// Cleanup IntersectionObserver
|
||||
if (observer) {
|
||||
observer.disconnect()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.animation-element{
|
||||
will-change: opacity transform;
|
||||
}
|
||||
.apply-container {
|
||||
flex: 1;
|
||||
height: 143.3rem;
|
||||
background: url('@/assets/images/award/apply_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 12.7rem 21.4rem 12rem;
|
||||
.title {
|
||||
text-align: center;
|
||||
color: #232323;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 4rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
.sub-title {
|
||||
text-align: center;
|
||||
color: #b10000;
|
||||
font-size: 3rem;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
margin-bottom: 8.2rem;
|
||||
}
|
||||
.requirments-list {
|
||||
flex: 1;
|
||||
row-gap: 8.2rem;
|
||||
.top {
|
||||
height: 27.4rem;
|
||||
color: #585858;
|
||||
column-gap: 4.6rem;
|
||||
.item-box {
|
||||
height: 27.4rem;
|
||||
}
|
||||
}
|
||||
.item-box {
|
||||
border-radius: 0.8rem;
|
||||
&:nth-of-type(1) {
|
||||
width: 47rem;
|
||||
flex-grow: initial;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
flex: 1;
|
||||
}
|
||||
.item-header {
|
||||
background-color: #424242;
|
||||
border-radius: 0.8rem;
|
||||
height: 7.8rem;
|
||||
.item-title {
|
||||
color: #fff;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 2.4rem;
|
||||
text-align: center;
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
.context-container {
|
||||
margin-top: 4rem;
|
||||
column-gap: 7rem;
|
||||
.list {
|
||||
font-family: 'Instrument';
|
||||
font-weight: 400;
|
||||
font-size: 2.4rem;
|
||||
line-height: 3rem;
|
||||
}
|
||||
}
|
||||
.context {
|
||||
// margin-top: 4rem;
|
||||
// width: 46.8rem;
|
||||
text-align: center;
|
||||
color: #585858;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
line-height: 3rem;
|
||||
font-size: 2.4rem;
|
||||
// padding-left: 5.6rem;
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
.bottom {
|
||||
column-gap: 4.6rem;
|
||||
height: 63.4rem;
|
||||
.step-3 {
|
||||
flex: 1;
|
||||
}
|
||||
.step-3,
|
||||
.step-4 {
|
||||
.header {
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 2.4rem;
|
||||
text-align: center;
|
||||
height: 7.4rem;
|
||||
line-height: 7.4rem;
|
||||
color: #fff;
|
||||
background-color: #b10000;
|
||||
border-radius: 0.8rem;
|
||||
}
|
||||
.content {
|
||||
padding: 4rem;
|
||||
border-radius: 0.8rem;
|
||||
column-gap: 6.4rem;
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
#ffe8e8 0%,
|
||||
#feefef 25%,
|
||||
#f9f9f9 100%
|
||||
);
|
||||
flex: 1;
|
||||
.content-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.content-item {
|
||||
.item-header {
|
||||
column-gap: 2rem;
|
||||
color: #585858;
|
||||
font-family: 'InstrumentBold';
|
||||
font-weight: 700;
|
||||
font-size: 2.4rem;
|
||||
line-height: 3rem;
|
||||
.point {
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
background-color: #b10000;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.item-desc {
|
||||
font-family: 'Instrument';
|
||||
font-weight: 400;
|
||||
font-size: 2.4rem;
|
||||
color: #585858;
|
||||
&.indent {
|
||||
padding-left: 3.8rem;
|
||||
line-height: 3rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
}
|
||||
.desc-wrapper {
|
||||
margin-top: 3rem;
|
||||
/* 基线行高变量,供子元素计算方块垂直偏移以对齐首行 */
|
||||
--desc-line-height: 3rem;
|
||||
font-family: 'Instrument';
|
||||
font-weight: 400;
|
||||
color: #585858;
|
||||
font-size: 2.4rem;
|
||||
line-height: 3rem;
|
||||
row-gap: 3rem;
|
||||
.desc-lists {
|
||||
/* 使用自定义方块代替浏览器 marker,保证大小为 1rem 并与文字垂直居中 */
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
li {
|
||||
list-style: none;
|
||||
/* 使内容对齐到首行顶部,方块通过 margin-top 调整到首行中间 */
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 1rem;
|
||||
padding: 0;
|
||||
margin: 0.4rem 0;
|
||||
&::before {
|
||||
content: '';
|
||||
/* 固定为 1rem 方块 */
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
background-color: #585858;
|
||||
flex: 0 0 0.5rem;
|
||||
border-radius: 0;
|
||||
/* 让方块垂直居中于第一行文字:(line-height - square)/2 */
|
||||
margin-top: calc(
|
||||
(var(--desc-line-height, 3rem) - 1rem) / 2
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-right {
|
||||
.content-item {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.step-4 {
|
||||
width: 45.1rem;
|
||||
.header {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #424242;
|
||||
border-radius: 0.8rem;
|
||||
height: 7.8rem;
|
||||
white-space: pre-line;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 2.4rem;
|
||||
line-height: 1.5;
|
||||
.sub-title {
|
||||
font-family: 'Poppins';
|
||||
font-weight: 400;
|
||||
font-size: 1.8rem;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
202
src/views/AwardPage/components/Bloom.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="bloom flex flex-col align-center">
|
||||
<div
|
||||
class="title"
|
||||
ref="titleRef"
|
||||
>
|
||||
{{ $t('AwardsPage.bloomYourCreativity') }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="season"
|
||||
ref="subtitleRef"
|
||||
>
|
||||
{{ $t('AwardsPage.themeOf2026') }}
|
||||
</div>
|
||||
<div
|
||||
class="desc"
|
||||
ref="textRef"
|
||||
>
|
||||
<p class="section-1">
|
||||
{{ $t('AwardsPage.bloomText.desc1.regular1') }}
|
||||
<span class="arial-bold">
|
||||
{{ $t('AwardsPage.bloomText.desc1.bold1') }}
|
||||
</span>
|
||||
{{ $t('AwardsPage.bloomText.desc1.regular2') }}
|
||||
<span class="arial-bold">
|
||||
{{ $t('AwardsPage.bloomText.desc1.bold2') }}
|
||||
</span>
|
||||
{{ $t('AwardsPage.bloomText.desc1.regular3') }}
|
||||
<span class="arial-bold">
|
||||
{{ $t('AwardsPage.bloomText.desc1.bold3') }}
|
||||
</span>
|
||||
{{ $t('AwardsPage.bloomText.desc1.regular4') }}
|
||||
<span class="arial-bold">
|
||||
{{ $t('AwardsPage.bloomText.desc1.bold4') }}
|
||||
</span>
|
||||
{{ $t('AwardsPage.bloomText.desc1.regular5') }}
|
||||
</p>
|
||||
<p class="section-2">
|
||||
{{ $t('AwardsPage.bloomText.desc2.regular1') }}
|
||||
<span class="arial-bold">
|
||||
{{ $t('AwardsPage.bloomText.desc2.bold1') }}
|
||||
</span>
|
||||
{{ $t('AwardsPage.bloomText.desc2.regular2') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { gsap } from 'gsap'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const titleRef = ref<HTMLElement | null>(null)
|
||||
const subtitleRef = ref<HTMLElement | null>(null)
|
||||
const textRef = ref<HTMLElement | null>(null)
|
||||
|
||||
const hasPlayedBloomAnim = ref(false)
|
||||
let bloomObserver: IntersectionObserver | null = null
|
||||
|
||||
const setupBloomInitialState = () => {
|
||||
const titleEls = [titleRef.value, subtitleRef.value].filter(
|
||||
Boolean
|
||||
) as HTMLElement[]
|
||||
if (titleEls.length) {
|
||||
gsap.set(titleEls, {
|
||||
opacity: 0,
|
||||
// start larger than final size, then animate down to scale:1
|
||||
scale: 1.6,
|
||||
transformOrigin: '50% 50%'
|
||||
})
|
||||
}
|
||||
|
||||
if (textRef.value) {
|
||||
// start below and hidden
|
||||
gsap.set(textRef.value, {
|
||||
opacity: 0,
|
||||
y: 60
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const playBloomAnimation = () => {
|
||||
if (hasPlayedBloomAnim.value) return
|
||||
const titleEls = [titleRef.value, subtitleRef.value].filter(
|
||||
Boolean
|
||||
) as HTMLElement[]
|
||||
const textEl = textRef.value
|
||||
if (!titleEls.length || !textEl) return
|
||||
|
||||
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
||||
|
||||
tl.to(titleEls, {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
duration: 0.9,
|
||||
ease: 'back.out(1.6)',
|
||||
stagger: 0.12
|
||||
})
|
||||
|
||||
tl.to(
|
||||
textEl,
|
||||
{
|
||||
opacity: 1,
|
||||
y: -12,
|
||||
scale: 1.05,
|
||||
duration: 0.3,
|
||||
ease: 'power2.out'
|
||||
},
|
||||
'-=0.3'
|
||||
)
|
||||
tl.to(
|
||||
textEl,
|
||||
{
|
||||
y: 0,
|
||||
scale: 1,
|
||||
duration: 0.18,
|
||||
ease: 'bounce.out'
|
||||
},
|
||||
'+=0.08'
|
||||
)
|
||||
|
||||
hasPlayedBloomAnim.value = true
|
||||
bloomObserver?.disconnect()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
setupBloomInitialState()
|
||||
if ('IntersectionObserver' in window) {
|
||||
bloomObserver = new IntersectionObserver(
|
||||
entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
playBloomAnimation()
|
||||
}
|
||||
})
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
)
|
||||
if (titleRef.value) {
|
||||
bloomObserver.observe(titleRef.value)
|
||||
}
|
||||
} else {
|
||||
// fallback
|
||||
playBloomAnimation()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
bloomObserver?.disconnect()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.arial-bold {
|
||||
font-family: 'ArialBold';
|
||||
font-weight: 700;
|
||||
}
|
||||
.bloom {
|
||||
height: 108rem;
|
||||
padding-top: 12.8rem;
|
||||
font-family: 'Poppins';
|
||||
background: url('@/assets/images/award/bloom_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
.title {
|
||||
font-size: 4rem;
|
||||
color: #232323;
|
||||
margin-bottom: 2.4rem;
|
||||
}
|
||||
.logo {
|
||||
margin-bottom: 2.2rem;
|
||||
}
|
||||
.season {
|
||||
font-size: 3rem;
|
||||
color: #c7342c;
|
||||
margin-bottom: 6.6rem;
|
||||
}
|
||||
.desc {
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
font-size: 2.4rem;
|
||||
color: #585858;
|
||||
text-align: center;
|
||||
padding: 0 21.5rem;
|
||||
line-height: 4.5rem;
|
||||
margin-bottom: 12.3rem;
|
||||
white-space: pre-line;
|
||||
.section-2 {
|
||||
margin-top: 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
233
src/views/AwardPage/components/JudgesSection.vue
Normal file
@@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<div class="judges-container flex flex-col align-center">
|
||||
<div class="title" ref="judgesTitleRef">{{ $t('AwardsPage.panelOfJudges') }}</div>
|
||||
<!-- <img src="@/assets/images/award/bloom_logo.png" class="logo" /> -->
|
||||
<div class="sub-title" ref="judgesSubTitleRef">{{ $t('AwardsPage.expertise') }}</div>
|
||||
<div class="judgement-list" ref="judgementListRef">
|
||||
<div
|
||||
class="judgement-item flex flex-col align-center"
|
||||
v-for="item in judgements"
|
||||
:key="item.name"
|
||||
>
|
||||
<img :src="item.picture" class="picture" />
|
||||
<div class="name">{{ $t(item.name) }}</div>
|
||||
<div class="desc">{{ $t(item.desc) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, onMounted, nextTick, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { gsap } from 'gsap'
|
||||
import jae from '@/assets/images/award/jae.png'
|
||||
import diego from '@/assets/images/award/diego.png'
|
||||
import gregory from '@/assets/images/award/gregory.png'
|
||||
import vincenzo from '@/assets/images/award/vincenzo.png'
|
||||
import tim from '@/assets/images/award/tim.png'
|
||||
import desmond from '@/assets/images/award/desmond.png'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const judgements = [
|
||||
{
|
||||
picture: jae,
|
||||
name: 'Jae Hyuk Lim',
|
||||
desc: 'AwardsPage.judgesHat.jae'
|
||||
},
|
||||
{
|
||||
picture: diego,
|
||||
name: 'Diego Dultzin Lacoste',
|
||||
desc: 'AwardsPage.judgesHat.diego'
|
||||
},
|
||||
{
|
||||
picture: gregory,
|
||||
name: 'Gregory de la Hogue Moran',
|
||||
desc: 'AwardsPage.judgesHat.gregory'
|
||||
},
|
||||
{
|
||||
picture: vincenzo,
|
||||
name: 'Vincenzo La Torre',
|
||||
desc: 'AwardsPage.judgesHat.vincenzo'
|
||||
},
|
||||
{
|
||||
picture: tim,
|
||||
name: 'Tim Lim',
|
||||
desc: 'AwardsPage.judgesHat.tim'
|
||||
},
|
||||
{
|
||||
picture: desmond,
|
||||
name: 'Desmond Lim',
|
||||
desc: 'AwardsPage.judgesHat.desmond'
|
||||
}
|
||||
]
|
||||
|
||||
const judgesTitleRef = ref<HTMLElement | null>(null)
|
||||
const judgesSubTitleRef = ref<HTMLElement | null>(null)
|
||||
const judgementListRef = ref<HTMLElement | null>(null)
|
||||
const hasPlayedJudgementAnim = ref(false)
|
||||
let judgementObserver: IntersectionObserver | null = null
|
||||
|
||||
const setupJudgementInitialState = () => {
|
||||
const titleEls = [judgesTitleRef.value, judgesSubTitleRef.value].filter(
|
||||
Boolean
|
||||
) as HTMLElement[]
|
||||
if (titleEls.length) {
|
||||
gsap.set(titleEls, {
|
||||
opacity: 0,
|
||||
scale: 0,
|
||||
transformOrigin: '50% 50%'
|
||||
})
|
||||
}
|
||||
const items =
|
||||
judgementListRef.value?.querySelectorAll<HTMLElement>('.judgement-item')
|
||||
if (items?.length) {
|
||||
gsap.set(items, {
|
||||
opacity: 0,
|
||||
clipPath: 'inset(0 0 100% 0)'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const playJudgementAnimation = () => {
|
||||
if (hasPlayedJudgementAnim.value) return
|
||||
const titleEls = [judgesTitleRef.value, judgesSubTitleRef.value].filter(
|
||||
Boolean
|
||||
) as HTMLElement[]
|
||||
const listEl = judgementListRef.value
|
||||
if (!titleEls.length || !listEl) return
|
||||
|
||||
const items = Array.from(
|
||||
listEl.querySelectorAll<HTMLElement>('.judgement-item')
|
||||
)
|
||||
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
||||
|
||||
tl.to(titleEls, {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
duration: 0.4,
|
||||
ease: 'back.out(1.6)',
|
||||
stagger: 0.1
|
||||
})
|
||||
if (items.length) {
|
||||
const firstRow = items.slice(0, 3)
|
||||
const secondRow = items.slice(3)
|
||||
|
||||
if (firstRow.length) {
|
||||
tl.to(
|
||||
firstRow,
|
||||
{
|
||||
opacity: 1,
|
||||
clipPath: 'inset(0% 0% 0% 0%)',
|
||||
duration: 0.45,
|
||||
stagger: 0.05
|
||||
},
|
||||
'-=0.2'
|
||||
)
|
||||
}
|
||||
|
||||
if (secondRow.length) {
|
||||
tl.to(
|
||||
secondRow,
|
||||
{
|
||||
opacity: 1,
|
||||
clipPath: 'inset(0% 0% 0% 0%)',
|
||||
duration: 0.45,
|
||||
stagger: 0.05
|
||||
},
|
||||
'+=0.1'
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
hasPlayedJudgementAnim.value = true
|
||||
judgementObserver?.disconnect()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
setupJudgementInitialState()
|
||||
if ('IntersectionObserver' in window) {
|
||||
judgementObserver = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
playJudgementAnimation()
|
||||
}
|
||||
})
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
)
|
||||
if (judgementListRef.value) {
|
||||
judgementObserver.observe(judgementListRef.value)
|
||||
}
|
||||
} else {
|
||||
// Fallback: play immediately if IntersectionObserver unsupported
|
||||
playJudgementAnimation()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
judgementObserver?.disconnect()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.judges-container {
|
||||
height: 147.4rem;
|
||||
background: url('@/assets/images/award/judges_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding-top: 12.8rem;
|
||||
.title {
|
||||
color: #232323;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 4rem;
|
||||
}
|
||||
.logo {
|
||||
margin: 2.4rem 0 2.2rem;
|
||||
}
|
||||
.sub-title {
|
||||
color: #b10000;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
font-size: 3rem;
|
||||
margin-bottom: 12rem;
|
||||
}
|
||||
.judgement-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
column-gap: 23.22rem;
|
||||
row-gap: 8rem;
|
||||
padding: 0 25rem 0 26.6rem;
|
||||
div{
|
||||
text-align: center;
|
||||
}
|
||||
.judgement-item {
|
||||
overflow: hidden;
|
||||
.picture {
|
||||
width: 20.2rem;
|
||||
height: 26rem;
|
||||
border-radius: 0.8rem;
|
||||
}
|
||||
.name {
|
||||
margin: 3rem 0 2.4rem;
|
||||
color: #232323;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
.desc {
|
||||
color: #585858;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
font-size: 2rem;
|
||||
white-space: pre-line;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
276
src/views/AwardPage/components/PrizesSection.vue
Normal file
@@ -0,0 +1,276 @@
|
||||
<template>
|
||||
<div
|
||||
class="prizes-container container flex align-center space-between"
|
||||
ref="prizesRef"
|
||||
>
|
||||
<div class="left flex flex-col flex-center">
|
||||
<div
|
||||
class="title"
|
||||
ref="prizesTitleRef"
|
||||
>
|
||||
{{ $t('AwardsPage.awardPrizes') }}
|
||||
</div>
|
||||
<!-- <img src="@/assets/images/award/bloom_logo.png" class="logo" /> -->
|
||||
<div
|
||||
class="desc"
|
||||
ref="prizesSubTitleRef"
|
||||
>
|
||||
{{ $t('AwardsPage.recognition') }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="right"
|
||||
ref="prizesRightRef"
|
||||
>
|
||||
<div
|
||||
class="prize-item flex flex-col flex-center"
|
||||
:class="{ smaller: item.smaller }"
|
||||
v-for="item in prizes"
|
||||
:key="item.name"
|
||||
>
|
||||
<div class="prize-money">
|
||||
{{ $t(item.money) }}
|
||||
</div>
|
||||
<div class="prize-name">{{ $t(item.name) }}</div>
|
||||
<div class="prize-desc flex flex-col flex-center">
|
||||
<div
|
||||
class="desc-item"
|
||||
v-for="el in item.desc"
|
||||
>
|
||||
{{ $t(el) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { gsap } from 'gsap'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
isZh: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const prizes = [
|
||||
{
|
||||
money: 'AwardsPage.grandMoney',
|
||||
name: 'AwardsPage.grandAwards',
|
||||
desc: [
|
||||
'AwardsPage.cashAward',
|
||||
'AwardsPage.awardCertificate',
|
||||
'AwardsPage.globalMediaExposure'
|
||||
]
|
||||
},
|
||||
{
|
||||
money: 'AwardsPage.goldMoney',
|
||||
name: 'AwardsPage.goldAwards',
|
||||
desc: [
|
||||
'AwardsPage.cashAward',
|
||||
'AwardsPage.awardCertificate',
|
||||
'AwardsPage.globalMediaExposure'
|
||||
]
|
||||
},
|
||||
{
|
||||
money: 'AwardsPage.silverMoney',
|
||||
name: 'AwardsPage.silverAwards',
|
||||
desc: [
|
||||
'AwardsPage.cashAward',
|
||||
'AwardsPage.awardCertificate',
|
||||
'AwardsPage.globalMediaExposure'
|
||||
]
|
||||
},
|
||||
{
|
||||
money: 'AwardsPage.awardCertification',
|
||||
name: 'AwardsPage.finalists',
|
||||
desc: ['AwardsPage.TravelAllowance', 'AwardsPage.globalMediaExposure'],
|
||||
smaller: !props.isZh
|
||||
}
|
||||
]
|
||||
|
||||
const prizesRef = ref<HTMLElement | null>(null)
|
||||
const prizesTitleRef = ref<HTMLElement | null>(null)
|
||||
const prizesSubTitleRef = ref<HTMLElement | null>(null)
|
||||
const prizesRightRef = ref<HTMLElement | null>(null)
|
||||
const hasPlayedPrizesAnim = ref(false)
|
||||
let prizesObserver: IntersectionObserver | null = null
|
||||
|
||||
const setupPrizesInitialState = () => {
|
||||
const titleEls = [prizesTitleRef.value, prizesSubTitleRef.value].filter(
|
||||
Boolean
|
||||
) as HTMLElement[]
|
||||
if (titleEls.length) {
|
||||
gsap.set(titleEls, {
|
||||
opacity: 0,
|
||||
scale: 0,
|
||||
transformOrigin: '50% 50%'
|
||||
})
|
||||
}
|
||||
if (prizesRightRef.value) {
|
||||
gsap.set(prizesRightRef.value, {
|
||||
'opacity': 0,
|
||||
'y': 40,
|
||||
'scale': 1.08,
|
||||
'--prize-row-gap': '2rem',
|
||||
'--prize-col-gap': '2rem'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const playPrizesAnimation = () => {
|
||||
if (hasPlayedPrizesAnim.value) return
|
||||
const titleEls = [prizesTitleRef.value, prizesSubTitleRef.value].filter(
|
||||
Boolean
|
||||
) as HTMLElement[]
|
||||
|
||||
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
||||
if (titleEls.length) {
|
||||
tl.to(titleEls, {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
duration: 0.6,
|
||||
ease: 'back.out(1.6)',
|
||||
stagger: 0.1
|
||||
})
|
||||
}
|
||||
if (prizesRightRef.value) {
|
||||
tl.to(
|
||||
prizesRightRef.value,
|
||||
{
|
||||
'opacity': 1,
|
||||
'y': 0,
|
||||
'scale': 1,
|
||||
'--prize-row-gap': '4.2rem',
|
||||
'--prize-col-gap': '4.4rem',
|
||||
'duration': 0.55,
|
||||
'ease': 'back.out(1.4)'
|
||||
},
|
||||
titleEls.length ? '-=0.15' : 0
|
||||
)
|
||||
}
|
||||
|
||||
hasPlayedPrizesAnim.value = true
|
||||
prizesObserver?.disconnect()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
setupPrizesInitialState()
|
||||
if ('IntersectionObserver' in window) {
|
||||
prizesObserver = new IntersectionObserver(
|
||||
entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
playPrizesAnimation()
|
||||
}
|
||||
})
|
||||
},
|
||||
{ threshold: 0.25 }
|
||||
)
|
||||
if (prizesRef.value) prizesObserver.observe(prizesRef.value)
|
||||
} else {
|
||||
playPrizesAnimation()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
prizesObserver?.disconnect()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.prizes-container {
|
||||
background: url('@/assets/images/award/prizes_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding: 0 21.4rem 0 34.2rem;
|
||||
box-sizing: border-box;
|
||||
.left {
|
||||
row-gap: 3.6rem;
|
||||
.title {
|
||||
text-align: center;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 4rem;
|
||||
color: #fff;
|
||||
}
|
||||
.desc {
|
||||
text-align: center;
|
||||
color: #f95750;
|
||||
font-family: 'Poppins';
|
||||
font-weight: 400;
|
||||
font-size: 3rem;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
// height: 45.4rem;
|
||||
// padding: 4.6rem 6.1rem 4.6rem 0;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: repeat(2, 1fr);
|
||||
row-gap: var(--prize-row-gap, 4.2rem);
|
||||
column-gap: var(--prize-col-gap, 4.4rem);
|
||||
// flex: 1;
|
||||
.prize-item {
|
||||
width: 35.5rem;
|
||||
height: 32.8rem;
|
||||
color: #fff;
|
||||
padding: 4.5rem 0 4.8rem 0;
|
||||
justify-content: space-between;
|
||||
background: url('@/assets/images/award/first_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
&:nth-of-type(2) {
|
||||
background: url('@/assets/images/award/second_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
&:nth-of-type(3) {
|
||||
background: url('@/assets/images/award/grand_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
&:nth-of-type(4) {
|
||||
background: url('@/assets/images/award/certification_bg.png')
|
||||
no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
&.smaller {
|
||||
.prize-money {
|
||||
font-size: 3.6rem;
|
||||
line-height: 3.8rem;
|
||||
}
|
||||
}
|
||||
.prize-money {
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: bold;
|
||||
font-size: 4rem;
|
||||
white-space: pre-line;
|
||||
text-align: center;
|
||||
line-height: 7.6rem;
|
||||
&.smaller {
|
||||
font-size: 3.6rem;
|
||||
}
|
||||
}
|
||||
.prize-name {
|
||||
font-family: 'PoppinsMedium';
|
||||
font-weight: 500;
|
||||
font-size: 2.8rem;
|
||||
}
|
||||
.prize-desc {
|
||||
color: #e0e0e0;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
font-size: 2rem;
|
||||
line-height: 3rem;
|
||||
height: 8.9rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
177
src/views/AwardPage/components/SelectionSection.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<div
|
||||
class="selection-container container flex flex-col align-center"
|
||||
ref="selectionRef"
|
||||
>
|
||||
<div class="title">{{ $t('AwardsPage.selectionCriteria') }}</div>
|
||||
<!-- <img src="@/assets/images/award/bloom_logo.png" class="logo" /> -->
|
||||
<div class="sub-title">{{ $t('AwardsPage.evaluation') }}</div>
|
||||
<div class="criteria-list flex" ref="criteriaListRef">
|
||||
<div
|
||||
class="item flex flex-col align-center"
|
||||
v-for="item in criteriaList"
|
||||
:key="item.name"
|
||||
>
|
||||
<img :src="item.icon" class="icon" :style="item.style" />
|
||||
<div class="name">{{ $t(item.name) }}</div>
|
||||
<div class="desc">{{ $t(item.desc) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { gsap } from 'gsap'
|
||||
import criteria1 from '@/assets/images/award/criteria_1.png'
|
||||
import criteria2 from '@/assets/images/award/criteria_2.png'
|
||||
import criteria3 from '@/assets/images/award/criteria_3.png'
|
||||
import criteria4 from '@/assets/images/award/criteria_4.png'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const criteriaList = ref([
|
||||
{
|
||||
icon: criteria1,
|
||||
name: 'AwardsPage.originality',
|
||||
desc: 'AwardsPage.originalityDesc',
|
||||
style: { width: '13rem', height: '17rem' }
|
||||
},
|
||||
{
|
||||
icon: criteria2,
|
||||
name: 'AwardsPage.creativity',
|
||||
desc: 'AwardsPage.creativityDesc',
|
||||
style: { width: '16rem', height: '18rem' }
|
||||
},
|
||||
{
|
||||
icon: criteria3,
|
||||
name: 'AwardsPage.aidaIntegration',
|
||||
desc: 'AwardsPage.aidaIntegrationDesc',
|
||||
style: { width: '16rem', height: '18rem' }
|
||||
},
|
||||
{
|
||||
icon: criteria4,
|
||||
name: 'AwardsPage.execution',
|
||||
desc: 'AwardsPage.executionDesc',
|
||||
style: { width: '18.8rem', height: '18rem' }
|
||||
}
|
||||
])
|
||||
|
||||
const selectionRef = ref<HTMLElement | null>(null)
|
||||
const criteriaListRef = ref<HTMLElement | null>(null)
|
||||
const hasPlayedSelectionAnim = ref(false)
|
||||
let selectionObserver: IntersectionObserver | null = null
|
||||
|
||||
const setupSelectionInitialState = () => {
|
||||
const items =
|
||||
criteriaListRef.value?.querySelectorAll<HTMLElement>('.item') ?? []
|
||||
if (items.length) {
|
||||
gsap.set(items, {
|
||||
opacity: 0,
|
||||
scale: 0,
|
||||
transformOrigin: '50% 50%'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const playSelectionAnimation = () => {
|
||||
if (hasPlayedSelectionAnim.value) return
|
||||
const items =
|
||||
criteriaListRef.value?.querySelectorAll<HTMLElement>('.item') ?? []
|
||||
if (!items.length) return
|
||||
|
||||
gsap.to(items, {
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
duration: 0.6,
|
||||
ease: 'back.out(1.6)',
|
||||
stagger: 0.3
|
||||
})
|
||||
|
||||
hasPlayedSelectionAnim.value = true
|
||||
selectionObserver?.disconnect()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
setupSelectionInitialState()
|
||||
if ('IntersectionObserver' in window) {
|
||||
selectionObserver = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
playSelectionAnimation()
|
||||
}
|
||||
})
|
||||
},
|
||||
{ threshold: 0.25 }
|
||||
)
|
||||
if (selectionRef.value) {
|
||||
selectionObserver.observe(selectionRef.value)
|
||||
}
|
||||
} else {
|
||||
playSelectionAnimation()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
selectionObserver?.disconnect()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.selection-container {
|
||||
background: url('@/assets/images/award/selection_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
padding-top: 9.3rem;
|
||||
.title {
|
||||
color: #fff;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 4rem;
|
||||
}
|
||||
.logo {
|
||||
margin: 2.3rem 0 2.3rem;
|
||||
}
|
||||
.sub-title {
|
||||
color: #f95750;
|
||||
font-family: 'Popins';
|
||||
font-weight: 400;
|
||||
font-size: 3rem;
|
||||
margin-bottom: 11.8rem;
|
||||
}
|
||||
.criteria-list {
|
||||
column-gap: 6rem;
|
||||
.item {
|
||||
height: 44rem;
|
||||
width: 32.2rem;
|
||||
box-sizing: border-box;
|
||||
&:nth-of-type(3) {
|
||||
background: url('@/assets/images/award/criteria_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
.icon {
|
||||
width: 18.8rem;
|
||||
height: 18rem;
|
||||
}
|
||||
.name {
|
||||
font-family: 'PoppinsMedium';
|
||||
font-weight: 500;
|
||||
font-size: 2.8rem;
|
||||
color: #fff;
|
||||
margin: 2rem 0 5rem;
|
||||
}
|
||||
.desc {
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
font-size: 2.4rem;
|
||||
color: #e0e0e0;
|
||||
text-align: center;
|
||||
white-space: pre-line;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
156
src/views/AwardPage/components/Slogan.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<div
|
||||
class="blocks-list flex"
|
||||
ref="root"
|
||||
:class="{ 'in-view': inView }"
|
||||
>
|
||||
<div
|
||||
class="block-item flex flex-col flex-center"
|
||||
v-for="(item, idx) in blocksList"
|
||||
:key="item.number"
|
||||
:style="{ '--delay': `${idx * 0.18}s` }"
|
||||
>
|
||||
<div class="number">{{ $t(item.number) }}</div>
|
||||
<div class="label">{{ $t(item.label) }}</div>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, onMounted, onUnmounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const blocksList = ref([
|
||||
{
|
||||
number: 'AwardsPage.totalCashPrizes',
|
||||
label: 'AwardsPage.totalCashPrizesLabel'
|
||||
},
|
||||
{
|
||||
number: 'AwardsPage.globalMediaExpose',
|
||||
label: 'AwardsPage.globalMediaExposeLabel'
|
||||
},
|
||||
{
|
||||
number: 'AwardsPage.networkingOpportunities',
|
||||
label: 'AwardsPage.networkingOpportunitiesLabel'
|
||||
},
|
||||
{
|
||||
number: 'AwardsPage.awardCeremonyHongKong',
|
||||
label: 'AwardsPage.awardCeremonyLabel'
|
||||
}
|
||||
])
|
||||
const root = ref<HTMLElement | null>(null)
|
||||
const inView = ref(false)
|
||||
let io: IntersectionObserver | null = null
|
||||
|
||||
onMounted(() => {
|
||||
io = new IntersectionObserver(
|
||||
entries => {
|
||||
for (const entry of entries) {
|
||||
if (entry.isIntersecting) {
|
||||
// 延迟 0.5s 后触发动画并断开观察
|
||||
setTimeout(() => {
|
||||
inView.value = true
|
||||
}, 500)
|
||||
if (io) {
|
||||
io.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{ threshold: 0.05 }
|
||||
)
|
||||
if (root.value) {
|
||||
io.observe(root.value)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
io?.disconnect()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.blocks-list {
|
||||
height: 31.4rem;
|
||||
background: linear-gradient(98.55deg, #232323 18.22%, #898989 101.1%);
|
||||
|
||||
.block-item {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
white-space: pre-line;
|
||||
row-gap: 3rem;
|
||||
/* text scale-in animations */
|
||||
.number {
|
||||
font-size: 3.6rem;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
.label {
|
||||
font-size: 2.4rem;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.05em;
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
/* vertical line grows top -> bottom */
|
||||
.line {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
/* 固定 top 为最终高度的一半位置,这样 height 从 0 -> 27.4rem 时会从上向下增长 */
|
||||
top: calc(50% - 13.7rem);
|
||||
width: 0.1rem;
|
||||
height: 0;
|
||||
background-color: #8d8d8d;
|
||||
will-change: height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 当组件进入视口并且等待 0.5s 后,.in-view 会加入根节点,下面规则触发动画 */
|
||||
.in-view .block-item .number {
|
||||
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
||||
animation-delay: var(--delay);
|
||||
}
|
||||
|
||||
.in-view .block-item .label {
|
||||
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
||||
animation-delay: calc(var(--delay) + 0.12s);
|
||||
}
|
||||
|
||||
.in-view .block-item .line {
|
||||
animation: growLine 0.7s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
||||
animation-delay: calc(var(--delay) + 0.18s);
|
||||
}
|
||||
|
||||
/* keyframes */
|
||||
@keyframes scaleIn {
|
||||
from {
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes growLine {
|
||||
from {
|
||||
height: 0;
|
||||
}
|
||||
to {
|
||||
height: 27.4rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
81
src/views/AwardPage/components/Success.vue
Normal file
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div class="success-container flex flex-col align-center">
|
||||
<img
|
||||
:src="info.icon"
|
||||
alt=""
|
||||
class="icon-img"
|
||||
/>
|
||||
<div class="title">{{ $t(info.title) }}</div>
|
||||
<div class="desc">
|
||||
{{ $t(info.desc) }}
|
||||
<!-- <div>
|
||||
Please review your submitted information in the AiDA in-platform message.
|
||||
</div>
|
||||
<div>
|
||||
You may edit it if needed. Competition updates and results will be sent
|
||||
via email.
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import successIcon from '@/assets/images/award/successful.png'
|
||||
import expiredIcon from '@/assets/images/award/expired.png'
|
||||
|
||||
const { t } = useI18n()
|
||||
const props = defineProps({
|
||||
isExpired: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const info = computed(() => {
|
||||
if (props.isExpired) {
|
||||
return {
|
||||
icon: expiredIcon,
|
||||
title: 'AwardsPage.deadlinePassed',
|
||||
desc: 'AwardsPage.deadlinePassedDesc'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
icon: successIcon,
|
||||
title: 'AwardsPage.submissionSuccessful',
|
||||
desc: 'AwardsPage.submissionSuccessfulDesc'
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.success-container {
|
||||
margin: 0 21.5rem;
|
||||
padding: 10.6rem 27.3rem 0;
|
||||
height: 50rem;
|
||||
position: relative;
|
||||
top: -16.8rem;
|
||||
background-color: #fff;
|
||||
border-radius: 0.8rem;
|
||||
.icon-img {
|
||||
width: 12rem;
|
||||
height: 12rem;
|
||||
}
|
||||
.title {
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 3rem;
|
||||
color: #232323;
|
||||
text-align: center;
|
||||
margin: 2rem 0 4rem;
|
||||
}
|
||||
.desc {
|
||||
color: #585858;
|
||||
font-family: Arial;
|
||||
font-weight: 400;
|
||||
font-size: 2.4rem;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
370
src/views/AwardPage/components/TimeLine.vue
Normal file
@@ -0,0 +1,370 @@
|
||||
<template>
|
||||
<div
|
||||
ref="containerRef"
|
||||
class="timeline-container container flex flex-col align-center"
|
||||
>
|
||||
<div class="timeline-title">{{ $t('AwardsPage.competitionTimeline') }}</div>
|
||||
<div class="desc">{{ $t('AwardsPage.shapingTheFuture') }}</div>
|
||||
<div
|
||||
class="timeline-point"
|
||||
ref="timelineRef"
|
||||
>
|
||||
<!-- 顶部标签行 -->
|
||||
<div class="grid-row labels-row">
|
||||
<div
|
||||
class="grid-cell label-cell"
|
||||
v-for="item in points"
|
||||
:key="'label-' + item.time"
|
||||
>
|
||||
<div class="main-label">{{ $t(item.label) }}</div>
|
||||
<div
|
||||
class="sub-label"
|
||||
v-if="item.subLabel"
|
||||
>
|
||||
{{ $t(item.subLabel) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图标行 -->
|
||||
<div class="grid-row icons-row">
|
||||
<div class="timeline-line"></div>
|
||||
<div
|
||||
class="grid-cell icon-cell"
|
||||
v-for="item in points"
|
||||
:key="'icon-' + item.time"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/award/point.png"
|
||||
class="point-icon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 时间行 -->
|
||||
<div class="grid-row times-row">
|
||||
<div
|
||||
class="grid-cell time-cell"
|
||||
v-for="item in points"
|
||||
:key="'time-' + item.time"
|
||||
>
|
||||
{{ $t(item.time) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 描述行 -->
|
||||
<div class="grid-row descs-row">
|
||||
<div
|
||||
class="grid-cell desc-cell"
|
||||
v-for="item in points"
|
||||
:key="'desc-' + item.time"
|
||||
>
|
||||
<div class="txt">
|
||||
{{ $t(item.desc) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, onBeforeUnmount, onMounted, ref, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { gsap } from 'gsap'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const containerRef = ref<HTMLElement | null>(null)
|
||||
const timelineRef = ref<HTMLElement | null>(null)
|
||||
const hasAnimated = ref(false)
|
||||
|
||||
const points = ref([
|
||||
{
|
||||
label: 'AwardsPage.timelineApplicationLabel',
|
||||
subLabel: 'AwardsPage.timelineDeadlineLabel',
|
||||
time: 'AwardsPage.timeJul15',
|
||||
desc: 'AwardsPage.applicationDeadlineDesc'
|
||||
},
|
||||
{
|
||||
label: 'AwardsPage.twentyFinalistsAnnounced',
|
||||
subLabel: 'AwardsPage.announcedLabel',
|
||||
time: 'AwardsPage.timeAug30',
|
||||
desc: 'AwardsPage.twentyFinalistsDesc'
|
||||
},
|
||||
{
|
||||
label: 'AwardsPage.finalistSubmission',
|
||||
subLabel: 'AwardsPage.submissionLabel',
|
||||
time: 'AwardsPage.timeSept30',
|
||||
desc: 'AwardsPage.finalistSubmissionDesc'
|
||||
},
|
||||
{
|
||||
label: 'AwardsPage.receivingOutfits',
|
||||
subLabel: 'AwardsPage.fromFinalistsLabel',
|
||||
time: 'AwardsPage.timeOctober',
|
||||
desc: 'AwardsPage.receivingOutfitsDesc'
|
||||
},
|
||||
{
|
||||
label: 'AwardsPage.awardCeremony',
|
||||
subLabel: 'AwardsPage.ceremonyLabel',
|
||||
time: 'AwardsPage.timeNov12',
|
||||
desc: 'AwardsPage.awardCeremonyDesc'
|
||||
}
|
||||
])
|
||||
|
||||
const playAnimation = () => {
|
||||
if (!containerRef.value || hasAnimated.value) return
|
||||
const title = containerRef.value.querySelector('.timeline-title')
|
||||
const subtitle = containerRef.value.querySelector('.desc')
|
||||
const line = containerRef.value.querySelector('.timeline-line')
|
||||
const timeline = containerRef.value.querySelector('.timeline-point')
|
||||
|
||||
const tl = gsap.timeline()
|
||||
|
||||
// 我们使用一个统一的开始 label,使横线、timeline 裁剪与所有文字同时启动,
|
||||
// 点图标在它们完成后立即开始。
|
||||
tl.addLabel('start')
|
||||
|
||||
// 整体 timeline 的裁剪展开(与 start 同步)
|
||||
if (timeline) {
|
||||
tl.fromTo(
|
||||
timeline,
|
||||
{
|
||||
clipPath: 'inset(0 100% 0 0)'
|
||||
},
|
||||
{
|
||||
clipPath: 'inset(0 0% 0 0)',
|
||||
duration: 1.3,
|
||||
ease: 'power1.out'
|
||||
},
|
||||
'start'
|
||||
)
|
||||
}
|
||||
|
||||
// 线条动画(与 start 同步)
|
||||
if (line) {
|
||||
tl.from(
|
||||
line,
|
||||
{
|
||||
scaleX: 0,
|
||||
transformOrigin: '0% 50%',
|
||||
duration: 1.3,
|
||||
ease: 'power1.out'
|
||||
},
|
||||
'start'
|
||||
)
|
||||
}
|
||||
|
||||
// 标题与副标题(与 start 同步)
|
||||
if (title && subtitle) {
|
||||
tl.from(
|
||||
[title, subtitle],
|
||||
{
|
||||
scaleX: 0,
|
||||
autoAlpha: 0.5,
|
||||
transformOrigin: '50% 50%',
|
||||
duration: 0.6,
|
||||
stagger: 0.1,
|
||||
ease: 'power2.out'
|
||||
},
|
||||
'start'
|
||||
)
|
||||
}
|
||||
|
||||
// 行内文字(标签、时间、描述、图标)与 start 同步开始
|
||||
const textItems = containerRef.value.querySelectorAll('.grid-cell')
|
||||
if (textItems && textItems.length) {
|
||||
tl.from(
|
||||
textItems,
|
||||
{
|
||||
// autoAlpha: 0.5,
|
||||
duration: 0.7,
|
||||
stagger: 0.08,
|
||||
ease: 'power2.out'
|
||||
},
|
||||
'start'
|
||||
)
|
||||
}
|
||||
|
||||
hasAnimated.value = true
|
||||
}
|
||||
|
||||
let observer: IntersectionObserver | null = null
|
||||
|
||||
onMounted(async () => {
|
||||
await nextTick()
|
||||
if (!containerRef.value) return
|
||||
observer = new IntersectionObserver(
|
||||
entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
playAnimation()
|
||||
}
|
||||
})
|
||||
},
|
||||
{ threshold: 0.3 }
|
||||
)
|
||||
observer.observe(containerRef.value)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (observer && containerRef.value) {
|
||||
observer.unobserve(containerRef.value)
|
||||
}
|
||||
observer = null
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.timeline-container {
|
||||
background: url('@/assets/images/award/timeline_bg.png') no-repeat;
|
||||
background-size: 100% 100%;
|
||||
position: relative;
|
||||
padding: 12.8rem 0 15.9rem;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
.timeline-title {
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 4rem;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.logo {
|
||||
margin: 2.4rem 0 2.2rem 0;
|
||||
}
|
||||
.desc {
|
||||
font-family: 'Arial';
|
||||
font-size: 3rem;
|
||||
font-weight: 400;
|
||||
color: #f95750;
|
||||
}
|
||||
.timeline-point {
|
||||
overflow: hidden;
|
||||
will-change: clip-path;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
margin-top: 11rem;
|
||||
padding: 0 13.8rem;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
// 主网格布局:5列
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-template-rows: auto auto auto auto;
|
||||
grid-column-gap: 0;
|
||||
grid-row-gap: 0;
|
||||
|
||||
// 所有 grid 子行的通用样式
|
||||
.grid-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
.grid-cell {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
// 图标行
|
||||
.icons-row {
|
||||
align-items: center;
|
||||
height: 6.4rem;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
margin-bottom: 1.6rem;
|
||||
|
||||
.timeline-line {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -22rem;
|
||||
right: -21.2rem;
|
||||
height: 0.15rem;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(199, 52, 44, 0) 0%,
|
||||
rgba(199, 52, 44, 0.719626) 25.96%,
|
||||
#c7342c 51.44%,
|
||||
rgba(199, 52, 44, 0.762376) 75.96%,
|
||||
rgba(199, 52, 44, 0) 100%
|
||||
);
|
||||
transform: translateY(-50%);
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.icon-cell {
|
||||
position: relative;
|
||||
.point-icon {
|
||||
width: 6.4rem;
|
||||
height: 6.4rem;
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 标签行
|
||||
.labels-row {
|
||||
margin-bottom: 8rem;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
.label-cell {
|
||||
flex-direction: column;
|
||||
color: #fff;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 2.8rem;
|
||||
white-space: pre-line;
|
||||
justify-content: center;
|
||||
min-height: 6rem;
|
||||
|
||||
// .sub-label {
|
||||
// font-family: 'Arial';
|
||||
// font-weight: 400;
|
||||
// font-size: 1.4rem;
|
||||
// color: rgba(255, 255, 255, 0.8);
|
||||
// margin-top: 0.4rem;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// 时间行
|
||||
.times-row {
|
||||
margin-bottom: 6rem;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
.time-cell {
|
||||
color: #f95750;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
font-size: 2.8rem;
|
||||
line-height: 4.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
// 描述行
|
||||
.descs-row {
|
||||
.desc-cell {
|
||||
.txt {
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
font-size: 2rem;
|
||||
text-align: center;
|
||||
color: #e0e0e0;
|
||||
width: 100%;
|
||||
max-width: 31.2rem;
|
||||
min-height: 10.2rem;
|
||||
white-space: pre-line;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
82
src/views/AwardPage/components/UploadStatus.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<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">{{ $t(text) }}</div>
|
||||
<div class="tips">{{ $t(tips) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const props = defineProps<{
|
||||
status: string
|
||||
type: 'pdf' | 'video'
|
||||
}>()
|
||||
|
||||
const textMap: Record<string, string> = {
|
||||
idle: '',
|
||||
uploading: 'AwardsPage.uploadInProgress',
|
||||
success:'AwardsPage.uploadSuccess',
|
||||
error: 'AwardsPage.fileUploadFailed'
|
||||
}
|
||||
|
||||
const tips = computed(() => {
|
||||
if (props.type === 'pdf') {
|
||||
return 'AwardsPage.pdfFileTip'
|
||||
} else if (props.type === 'video') {
|
||||
return 'AwardsPage.videoFileTip'
|
||||
}
|
||||
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>
|
||||
191
src/views/AwardPage/components/VerificationCodeInput.vue
Normal file
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div class="captcha">
|
||||
<input
|
||||
v-for="(c, index) in getCtData"
|
||||
:key="index"
|
||||
type="text"
|
||||
v-model="getCtData[index]"
|
||||
ref="inputRefs"
|
||||
inputmode="numeric"
|
||||
pattern="[0-9]*"
|
||||
@input="e => onInput(e.target.value, index)"
|
||||
@keydown="e => onKeydown(e, index)"
|
||||
@keypress="e => onKeypress(e)"
|
||||
@focus="onFocus"
|
||||
@pause="onPause"
|
||||
:disabled="loading"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
|
||||
interface Props {
|
||||
ct: string[]
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'sendCaptcha', password: string): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const loading = ref(false)
|
||||
const timeout = ref<NodeJS.Timeout | null>(null)
|
||||
const inputRefs = ref<HTMLInputElement[]>([])
|
||||
|
||||
const getCtData = computed({
|
||||
get: () => props.ct,
|
||||
set: (value: string[]) => {
|
||||
// 这里需要特殊处理,因为computed通常是只读的
|
||||
// 但原代码中直接修改了getCtData,所以这里需要emit一个事件或者使用其他方式
|
||||
// 由于这是父组件传来的props,我们需要通过emit通知父组件更新
|
||||
props.ct.splice(0, props.ct.length, ...value)
|
||||
}
|
||||
})
|
||||
|
||||
const ctSize = computed(() => getCtData.value.length)
|
||||
|
||||
const cIndex = computed(() => {
|
||||
let i = getCtData.value.findIndex(item => item === '')
|
||||
i = (i + ctSize.value) % ctSize.value
|
||||
return i
|
||||
})
|
||||
|
||||
const lastCode = computed(() => getCtData.value[ctSize.value - 1])
|
||||
|
||||
watch(cIndex, () => {
|
||||
resetCaret()
|
||||
})
|
||||
|
||||
watch(lastCode, (newVal, oldVal) => {
|
||||
if (newVal && newVal !== oldVal) {
|
||||
inputRefs.value[ctSize.value - 1]?.blur()
|
||||
sendCaptcha()
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
resetCaret()
|
||||
})
|
||||
|
||||
const onInput = (val: string, index: number) => {
|
||||
if (timeout.value) {
|
||||
clearTimeout(timeout.value)
|
||||
}
|
||||
timeout.value = setTimeout(() => {
|
||||
val = String(val).replace(/\D/g, '')
|
||||
getCtData.value[index] = val
|
||||
if (index === ctSize.value - 1) {
|
||||
getCtData.value[ctSize.value - 1] = val[0] // 最后一个码,只允许输入一个字符。
|
||||
} else if (val.length > 1) {
|
||||
let i = index
|
||||
for (i = index; i < ctSize.value && i - index < val.length; i++) {
|
||||
getCtData.value[i] = val[i - index]
|
||||
}
|
||||
resetCaret()
|
||||
} else if (!(val + '')) {
|
||||
getCtData.value[index] = ''
|
||||
}
|
||||
}, 10)
|
||||
}
|
||||
|
||||
const onPause = () => {}
|
||||
|
||||
const resetCaret = () => {
|
||||
inputRefs.value[ctSize.value - 1]?.focus()
|
||||
}
|
||||
|
||||
const onFocus = () => {
|
||||
// 监听 focus 事件,将光标重定位到"第一个空白符的位置"。
|
||||
let index = getCtData.value.findIndex(item => item === '')
|
||||
index = (index + ctSize.value) % ctSize.value
|
||||
inputRefs.value[index]?.focus()
|
||||
}
|
||||
|
||||
const onKeypress = (e: KeyboardEvent) => {
|
||||
// 只允许输入数字0-9
|
||||
const char = String.fromCharCode((e as any).which)
|
||||
if (!/[0-9]/.test(char)) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
const onKeydown = (e: KeyboardEvent, index: number) => {
|
||||
// 处理删除键
|
||||
if (e.key === 'Backspace' || e.key === 'Delete') {
|
||||
const val = (e.target as HTMLInputElement).value
|
||||
if (val === '') {
|
||||
// 删除上一个input里的值,并对其focus。
|
||||
if (index > 0) {
|
||||
getCtData.value[index - 1] = ''
|
||||
inputRefs.value[index - 1]?.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
// 阻止其他非数字字符
|
||||
else if (
|
||||
e.key &&
|
||||
!/[0-9]/.test(e.key) &&
|
||||
![
|
||||
'Backspace',
|
||||
'Delete',
|
||||
'Tab',
|
||||
'Enter',
|
||||
'ArrowLeft',
|
||||
'ArrowRight',
|
||||
'ArrowUp',
|
||||
'ArrowDown'
|
||||
].includes(e.key)
|
||||
) {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
const sendCaptcha = () => {
|
||||
const password = getCtData.value.map(item => item).join('')
|
||||
emit('sendCaptcha', password)
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
// 重置。一般是验证码错误时触发。
|
||||
getCtData.value = getCtData.value.map(() => '')
|
||||
resetCaret()
|
||||
}
|
||||
|
||||
// 暴露reset方法给父组件使用
|
||||
defineExpose({
|
||||
reset
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.captcha {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
input {
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
border: 0.2rem solid #e6e6e6;
|
||||
border-radius: 0.8rem;
|
||||
text-align: center;
|
||||
font-size: 2.4rem;
|
||||
line-height: 6rem;
|
||||
outline: none;
|
||||
background-color: #f6f6f4;
|
||||
}
|
||||
input:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
input:disabled {
|
||||
color: #000;
|
||||
background-color: #f6f6f4;
|
||||
}
|
||||
.msg {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
268
src/views/AwardPage/container.vue
Normal file
@@ -0,0 +1,268 @@
|
||||
<template>
|
||||
<div class="award-container">
|
||||
<div class="header-wrapper">
|
||||
<div class="header flex align-center space-between">
|
||||
<div class="header-left">
|
||||
<img
|
||||
src="@/assets/images/award/code_create_logo.png"
|
||||
class="logo"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="header-right flex align-center"
|
||||
@click="handleBtnClick"
|
||||
>
|
||||
<div class="text">{{ btnText }}</div>
|
||||
<img
|
||||
src="@/assets/images/award/arrow.png"
|
||||
alt=""
|
||||
class="arrow"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-placeholder"></div>
|
||||
</div>
|
||||
<router-view />
|
||||
<div class="footer flex space-between align-center">
|
||||
<div class="social-list flex">
|
||||
<a
|
||||
href="https://xhslink.com/m/5Ony2FapizV"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/award/xiaohongshu.svg"
|
||||
alt=""
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.linkedin.com/company/code-create-limited"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/award/linkdin.svg"
|
||||
alt=""
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.facebook.com/CodeCreateAI"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/award/facebook.svg"
|
||||
alt=""
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.tiktok.com/@aida_codecreate"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/award/tiktok.svg"
|
||||
alt=""
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
href="javascript:void(0)"
|
||||
@click="showQRcode = true"
|
||||
>
|
||||
<img
|
||||
src="@/assets/images/award/weichat.svg"
|
||||
alt=""
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="copyright">© Code-Create 2026</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">{{ $t('AwardsPage.wechatTitle') }}</div>
|
||||
<img
|
||||
src="@/assets/images/award/qrcode.jpg"
|
||||
class="qrcode"
|
||||
/>
|
||||
<div class="tips">{{ $t('AwardsPage.wechatDesc') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { getCookie } from '@/utils/cookie'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { locale } = useI18n()
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化语言设置
|
||||
const loginLanguage = localStorage.getItem('loginLanguage')
|
||||
if (loginLanguage) {
|
||||
locale.value = loginLanguage
|
||||
} else {
|
||||
const userLanguage = getCookie('language')
|
||||
if (userLanguage) {
|
||||
locale.value = userLanguage
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const showQRcode = ref(false)
|
||||
const handleCloseQRcode = () => {
|
||||
showQRcode.value = false
|
||||
}
|
||||
|
||||
type BtnType = 'index' | 'form'
|
||||
const btnType = ref<BtnType>('index')
|
||||
const btnText = computed(() => {
|
||||
if (btnType.value === 'index') {
|
||||
return locale.value === 'CHINESE_SIMPLIFIED' ? '提交申请' : 'Submit your Application'
|
||||
}
|
||||
if (btnType.value === 'form') {
|
||||
return locale.value === 'CHINESE_SIMPLIFIED' ? '赛事介绍' : 'Back to Introduction'
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
val => {
|
||||
if (val.includes('contestants')) {
|
||||
btnType.value = 'form'
|
||||
} else {
|
||||
btnType.value = 'index'
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
const handleBtnClick = () => {
|
||||
if (btnType.value === 'index') {
|
||||
router.push('/award/contestants')
|
||||
} else {
|
||||
router.push('/award/index')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.award-container {
|
||||
overflow: auto;
|
||||
height: 100vh;
|
||||
// 隐藏滚动条箭头,只显示滚动条本体
|
||||
box-sizing: border-box;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
.header-wrapper {
|
||||
.header-placeholder {
|
||||
height: 8rem;
|
||||
}
|
||||
.header {
|
||||
height: 8rem;
|
||||
background-color: #232323;
|
||||
padding-left: 21.5rem;
|
||||
padding-right: 8.6rem;
|
||||
box-sizing: border-box;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 9;
|
||||
.header-left {
|
||||
.logo {
|
||||
width: 13rem;
|
||||
height: 5rem;
|
||||
}
|
||||
}
|
||||
.header-right {
|
||||
column-gap: 1rem;
|
||||
cursor: pointer;
|
||||
.text {
|
||||
font-size: 1.6rem;
|
||||
color: #fff;
|
||||
}
|
||||
.arrow {
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.footer {
|
||||
height: 10rem;
|
||||
padding-left: 21.5rem;
|
||||
box-sizing: border-box;
|
||||
padding-right: 22rem;
|
||||
background-color: #232323;
|
||||
.social-list {
|
||||
column-gap: 2rem;
|
||||
img {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
.copyright {
|
||||
color: #fff;
|
||||
font-family: 'Arial';
|
||||
font-weight: 400;
|
||||
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>
|
||||
143
src/views/AwardPage/index.vue
Normal file
@@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<div
|
||||
class="award-page"
|
||||
:class="{ 'is-zh': isZh }"
|
||||
>
|
||||
<div class="banner">
|
||||
<video
|
||||
:src="bannerUrl"
|
||||
autoplay
|
||||
muted
|
||||
loop
|
||||
class="banner-video"
|
||||
playsinline
|
||||
webkit-playsinline
|
||||
x5-playsinline
|
||||
></video>
|
||||
<div
|
||||
class="submit-btn flex flex-center"
|
||||
@click="handleSubmitApplication"
|
||||
>
|
||||
<div>{{ $t('AwardsPage.submitApplication') }}</div>
|
||||
<img
|
||||
src="@/assets/images/award/arrow_right.png"
|
||||
alt=""
|
||||
class="arrow"
|
||||
/>
|
||||
<div class="ddl">{{ $t('AwardsPage.applicationDeadline') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Slogan />
|
||||
<Bloom />
|
||||
<TimeLine />
|
||||
<JudgesSection />
|
||||
<PrizesSection :is-zh="isZh" />
|
||||
<ApplySection />
|
||||
<SelectionSection />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import JudgesSection from './components/JudgesSection.vue'
|
||||
import SelectionSection from './components/SelectionSection.vue'
|
||||
import ApplySection from './components/ApplySection.vue'
|
||||
import PrizesSection from './components/PrizesSection.vue'
|
||||
import TimeLine from './components/TimeLine.vue'
|
||||
import Bloom from './components/Bloom.vue'
|
||||
import Slogan from './components/Slogan.vue'
|
||||
|
||||
import banner from '@/assets/images/award/banner.mp4'
|
||||
import bannerZh from '@/assets/images/award/banner_chinese.mp4'
|
||||
|
||||
const router = useRouter()
|
||||
const { locale } = useI18n()
|
||||
|
||||
const isZh = computed(() => {
|
||||
return locale.value === 'CHINESE_SIMPLIFIED'
|
||||
})
|
||||
|
||||
const bannerUrl = computed(() => {
|
||||
return isZh.value ? bannerZh : banner
|
||||
})
|
||||
|
||||
const handleSubmitApplication = () => {
|
||||
router.push('/award/contestants')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.container {
|
||||
height: 97rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 2.4rem;
|
||||
height: 2.4rem;
|
||||
}
|
||||
.banner {
|
||||
height: 100rem;
|
||||
// background: url('@/assets/images/award/banner.png') no-repeat;
|
||||
// background-size: cover;
|
||||
position: relative;
|
||||
.banner-video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.submit-btn {
|
||||
width: 41rem;
|
||||
height: 6.394rem;
|
||||
line-height: 6.394rem;
|
||||
text-align: center;
|
||||
border-radius: 3.2rem;
|
||||
background-color: rgba(35, 35, 35, 0.7);
|
||||
box-shadow: inset 0 0 1119px 0 rgba(255, 255, 255, 0.3),
|
||||
inset -0.8px -2.4px 1.6px 0.4px rgba(255, 255, 255, 0.1),
|
||||
inset 0.8px 2.4px 1.6px 0 rgba(255, 255, 255, 0.3);
|
||||
color: #fff;
|
||||
font-family: 'PoppinsBold';
|
||||
font-weight: 600;
|
||||
font-size: 2.4rem;
|
||||
column-gap: 3.2rem;
|
||||
position: absolute;
|
||||
left: 42.1rem;
|
||||
bottom: 15.7rem;
|
||||
backdrop-filter: blur(5px);
|
||||
cursor: pointer;
|
||||
.arrow {
|
||||
width: 3.83rem;
|
||||
height: 3.83rem;
|
||||
}
|
||||
.ddl {
|
||||
position: absolute;
|
||||
bottom: -4rem;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
width: 41rem;
|
||||
font-family: 'ArialBold';
|
||||
font-weight: 700;
|
||||
font-size: 2rem;
|
||||
line-height: 2.2rem;
|
||||
color: #232323e5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-zh {
|
||||
.submit-btn {
|
||||
padding: 0 7.5rem;
|
||||
height: 7.8rem;
|
||||
border-radius: 7.74rem;
|
||||
column-gap: 3.8rem;
|
||||
// justify-content: space-between;
|
||||
&,
|
||||
.ddl {
|
||||
width: 35.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||