Compare commits
17 Commits
research
...
46b264e69e
| Author | SHA1 | Date | |
|---|---|---|---|
| 46b264e69e | |||
| 27651e3a46 | |||
|
|
5e1d43b5a0 | ||
|
|
3a7ba636f2 | ||
|
|
4ac3f7e054 | ||
|
|
b50c471e97 | ||
|
|
ab71ccdaec | ||
|
|
e79a635220 | ||
|
|
2b4e77f4e1 | ||
|
|
469f5e6c88 | ||
|
|
9857c2a2f9 | ||
|
|
fa2b9ff335 | ||
|
|
dbb9d5f3bc | ||
|
|
103028f98a | ||
|
|
fe93b375c4 | ||
|
|
4da9c06aa9 | ||
|
|
41e530d33d |
@@ -13,6 +13,11 @@
|
||||
font-weight: normal;
|
||||
src: url('pingfang/pingfang-regular.ttf') format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'pingfang_heavy';
|
||||
font-weight: normal;
|
||||
src: url('pingfang/pingfang-heavy.ttf') format('truetype');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'satoshi_light';
|
||||
font-weight: normal;
|
||||
|
||||
BIN
public/css/pingfang/pingfang-heavy.ttf
Normal file
88
src/assets/css/ant-from-style.css
Normal file
@@ -0,0 +1,88 @@
|
||||
:deep(.ant-form) .form-group {
|
||||
display: flex;
|
||||
gap: 1.6rem;
|
||||
}
|
||||
:deep(.ant-form) .form-group .ant-form-item {
|
||||
flex: 1;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item {
|
||||
margin-bottom: 1.6rem;
|
||||
position: relative;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item .tip-length {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
right: 1.6rem;
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1rem;
|
||||
color: #df2c2c;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item .ant-form-item-explain,
|
||||
:deep(.ant-form) .ant-form-item .ant-form-item-explain-connected {
|
||||
min-height: 0;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item .ant-form-item-explain-error {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-label {
|
||||
display: flex;
|
||||
padding: 0 0 0.6rem 0;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-label > label {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.4rem;
|
||||
line-height: 150%;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-label > label.ant-form-item-required:not(.ant-form-item-required-mark-optional)::before {
|
||||
content: "";
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-label > label.ant-form-item-required:not(.ant-form-item-required-mark-optional):after {
|
||||
display: inline-block;
|
||||
color: #df2c2c;
|
||||
font-size: 1.4rem;
|
||||
content: "*";
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input .ant-input-affix-wrapper,
|
||||
:deep(.ant-form) .ant-form-item-control-input textarea,
|
||||
:deep(.ant-form) .ant-form-item-control-input input {
|
||||
border-radius: 1.2rem;
|
||||
border: 0.16rem solid #d1d1d1;
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.4rem;
|
||||
color: #000;
|
||||
padding: 1.6rem;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input .ant-input-affix-wrapper::placeholder,
|
||||
:deep(.ant-form) .ant-form-item-control-input textarea::placeholder,
|
||||
:deep(.ant-form) .ant-form-item-control-input input::placeholder {
|
||||
color: #999;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input .ant-input-affix-wrapper {
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input .ant-input-affix-wrapper:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input .ant-input-affix-wrapper .ant-input-prefix {
|
||||
width: 5.2rem;
|
||||
font-size: 1.4rem;
|
||||
line-height: 150%;
|
||||
color: #000;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input .ant-input-affix-wrapper input {
|
||||
border: none;
|
||||
height: 100%;
|
||||
padding: 0 1.6rem;
|
||||
border-radius: 0;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input input {
|
||||
height: 5rem;
|
||||
}
|
||||
:deep(.ant-form) .ant-form-item-control-input textarea {
|
||||
height: 11rem;
|
||||
resize: none;
|
||||
}
|
||||
2519
src/assets/css/style.css
Normal file
3
src/assets/icons/CCrop.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M24 18H20V7C20 6.20435 19.6839 5.44129 19.1213 4.87868C18.5587 4.31607 17.7956 4 17 4H6V0H4V4H0V6H4V17C4 17.7956 4.31607 18.5587 4.87868 19.1213C5.44129 19.6839 6.20435 20 7 20H18V24H20V20H24V18ZM7 18C6.73478 18 6.48043 17.8946 6.29289 17.7071C6.10536 17.5196 6 17.2652 6 17V6H17C17.2652 6 17.5196 6.10536 17.7071 6.29289C17.8946 6.48043 18 6.73478 18 7V18H7Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 495 B |
3
src/assets/icons/CPublish.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14 8H12C11.2647 8 10.6667 8.598 10.6667 9.33333C10.6667 10.0687 10.0687 10.6667 9.33333 10.6667H6.66667C5.93133 10.6667 5.33333 10.0687 5.33333 9.33333C5.33333 8.598 4.73533 8 4 8H2C0.897333 8 0 8.89733 0 10V12.6667C0 14.5047 1.49533 16 3.33333 16H12.6667C14.5047 16 16 14.5047 16 12.6667V10C16 8.89733 15.1027 8 14 8ZM14.6667 12.6667C14.6667 13.7693 13.7693 14.6667 12.6667 14.6667H3.33333C2.23067 14.6667 1.33333 13.7693 1.33333 12.6667V10C1.33333 9.632 1.632 9.33333 2 9.33333L4 9.332V9.33333C4 10.804 5.196 12 6.66667 12H9.33333C10.804 12 12 10.804 12 9.33333H14C14.368 9.33333 14.6667 9.632 14.6667 10V12.6667ZM4.862 3.52867C4.60133 3.268 4.60133 2.84667 4.862 2.586L7.05733 0.390667C7.31467 0.133333 7.65267 0.004 7.99067 0.002L8 0L8.00933 0.002C8.348 0.004 8.68533 0.133333 8.94267 0.390667L11.138 2.586C11.3987 2.84667 11.3987 3.268 11.138 3.52867C11.008 3.65867 10.8373 3.724 10.6667 3.724C10.496 3.724 10.3253 3.65867 10.1953 3.52867L8.66667 2V6.66667C8.66667 7.03533 8.36867 7.33333 8 7.33333C7.63133 7.33333 7.33333 7.03533 7.33333 6.66667V2L5.80467 3.52867C5.544 3.78933 5.12267 3.78933 4.862 3.52867Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
3
src/assets/icons/CSave.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.024 2.74801L13.252 0.976013C12.9432 0.665575 12.576 0.419466 12.1714 0.251935C11.7669 0.0844031 11.3332 -0.00122304 10.8953 1.31975e-05H3.33333C2.4496 0.00107177 1.60237 0.352601 0.97748 0.977493C0.352588 1.60239 0.00105857 2.44962 0 3.33335L0 12.6667C0.00105857 13.5504 0.352588 14.3976 0.97748 15.0225C1.60237 15.6474 2.4496 15.999 3.33333 16H12.6667C13.5504 15.999 14.3976 15.6474 15.0225 15.0225C15.6474 14.3976 15.9989 13.5504 16 12.6667V5.10468C16.0012 4.66684 15.9156 4.2331 15.7481 3.82858C15.5805 3.42405 15.3344 3.05678 15.024 2.74801ZM11.3333 1.38668V2.00001C11.3333 2.53045 11.1226 3.03915 10.7475 3.41423C10.3725 3.7893 9.86377 4.00001 9.33333 4.00001H6.66667C6.13623 4.00001 5.62753 3.7893 5.25245 3.41423C4.87738 3.03915 4.66667 2.53045 4.66667 2.00001V1.33335H10.8953C11.0429 1.33466 11.1898 1.35255 11.3333 1.38668ZM14.6667 12.6667C14.6667 13.1971 14.456 13.7058 14.0809 14.0809C13.7058 14.456 13.1971 14.6667 12.6667 14.6667H3.33333C2.8029 14.6667 2.29419 14.456 1.91912 14.0809C1.54405 13.7058 1.33333 13.1971 1.33333 12.6667V3.33335C1.33333 2.80291 1.54405 2.29421 1.91912 1.91913C2.29419 1.54406 2.8029 1.33335 3.33333 1.33335V2.00001C3.33439 2.88374 3.68592 3.73097 4.31081 4.35587C4.93571 4.98076 5.78294 5.33229 6.66667 5.33335H9.33333C10.1717 5.33074 10.9781 5.01179 11.5914 4.44026C12.2047 3.86872 12.5797 3.08674 12.6413 2.25068L14.0813 3.69068C14.455 4.0666 14.6653 4.57468 14.6667 5.10468V12.6667Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
3
src/assets/icons/seller/add.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.1667 9.16667H10.8333V0.833333C10.8333 0.61232 10.7455 0.400358 10.5893 0.244078C10.433 0.0877974 10.221 0 10 0C9.77899 0 9.56702 0.0877974 9.41074 0.244078C9.25446 0.400358 9.16667 0.61232 9.16667 0.833333V9.16667H0.833333C0.61232 9.16667 0.400358 9.25446 0.244078 9.41074C0.0877974 9.56702 0 9.77899 0 10C0 10.221 0.0877974 10.433 0.244078 10.5893C0.400358 10.7455 0.61232 10.8333 0.833333 10.8333H9.16667V19.1667C9.16667 19.3877 9.25446 19.5996 9.41074 19.7559C9.56702 19.9122 9.77899 20 10 20C10.221 20 10.433 19.9122 10.5893 19.7559C10.7455 19.5996 10.8333 19.3877 10.8333 19.1667V10.8333H19.1667C19.3877 10.8333 19.5996 10.7455 19.7559 10.5893C19.9122 10.433 20 10.221 20 10C20 9.77899 19.9122 9.56702 19.7559 9.41074C19.5996 9.25446 19.3877 9.16667 19.1667 9.16667Z" fill="#B0B0B0"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 906 B |
3
src/assets/icons/seller/arrow_right_solid.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="10" height="11" viewBox="0 0 10 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 4.46552C9.66667 4.85042 9.66667 5.81267 9 6.19757L1.5 10.5277C0.833332 10.9126 -1.90735e-06 10.4315 -1.90735e-06 9.66167V1.00142C-1.90735e-06 0.231615 0.833331 -0.24951 1.5 0.13539L9 4.46552Z" fill="#999999"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 325 B |
3
src/assets/icons/seller/back.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="12" height="24" viewBox="0 0 12 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.3489 24C10.2173 24.0008 10.0869 23.9755 9.96503 23.9258C9.84319 23.876 9.73238 23.8027 9.63894 23.71L1.46894 15.54C1.00331 15.0755 0.633877 14.5238 0.381813 13.9163C0.129748 13.3089 0 12.6577 0 12C0 11.3423 0.129748 10.6911 0.381813 10.0837C0.633877 9.47621 1.00331 8.92446 1.46894 8.46L9.63894 0.290002C9.73218 0.196764 9.84287 0.122803 9.96469 0.0723426C10.0865 0.0218822 10.2171 -0.00408935 10.3489 -0.00408936C10.4808 -0.00408936 10.6114 0.0218822 10.7332 0.0723426C10.855 0.122803 10.9657 0.196764 11.0589 0.290002C11.1522 0.383241 11.2261 0.493931 11.2766 0.615753C11.3271 0.737575 11.353 0.868143 11.353 1C11.353 1.13186 11.3271 1.26243 11.2766 1.38425C11.2261 1.50607 11.1522 1.61676 11.0589 1.71L2.88894 9.88C2.32714 10.4425 2.01158 11.205 2.01158 12C2.01158 12.795 2.32714 13.5575 2.88894 14.12L11.0589 22.29C11.1527 22.383 11.2271 22.4936 11.2778 22.6154C11.3286 22.7373 11.3547 22.868 11.3547 23C11.3547 23.132 11.3286 23.2627 11.2778 23.3846C11.2271 23.5064 11.1527 23.617 11.0589 23.71C10.9655 23.8027 10.8547 23.876 10.7328 23.9258C10.611 23.9755 10.4805 24.0008 10.3489 24Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
35
src/assets/icons/seller/brandProfile.svg
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M92 5103 c-66 -32 -101 -105 -87 -180 6 -33 52 -84 376 -408 l369
|
||||
-370 -75 -684 c-41 -377 -75 -716 -75 -753 0 -147 53 -312 140 -436 53 -76
|
||||
1977 -1988 2079 -2067 298 -229 717 -269 1051 -100 126 64 198 127 611 542
|
||||
446 447 493 503 560 665 57 137 73 226 73 393 -1 130 -4 164 -27 250 -34 127
|
||||
-100 259 -177 355 -70 88 -2000 1999 -2068 2049 -63 45 -193 107 -267 126
|
||||
-129 34 -199 31 -920 -44 l-680 -71 -365 364 c-201 201 -378 370 -393 376 -40
|
||||
14 -87 12 -125 -7z m2380 -924 c29 -6 82 -25 118 -42 59 -29 152 -118 1062
|
||||
-1020 918 -910 1034 -1030 1081 -1122 66 -129 83 -342 38 -485 -39 -127 -82
|
||||
-192 -230 -345 -311 -322 -650 -659 -701 -699 -124 -97 -248 -139 -410 -140
|
||||
-128 -1 -187 13 -309 71 l-94 45 -634 626 c-1451 1434 -1388 1370 -1423 1443
|
||||
-60 127 -60 131 4 724 32 292 60 550 63 573 l6 44 127 -127 128 -127 -19 -54
|
||||
c-77 -217 25 -464 232 -568 169 -85 340 -71 493 39 112 81 180 200 193 341 23
|
||||
244 -161 471 -410 507 -63 9 -87 8 -149 -7 -40 -9 -84 -19 -98 -22 -21 -4 -43
|
||||
13 -150 120 -118 119 -123 126 -95 127 17 0 255 24 530 54 552 58 571 60 647
|
||||
44z m-685 -649 c42 -18 77 -61 89 -108 18 -66 -37 -153 -109 -173 -177 -47
|
||||
-271 206 -104 282 53 23 71 23 124 -1z"/>
|
||||
<path d="M3697 2450 c-26 -5 -76 -22 -110 -38 -54 -25 -95 -62 -312 -283 -516
|
||||
-524 -522 -530 -557 -605 -31 -65 -33 -75 -33 -179 0 -105 2 -114 34 -180 29
|
||||
-60 61 -97 230 -266 164 -165 206 -201 261 -228 148 -71 332 -53 450 45 19 16
|
||||
197 193 396 394 325 329 364 372 395 435 33 67 34 74 34 185 0 174 -7 186
|
||||
-262 442 -221 222 -259 250 -370 273 -75 16 -86 16 -156 5z m295 -498 c176
|
||||
-175 178 -178 178 -221 0 -43 0 -43 -314 -364 -416 -427 -405 -417 -458 -417
|
||||
-42 0 -45 3 -220 178 -162 162 -178 181 -178 212 0 19 9 49 20 65 10 17 173
|
||||
186 362 378 l343 347 45 0 c44 0 45 -1 222 -178z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
11
src/assets/icons/seller/camera.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1572_2304)">
|
||||
<path d="M19 4H18.492L16.308 1.168C16.0265 0.805806 15.6663 0.512417 15.2547 0.310054C14.843 0.107691 14.3907 0.00166304 13.932 0L10.068 0C9.6093 0.00166304 9.15699 0.107691 8.74533 0.310054C8.33368 0.512417 7.97347 0.805806 7.692 1.168L5.508 4H5C3.67441 4.00159 2.40356 4.52888 1.46622 5.46622C0.528882 6.40356 0.00158786 7.67441 0 9L0 19C0.00158786 20.3256 0.528882 21.5964 1.46622 22.5338C2.40356 23.4711 3.67441 23.9984 5 24H19C20.3256 23.9984 21.5964 23.4711 22.5338 22.5338C23.4711 21.5964 23.9984 20.3256 24 19V9C23.9984 7.67441 23.4711 6.40356 22.5338 5.46622C21.5964 4.52888 20.3256 4.00159 19 4ZM9.276 2.39C9.36967 2.26905 9.48969 2.17106 9.62693 2.10348C9.76418 2.0359 9.91502 2.00051 10.068 2H13.932C14.085 2.00066 14.2357 2.03611 14.373 2.10368C14.5102 2.17125 14.6302 2.26916 14.724 2.39L15.966 4H8.034L9.276 2.39ZM22 19C22 19.7956 21.6839 20.5587 21.1213 21.1213C20.5587 21.6839 19.7956 22 19 22H5C4.20435 22 3.44129 21.6839 2.87868 21.1213C2.31607 20.5587 2 19.7956 2 19V9C2 8.20435 2.31607 7.44129 2.87868 6.87868C3.44129 6.31607 4.20435 6 5 6H19C19.7956 6 20.5587 6.31607 21.1213 6.87868C21.6839 7.44129 22 8.20435 22 9V19Z" fill="white"/>
|
||||
<path d="M12 8C10.8133 8 9.65328 8.35189 8.66658 9.01118C7.67989 9.67047 6.91085 10.6075 6.45673 11.7039C6.0026 12.8003 5.88378 14.0067 6.11529 15.1705C6.3468 16.3344 6.91825 17.4035 7.75736 18.2426C8.59648 19.0818 9.66558 19.6532 10.8295 19.8847C11.9933 20.1162 13.1997 19.9974 14.2961 19.5433C15.3925 19.0892 16.3295 18.3201 16.9888 17.3334C17.6481 16.3467 18 15.1867 18 14C17.9984 12.4092 17.3658 10.884 16.2409 9.75911C15.116 8.63424 13.5908 8.00159 12 8ZM12 18C11.2089 18 10.4355 17.7654 9.77772 17.3259C9.11993 16.8864 8.60723 16.2616 8.30448 15.5307C8.00173 14.7998 7.92252 13.9956 8.07686 13.2196C8.2312 12.4437 8.61217 11.731 9.17158 11.1716C9.73099 10.6122 10.4437 10.2312 11.2196 10.0769C11.9956 9.92252 12.7998 10.0017 13.5307 10.3045C14.2616 10.6072 14.8864 11.1199 15.3259 11.7777C15.7654 12.4355 16 13.2089 16 14C16 15.0609 15.5786 16.0783 14.8284 16.8284C14.0783 17.5786 13.0609 18 12 18Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1572_2304">
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
24
src/assets/icons/seller/myListings.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="512.000000pt" height="488.000000pt" viewBox="0 0 512.000000 488.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,488.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M2425 4873 c-518 -70 -923 -535 -929 -1063 0 -80 3 -102 21 -137 70
|
||||
-131 234 -159 337 -57 45 46 58 81 67 190 17 195 89 349 218 466 120 108 254
|
||||
161 411 161 184 0 307 -51 441 -183 71 -70 94 -100 127 -170 54 -112 85 -262
|
||||
80 -381 -6 -131 -39 -191 -192 -345 -276 -277 -500 -453 -1656 -1307 -733
|
||||
-541 -1115 -829 -1155 -871 -75 -78 -128 -167 -162 -271 -23 -69 -27 -98 -27
|
||||
-205 -1 -90 4 -143 17 -189 55 -200 190 -362 372 -446 138 -64 -7 -60 2170
|
||||
-60 1895 0 1993 1 2054 18 233 66 413 250 478 488 13 46 18 98 17 189 -1 107
|
||||
-4 137 -27 205 -36 109 -89 196 -167 275 -40 40 -436 339 -1032 779 -533 393
|
||||
-968 718 -968 722 0 3 64 62 142 130 347 301 481 474 539 694 41 154 25 417
|
||||
-38 620 -121 387 -448 677 -838 740 -83 14 -229 18 -300 8z m1152 -3229 c549
|
||||
-405 1015 -753 1037 -773 52 -49 76 -103 76 -176 0 -103 -58 -194 -147 -232
|
||||
-44 -18 -3893 -20 -3954 -2 -93 28 -159 126 -159 234 0 73 24 127 76 176 74
|
||||
69 2047 1520 2060 1515 8 -3 462 -337 1011 -742z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
22
src/assets/icons/seller/myOrders.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="96.000000pt" height="96.000000pt" viewBox="0 0 96.000000 96.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,96.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M207 953 c-4 -3 -7 -21 -7 -39 0 -31 -2 -33 -37 -36 l-38 -3 -3 -378
|
||||
c-3 -418 -1 -429 60 -467 31 -19 46 -20 306 -18 l274 3 34 37 34 38 0 395 0
|
||||
395 -40 0 -40 0 0 41 0 40 -37 -3 c-36 -3 -38 -5 -41 -40 -3 -36 -5 -38 -37
|
||||
-38 -32 0 -34 2 -37 38 -3 36 -4 37 -43 37 -40 0 -40 0 -40 -38 0 -36 -1 -37
|
||||
-37 -37 -38 0 -38 0 -38 40 l0 40 -40 0 -40 0 0 -40 0 -40 -40 0 -40 0 0 40
|
||||
c0 39 -1 40 -33 40 -19 0 -37 -3 -40 -7z m543 -496 c0 -253 -3 -346 -12 -355
|
||||
-9 -9 -79 -12 -254 -12 -133 0 -249 3 -258 6 -14 5 -16 46 -16 355 l0 349 270
|
||||
0 270 0 0 -343z"/>
|
||||
<path d="M280 640 l0 -40 198 2 197 3 3 38 3 37 -200 0 -201 0 0 -40z"/>
|
||||
<path d="M280 485 l0 -45 198 2 197 3 0 40 0 40 -197 3 -198 2 0 -45z"/>
|
||||
<path d="M280 330 l0 -40 120 0 120 0 0 40 0 40 -120 0 -120 0 0 -40z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
11
src/assets/icons/seller/picture.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1572_2553)">
|
||||
<path d="M47.5 0H12.5C9.18601 0.00396964 6.00889 1.3222 3.66555 3.66555C1.3222 6.00889 0.00396964 9.18601 0 12.5L0 47.5C0.00396964 50.814 1.3222 53.9911 3.66555 56.3345C6.00889 58.6778 9.18601 59.996 12.5 60H47.5C50.814 59.996 53.9911 58.6778 56.3345 56.3345C58.6778 53.9911 59.996 50.814 60 47.5V12.5C59.996 9.18601 58.6778 6.00889 56.3345 3.66555C53.9911 1.3222 50.814 0.00396964 47.5 0ZM12.5 5H47.5C49.4891 5 51.3968 5.79018 52.8033 7.1967C54.2098 8.60322 55 10.5109 55 12.5V47.5C54.9957 48.6137 54.7393 49.712 54.25 50.7125L31.3425 27.805C30.1817 26.6439 28.8036 25.7229 27.2868 25.0945C25.77 24.4661 24.1443 24.1427 22.5025 24.1427C20.8607 24.1427 19.235 24.4661 17.7182 25.0945C16.2014 25.7229 14.8233 26.6439 13.6625 27.805L5 36.465V12.5C5 10.5109 5.79018 8.60322 7.1967 7.1967C8.60322 5.79018 10.5109 5 12.5 5ZM12.5 55C10.5109 55 8.60322 54.2098 7.1967 52.8033C5.79018 51.3968 5 49.4891 5 47.5V43.535L17.195 31.34C17.8915 30.6431 18.7185 30.0902 19.6288 29.713C20.539 29.3358 21.5147 29.1416 22.5 29.1416C23.4853 29.1416 24.461 29.3358 25.3712 29.713C26.2815 30.0902 27.1085 30.6431 27.805 31.34L50.7125 54.25C49.712 54.7393 48.6137 54.9957 47.5 55H12.5Z" fill="#D0D0D0"/>
|
||||
<path d="M40 26.25C41.7306 26.25 43.4223 25.7368 44.8612 24.7754C46.3002 23.8139 47.4217 22.4473 48.0839 20.8485C48.7462 19.2496 48.9195 17.4903 48.5819 15.793C48.2443 14.0956 47.4109 12.5365 46.1872 11.3128C44.9635 10.0891 43.4044 9.25575 41.707 8.91813C40.0097 8.58051 38.2504 8.75379 36.6515 9.41606C35.0527 10.0783 33.6861 11.1998 32.7246 12.6388C31.7632 14.0777 31.25 15.7694 31.25 17.5C31.25 19.8206 32.1719 22.0462 33.8128 23.6872C35.4538 25.3281 37.6794 26.25 40 26.25ZM40 13.75C40.7417 13.75 41.4667 13.9699 42.0834 14.382C42.7001 14.794 43.1807 15.3797 43.4645 16.0649C43.7484 16.7502 43.8226 17.5042 43.6779 18.2316C43.5333 18.959 43.1761 19.6272 42.6516 20.1517C42.1272 20.6761 41.459 21.0333 40.7316 21.1779C40.0042 21.3226 39.2502 21.2484 38.5649 20.9646C37.8797 20.6807 37.294 20.2001 36.882 19.5834C36.4699 18.9667 36.25 18.2417 36.25 17.5C36.25 16.5054 36.6451 15.5516 37.3483 14.8484C38.0516 14.1451 39.0054 13.75 40 13.75Z" fill="#D0D0D0"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1572_2553">
|
||||
<rect width="60" height="60" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
3
src/assets/icons/seller/sellerIndex.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.9797 13.2649C14.0637 13.5764 13.8788 13.896 13.5673 13.9794C13.5166 13.9928 13.4658 13.9998 13.4157 13.9998C13.1584 13.9998 12.9228 13.8277 12.8528 13.5676C12.6451 12.7918 11.9171 12.25 11.083 12.25C10.2489 12.25 9.52088 12.7918 9.31322 13.5676C9.22922 13.8785 8.90956 14.0634 8.59866 13.98C8.28717 13.8966 8.10225 13.5769 8.18625 13.2655C8.53099 11.9805 9.72212 11.0834 11.083 11.0834C12.4439 11.0834 13.635 11.9805 13.9797 13.2655V13.2649ZM11.083 7.58318C10.2786 7.58318 9.62471 8.23704 9.62471 9.04138C9.62471 9.84572 10.2786 10.4996 11.083 10.4996C11.8874 10.4996 12.5413 9.84572 12.5413 9.04138C12.5413 8.23704 11.8874 7.58318 11.083 7.58318ZM2.33326 8.74974H2.91658C3.61656 8.74974 4.23837 8.4336 4.66653 7.94365C5.09468 8.4336 5.71649 8.74974 6.41647 8.74974H7.5831C7.85026 8.74974 8.11217 8.70483 8.36125 8.61617C8.66515 8.50826 8.82382 8.17521 8.7159 7.87132C8.60741 7.56744 8.27375 7.40995 7.97159 7.51669C7.84793 7.56044 7.71668 7.5826 7.5831 7.5826H6.41647C5.77308 7.5826 5.24984 7.0594 5.24984 6.41605C5.24984 6.09408 4.98852 5.83277 4.66653 5.83277C4.34454 5.83277 4.08321 6.09408 4.08321 6.41605C4.08321 7.0594 3.55998 7.5826 2.91658 7.5826H2.33326C1.70445 7.5826 1.19055 7.08273 1.16721 6.45921L1.83569 2.40602C2.0591 1.67517 2.74275 1.16655 3.50981 1.16655H4.08321V2.91638C4.08321 3.23835 4.34454 3.49966 4.66653 3.49966C4.98852 3.49966 5.24984 3.23835 5.24984 2.91638V1.16655H8.74973V2.91638C8.74973 3.23835 9.01048 3.49966 9.33305 3.49966C9.65562 3.49966 9.91637 3.23835 9.91637 2.91638V1.16655H10.4892C11.2557 1.16655 11.9399 1.67459 12.1633 2.40602L12.8318 6.45921C12.8271 6.57761 12.8049 6.69369 12.7659 6.80509C12.6585 7.10898 12.8184 7.44203 13.1217 7.54935C13.4262 7.65726 13.7587 7.49744 13.866 7.19356C13.9535 6.94391 13.999 6.68202 13.999 6.41605C13.999 6.38397 13.2996 2.13654 13.2932 2.11496C12.9374 0.869666 11.7836 0 10.4886 0H3.50981C2.21485 0.000583277 1.06163 0.870249 0.705229 2.11555C0.698812 2.13713 0 6.38455 0 6.41663C0 7.00282 0.224577 7.53302 0.583316 7.94365V11.6661C0.583316 12.9528 1.62978 13.9992 2.91658 13.9992H6.41647C6.73846 13.9992 6.99979 13.7379 6.99979 13.416C6.99979 13.094 6.73846 12.8327 6.41647 12.8327H2.91658C2.27318 12.8327 1.74995 12.3095 1.74995 11.6661V8.66691C1.93777 8.71591 2.13085 8.74974 2.33326 8.74974Z" fill="#585858"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
3
src/assets/icons/seller/sellerToolTipClose.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M29.75 0.5C30.2139 0.50007 30.6592 0.684683 30.9873 1.0127C31.3153 1.34085 31.499 1.78607 31.499 2.25C31.499 2.71394 31.3153 3.15919 30.9873 3.4873L18.4746 16L30.9873 28.5127C31.3153 28.8409 31.499 29.2861 31.499 29.75C31.499 30.2139 31.3153 30.6592 30.9873 30.9873C30.6592 31.3153 30.2139 31.499 29.75 31.499C29.2861 31.499 28.8409 31.3153 28.5127 30.9873L16 18.4746L3.4873 30.9873C3.15919 31.3153 2.71394 31.499 2.25 31.499C1.78607 31.499 1.34085 31.3153 1.0127 30.9873C0.684683 30.6592 0.50007 30.2139 0.5 29.75C0.5 29.286 0.684623 28.8409 1.0127 28.5127L13.5254 16L1.0127 3.4873C0.684684 3.15919 0.500071 2.71394 0.5 2.25C0.5 1.78596 0.684621 1.34087 1.0127 1.0127C1.34087 0.684621 1.78596 0.5 2.25 0.5C2.71394 0.500071 3.15919 0.684684 3.4873 1.0127L16 13.5254L28.5127 1.0127C28.8409 0.684623 29.286 0.5 29.75 0.5Z" fill="black" stroke="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 963 B |
27
src/assets/icons/seller/settings.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="96.000000pt" height="96.000000pt" viewBox="0 0 96.000000 96.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,96.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M235 946 c-30 -13 -85 -69 -85 -86 0 -5 -30 -10 -66 -12 -51 -2 -70
|
||||
-7 -78 -20 -21 -34 4 -52 77 -58 62 -5 67 -7 89 -40 27 -40 79 -70 123 -70 42
|
||||
0 96 31 123 71 l23 34 251 5 c225 4 252 7 262 23 8 12 8 22 0 35 -10 15 -36
|
||||
17 -267 20 l-255 2 -6 25 c-15 60 -125 101 -191 71z m103 -82 c47 -33 16 -124
|
||||
-43 -124 -31 0 -75 41 -75 70 0 28 43 70 72 70 13 0 34 -7 46 -16z"/>
|
||||
<path d="M600 611 c-19 -10 -45 -33 -58 -52 l-23 -34 -251 -5 c-225 -4 -252
|
||||
-7 -262 -22 -8 -13 -8 -23 0 -35 10 -16 36 -18 267 -21 l255 -2 6 -25 c3 -13
|
||||
23 -37 43 -52 29 -22 47 -28 89 -28 59 0 95 21 129 73 18 28 25 31 84 34 48 2
|
||||
67 7 75 21 21 33 -4 51 -77 57 -62 5 -67 7 -89 40 -44 65 -122 87 -188 51z
|
||||
m115 -86 c14 -13 25 -33 25 -45 0 -28 -43 -70 -72 -70 -40 0 -68 27 -68 66 0
|
||||
68 68 97 115 49z"/>
|
||||
<path d="M235 286 c-30 -13 -85 -69 -85 -86 0 -5 -30 -10 -66 -12 -51 -2 -70
|
||||
-7 -78 -20 -21 -34 4 -52 77 -58 62 -5 67 -7 89 -40 27 -40 79 -70 123 -70 42
|
||||
0 96 31 123 71 l23 34 251 5 c225 4 252 7 262 23 8 12 8 22 0 35 -10 15 -36
|
||||
17 -267 20 l-255 2 -6 25 c-15 60 -125 101 -191 71z m103 -82 c47 -33 16 -124
|
||||
-43 -124 -30 0 -75 41 -75 68 0 11 9 31 21 46 24 30 63 34 97 10z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
4
src/assets/icons/seller/user.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M24 24C26.3734 24 28.6935 23.2962 30.6668 21.9776C32.6402 20.6591 34.1783 18.7849 35.0866 16.5922C35.9948 14.3995 36.2324 11.9867 35.7694 9.65892C35.3064 7.33115 34.1635 5.19295 32.4853 3.51472C30.8071 1.83649 28.6689 0.693605 26.3411 0.230582C24.0133 -0.232441 21.6005 0.00519943 19.4078 0.913451C17.2151 1.8217 15.3409 3.35977 14.0224 5.33316C12.7038 7.30655 12 9.62663 12 12C12.0032 15.1816 13.2685 18.232 15.5182 20.4818C17.768 22.7315 20.8184 23.9968 24 24ZM24 4.00001C25.5823 4.00001 27.129 4.4692 28.4446 5.34825C29.7602 6.2273 30.7855 7.47673 31.391 8.93854C31.9965 10.4003 32.155 12.0089 31.8463 13.5607C31.5376 15.1126 30.7757 16.538 29.6569 17.6569C28.538 18.7757 27.1126 19.5376 25.5607 19.8463C24.0089 20.155 22.4003 19.9965 20.9385 19.391C19.4767 18.7855 18.2273 17.7602 17.3482 16.4446C16.4692 15.129 16 13.5823 16 12C16 9.87827 16.8429 7.84344 18.3431 6.34315C19.8434 4.84286 21.8783 4.00001 24 4.00001Z" fill="#BBBBBB"/>
|
||||
<path d="M24 28C19.2277 28.0053 14.6524 29.9034 11.2779 33.2779C7.90342 36.6524 6.00529 41.2277 6 46C6 46.5304 6.21071 47.0391 6.58579 47.4142C6.96086 47.7893 7.46957 48 8 48C8.53043 48 9.03914 47.7893 9.41421 47.4142C9.78929 47.0391 10 46.5304 10 46C10 42.287 11.475 38.726 14.1005 36.1005C16.726 33.475 20.287 32 24 32C27.713 32 31.274 33.475 33.8995 36.1005C36.525 38.726 38 42.287 38 46C38 46.5304 38.2107 47.0391 38.5858 47.4142C38.9609 47.7893 39.4696 48 40 48C40.5304 48 41.0391 47.7893 41.4142 47.4142C41.7893 47.0391 42 46.5304 42 46C41.9947 41.2277 40.0966 36.6524 36.7221 33.2779C33.3476 29.9034 28.7723 28.0053 24 28Z" fill="#BBBBBB"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 198 B |
@@ -1,3 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 212 B |
|
Before Width: | Height: | Size: 327 B |
|
Before Width: | Height: | Size: 492 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 231 KiB |
|
Before Width: | Height: | Size: 913 B |
@@ -1,4 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 636 B |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 339 KiB |
|
Before Width: | Height: | Size: 443 KiB |
|
Before Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 4.3 MiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 35 KiB |
@@ -1,9 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 930 KiB |
|
Before Width: | Height: | Size: 262 KiB |
|
Before Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 198 KiB |
@@ -1,10 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 4.3 MiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 253 KiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 47 KiB |
@@ -1,12 +0,0 @@
|
||||
<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>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 811 B |
BIN
src/assets/images/seller/sellerToolTip-1.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/images/seller/sellerToolTip-2.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
src/assets/images/seller/sellerToolTip-3.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
src/assets/images/seller/success-0.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/images/seller/success-1.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src/assets/images/test.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
110
src/assets/style/ant-from-style.less
Normal file
@@ -0,0 +1,110 @@
|
||||
:deep(.ant-form) {
|
||||
.form-group {
|
||||
display: flex;
|
||||
gap: 1.6rem;
|
||||
|
||||
.ant-form-item {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item {
|
||||
margin-bottom: 1.6rem;
|
||||
position: relative;
|
||||
|
||||
.tip-length {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
right: 1.6rem;
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1rem;
|
||||
color: #df2c2c;
|
||||
}
|
||||
|
||||
.ant-form-item-explain,
|
||||
.ant-form-item-explain-connected {
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.ant-form-item-explain-error {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item-label {
|
||||
display: flex;
|
||||
padding: 0 0 0.6rem 0;
|
||||
|
||||
>label {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.4rem;
|
||||
line-height: 150%;
|
||||
|
||||
&.ant-form-item-required:not(.ant-form-item-required-mark-optional) {
|
||||
&::before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
&:after {
|
||||
display: inline-block;
|
||||
color: #df2c2c;
|
||||
font-size: 1.4rem;
|
||||
content: "*";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-form-item-control-input {
|
||||
|
||||
.ant-input-affix-wrapper,
|
||||
textarea,
|
||||
input {
|
||||
border-radius: 1.2rem;
|
||||
border: 0.16rem solid #d1d1d1;
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.4rem;
|
||||
color: #000;
|
||||
padding: 1.6rem;
|
||||
|
||||
&::placeholder {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-input-affix-wrapper {
|
||||
margin-bottom: 0.6rem;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.ant-input-prefix {
|
||||
width: 5.2rem;
|
||||
font-size: 1.4rem;
|
||||
line-height: 150%;
|
||||
color: #000;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
height: 100%;
|
||||
padding: 0 1.6rem;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
input {
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 11rem;
|
||||
resize: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2386,6 +2386,16 @@ textarea:focus{
|
||||
// background: #ffffff;
|
||||
}
|
||||
}
|
||||
// 迷你滚动条
|
||||
.mini-scrollbar {
|
||||
&::-webkit-scrollbar {
|
||||
width: 0.4rem;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 0.4rem;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
//蒙层样式
|
||||
.mark_loading{
|
||||
|
||||
@@ -391,8 +391,8 @@ export class PartManager {
|
||||
this.canvas.loading.value = true;
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
// const user_id = store.state.UserHabit.userDetail.userId;
|
||||
const user_id = 24299;
|
||||
const user_id = store.state.UserHabit.userDetail.userId;
|
||||
// const user_id = 24299;
|
||||
const data = {
|
||||
image_path: this.props.clothingMinIOPath,
|
||||
user_id,
|
||||
|
||||
@@ -7,6 +7,7 @@ import { canvasConfig } from "../config/canvasConfig";
|
||||
export const createCanvas = (elementId, options = {}) => {
|
||||
// Create the canvas instance
|
||||
const canvas = new fabric.Canvas(elementId, {
|
||||
controlsAboveOverlay: true,// 控制面板在图层之上
|
||||
enableRetinaScaling: canvasConfig.enableRetinaScaling,
|
||||
renderOnAddRemove: false,
|
||||
preserveObjectStacking: true, // 保持对象堆叠顺序
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
:get-container="() => $refs.upgradePlan"
|
||||
width="35%"
|
||||
height="auto"
|
||||
zIndex="9999999"
|
||||
:zIndex="9999999"
|
||||
:maskClosable="false"
|
||||
:centered="true"
|
||||
:closable="false"
|
||||
|
||||
@@ -24,6 +24,8 @@ export default {
|
||||
SubscribeNow: '立即订阅',
|
||||
TaskList: '任务列表',
|
||||
ViewOrders: '查询订单',
|
||||
BecomeSeller: '成为卖家',
|
||||
SellerDashboard: '卖家中心',
|
||||
toolsToProduct: '转产品图',
|
||||
toolsRelight: '产品图编辑',
|
||||
toolsToTransferPose: '产品图视频',
|
||||
@@ -1719,5 +1721,19 @@ export default {
|
||||
IncorrectEmailFormat: '请输入正确的邮箱格式',
|
||||
CompleteVerificationCode: '请输入完整的验证码',
|
||||
PleaseEnterYourAccountNumberOrPassword: '请输入您的账号或密码'
|
||||
}
|
||||
},
|
||||
SellerToolTip: {
|
||||
title: '如何上架你的设计',
|
||||
titleInfo: '按照以下4个步骤将你的设计发布到市场。',
|
||||
step1Title: '选择系列',
|
||||
step1Info: '选择你要上架的设计系列。',
|
||||
step2Title: '选择草图',
|
||||
step2Info: '挑选你要上架的草图,可同时选择多个。',
|
||||
step3Title: '编辑草图详情',
|
||||
step3Info: '详情信息已从AiDA自动填充,请检查并补充任何缺失的信息。',
|
||||
step4Title: '上架发布',
|
||||
step4Info: '发布后,你的设计将立即在市场上线。',
|
||||
showAgain: '不再提示',
|
||||
GetStarted: '开始体验',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ export default {
|
||||
SubscribeNow: 'Subscribe now',
|
||||
TaskList: 'Task List',
|
||||
ViewOrders: 'View Orders',
|
||||
BecomeSeller: 'Become a Seller',
|
||||
SellerDashboard: 'Seller Dashboard',
|
||||
toolsToProduct: 'To product image',
|
||||
toolsRelight: 'Edit product image',
|
||||
toolsToTransferPose: 'To product video',
|
||||
@@ -1770,5 +1772,19 @@ export default {
|
||||
IncorrectEmailFormat: 'The email format is incorrect',
|
||||
CompleteVerificationCode: 'Please enter the complete verification code.',
|
||||
PleaseEnterYourAccountNumberOrPassword: 'Please enter your account number or password'
|
||||
},
|
||||
SellerToolTip: {
|
||||
title: 'How to List your Design',
|
||||
titleInfo: 'Follow these 4 steps to publish your design to the marketplace.',
|
||||
step1Title: 'Select Collection',
|
||||
step1Info: 'Choose the design collection you want to list from.',
|
||||
step2Title: 'Select Sketch',
|
||||
step2Info: 'Pick the sketch you want to list. You can select multiple at a time.',
|
||||
step3Title: 'Edit Sketch Details',
|
||||
step3Info: 'Details are pre-filled from AiDA. Review and complete any missing information.',
|
||||
step4Title: 'Listing Live',
|
||||
step4Info: 'Publish and your design goes live on the marketplace.',
|
||||
showAgain: 'Don’t show me again',
|
||||
GetStarted: 'Get Started',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,28 @@
|
||||
import {
|
||||
createRouter,
|
||||
createWebHistory,
|
||||
RouteRecordRaw,
|
||||
createWebHashHistory,
|
||||
} from "vue-router";
|
||||
import store from "@/store";
|
||||
import { Https } from "@/tool/https";
|
||||
import { getCookie, setCookie } from "@/tool/cookie";
|
||||
import { createRouter, createWebHistory, RouteRecordRaw, createWebHashHistory } from "vue-router"
|
||||
import store from "@/store"
|
||||
import { Https } from "@/tool/https"
|
||||
import { getCookie, setCookie } from "@/tool/cookie"
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
path: "/",
|
||||
// redirect重定向
|
||||
meta: { enter: "all" },
|
||||
redirect: "/Square",
|
||||
// redirect: "/upgrade"
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
name: "login",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/Login.vue"),
|
||||
},
|
||||
{
|
||||
path: "/canvasExample",
|
||||
name: "canvasExample",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/component/Canvas/canvasExample.vue"),
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
// redirect重定向
|
||||
meta: { enter: "all" },
|
||||
redirect: "/Square"
|
||||
// redirect: "/upgrade"
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
name: "login",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/Login.vue")
|
||||
},
|
||||
{
|
||||
path: "/canvasExample",
|
||||
name: "canvasExample",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/component/Canvas/canvasExample.vue")
|
||||
},
|
||||
|
||||
{
|
||||
path: "/schoolLogin",
|
||||
@@ -169,6 +164,69 @@ const routes: Array<RouteRecordRaw> = [
|
||||
name: "otherUsers",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/component/Account/otherUsers.vue"),
|
||||
},
|
||||
{
|
||||
path: "becomeSeller",
|
||||
name: "becomeSeller",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/BecomeSeller/index.vue"),
|
||||
},
|
||||
{
|
||||
path: "seller",
|
||||
name: "seller",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/index.vue"),
|
||||
children:[
|
||||
{
|
||||
path: "brandProfile",
|
||||
name: "brandProfile",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue"),
|
||||
},
|
||||
{
|
||||
path: "myListings",
|
||||
name: "myListings",
|
||||
meta: { enter: "all" },
|
||||
children:[
|
||||
{
|
||||
path: "",
|
||||
name: "myListingsChild",
|
||||
meta: { enter: "all" },
|
||||
redirect: "/home/seller/myListings/index",
|
||||
},
|
||||
{
|
||||
path: "index",
|
||||
name: "myListingsIndex",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/MyListings/main/index.vue"),
|
||||
},
|
||||
{
|
||||
path: "select",
|
||||
name: "myListingsSelect",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/MyListings/createSelect/index.vue"),
|
||||
},
|
||||
{
|
||||
path: "select/:id",
|
||||
name: "myListingsSelectItem",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/MyListings/createSelectItem/index.vue"),
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path: "myOrders",
|
||||
name: "myOrders",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue"),
|
||||
},
|
||||
{
|
||||
path: "settings",
|
||||
name: "settings",
|
||||
meta: { enter: "all" },
|
||||
component: () => import("@/views/SellerDashboard/BrandProfile/index.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -456,12 +514,12 @@ const routes: Array<RouteRecordRaw> = [
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
// history: createWebHashHistory(),
|
||||
routes,
|
||||
});
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
// history: createWebHashHistory(),
|
||||
routes
|
||||
})
|
||||
// 刷新保存数据-
|
||||
let state: any = store.state;
|
||||
let state: any = store.state
|
||||
// window.addEventListener("beforeunload", (e) => {
|
||||
// localStorage.setItem(
|
||||
// "vuex_setUserDetail",
|
||||
@@ -477,114 +535,110 @@ let state: any = store.state;
|
||||
// }
|
||||
|
||||
let setMurmur = (id: any) => {
|
||||
let murmurStr: any = localStorage.getItem("murmurStr");
|
||||
// let isSxis = false
|
||||
let data = {
|
||||
browserIdentifiers: murmurStr,
|
||||
id: id,
|
||||
};
|
||||
if (data.id) {
|
||||
Https.axiosPost(Https.httpUrls.noLoginRequired, data)
|
||||
.then((rv) => {
|
||||
let isTest = rv.systemUser == 3 ? true : false;
|
||||
let isBeginner = rv?.isBeginner == 1 ? true : false;
|
||||
setCookie("isMurmur", true);
|
||||
setCookie("token", rv.token);
|
||||
setCookie("isTest", isTest);
|
||||
setCookie("isBeginner", isBeginner);
|
||||
setCookie("isBeginnerNum", 0); //从第一步开始,机器人开始的话就是从第二部开始
|
||||
setCookie("userInfo", JSON.stringify(rv));
|
||||
let userid = {
|
||||
ueserId: rv.userId,
|
||||
systemUser: rv.systemUser,
|
||||
};
|
||||
store.commit("upUserDetail", userid);
|
||||
sessionStorage.setItem("isTimeOne", JSON.stringify(false)); //是否需要公告 提示 弹窗
|
||||
let randomNum: any =
|
||||
Math.floor(Math.random() * 9000000000000000) + 1000000000000000;
|
||||
sessionStorage.setItem("sessionId", randomNum);
|
||||
router.push("/home");
|
||||
})
|
||||
.catch((res) => {
|
||||
// router.push('/Square')
|
||||
});
|
||||
}
|
||||
};
|
||||
let murmurStr: any = localStorage.getItem("murmurStr")
|
||||
// let isSxis = false
|
||||
let data = {
|
||||
browserIdentifiers: murmurStr,
|
||||
id: id
|
||||
}
|
||||
if (data.id) {
|
||||
Https.axiosPost(Https.httpUrls.noLoginRequired, data)
|
||||
.then((rv) => {
|
||||
let isTest = rv.systemUser == 3 ? true : false
|
||||
let isBeginner = rv?.isBeginner == 1 ? true : false
|
||||
setCookie("isMurmur", true)
|
||||
setCookie("token", rv.token)
|
||||
setCookie("isTest", isTest)
|
||||
setCookie("isBeginner", isBeginner)
|
||||
setCookie("isBeginnerNum", 0) //从第一步开始,机器人开始的话就是从第二部开始
|
||||
setCookie("userInfo", JSON.stringify(rv))
|
||||
let userid = {
|
||||
ueserId: rv.userId,
|
||||
systemUser: rv.systemUser
|
||||
}
|
||||
store.commit("upUserDetail", userid)
|
||||
sessionStorage.setItem("isTimeOne", JSON.stringify(false)) //是否需要公告 提示 弹窗
|
||||
let randomNum: any = Math.floor(Math.random() * 9000000000000000) + 1000000000000000
|
||||
sessionStorage.setItem("sessionId", randomNum)
|
||||
router.push("/home")
|
||||
})
|
||||
.catch((res) => {
|
||||
// router.push('/Square')
|
||||
})
|
||||
}
|
||||
}
|
||||
const setViewsIncrease = (value: any) => {
|
||||
sessionStorage.setItem("affiliateRef", value);
|
||||
let data = {
|
||||
id: value,
|
||||
};
|
||||
Https.axiosGet(Https.httpUrls.viewsIncrease, { params: data }).then(
|
||||
(rv) => {}
|
||||
);
|
||||
};
|
||||
let upgradeList = ["/feedbackSurvey", "/feedbackSurveyCN", "emailVerify"]; //指定页面系统维护也可以访问
|
||||
sessionStorage.setItem("affiliateRef", value)
|
||||
let data = {
|
||||
id: value
|
||||
}
|
||||
Https.axiosGet(Https.httpUrls.viewsIncrease, { params: data }).then((rv) => {})
|
||||
}
|
||||
let upgradeList = ["/feedbackSurvey", "/feedbackSurveyCN", "emailVerify"] //指定页面系统维护也可以访问
|
||||
function isTimeRangePassed(timeRange) {
|
||||
const [startStr, endStr] = timeRange.split(' - ');
|
||||
const startTime = new Date(startStr).getTime();
|
||||
const endTime = new Date(endStr).getTime();
|
||||
const currentTime = new Date().getTime();
|
||||
|
||||
if (currentTime < startTime) {
|
||||
return 'not_started'; // 未开始
|
||||
} else if (currentTime >= startTime && currentTime <= endTime) {
|
||||
return 'in_progress'; // 进行中
|
||||
} else {
|
||||
return 'ended'; // 已结束
|
||||
}
|
||||
const [startStr, endStr] = timeRange.split(" - ")
|
||||
const startTime = new Date(startStr).getTime()
|
||||
const endTime = new Date(endStr).getTime()
|
||||
const currentTime = new Date().getTime()
|
||||
|
||||
if (currentTime < startTime) {
|
||||
return "not_started" // 未开始
|
||||
} else if (currentTime >= startTime && currentTime <= endTime) {
|
||||
return "in_progress" // 进行中
|
||||
} else {
|
||||
return "ended" // 已结束
|
||||
}
|
||||
}
|
||||
|
||||
router.beforeEach((to: any, from, next) => {
|
||||
store.commit("set_view_loading", true);
|
||||
//系统维护时间
|
||||
const time = '2026-01-23T21:00:00 - 2026-01-23T22:00:00';
|
||||
if (isTimeRangePassed(time) == 'in_progress') {
|
||||
// 系统维护
|
||||
const toName = to.name === 'upgrade';
|
||||
if(to.query.status == 'admin'){
|
||||
localStorage.setItem('isAdminVisit', 'true')
|
||||
store.commit("set_view_loading", true)
|
||||
//系统维护时间
|
||||
const time = "2026-01-23T21:00:00 - 2026-01-23T22:00:00"
|
||||
if (isTimeRangePassed(time) == "in_progress") {
|
||||
// 系统维护
|
||||
const toName = to.name === "upgrade"
|
||||
if (to.query.status == "admin") {
|
||||
localStorage.setItem("isAdminVisit", "true")
|
||||
}
|
||||
const isAdminVisit = localStorage.getItem('isAdminVisit') == 'true'
|
||||
if(upgradeList.indexOf(to.path) > -1 || isAdminVisit){
|
||||
next();
|
||||
}else{
|
||||
const isAdminVisit = localStorage.getItem("isAdminVisit") == "true"
|
||||
if (upgradeList.indexOf(to.path) > -1 || isAdminVisit) {
|
||||
next()
|
||||
} else {
|
||||
if (toName) {
|
||||
next();
|
||||
next()
|
||||
} else {
|
||||
next({ name: 'upgrade' });
|
||||
next({ name: "upgrade" })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
localStorage.setItem('isAdminVisit', 'false')
|
||||
|
||||
// 机房用户
|
||||
let herfData = window.location.search.substring(1);
|
||||
if (herfData.split("=")[0] == "noLogin" && to.name != "homePage") {
|
||||
setMurmur(herfData.split("=")[1]);
|
||||
return;
|
||||
}
|
||||
let affiliateRef = sessionStorage.getItem("affiliateRef");
|
||||
if (to.query.order) sessionStorage.setItem("orderId", to.query.order); //记录是否点击跳转订单链接
|
||||
if (to.query.ref && affiliateRef != to.query.ref)
|
||||
setViewsIncrease(to.query.ref);
|
||||
localStorage.setItem("isAdminVisit", "false")
|
||||
|
||||
var vuex_systemList: any = sessionStorage.getItem("vuex_systemList");
|
||||
// 机房用户
|
||||
let herfData = window.location.search.substring(1)
|
||||
if (herfData.split("=")[0] == "noLogin" && to.name != "homePage") {
|
||||
setMurmur(herfData.split("=")[1])
|
||||
return
|
||||
}
|
||||
let affiliateRef = sessionStorage.getItem("affiliateRef")
|
||||
if (to.query.order) sessionStorage.setItem("orderId", to.query.order) //记录是否点击跳转订单链接
|
||||
if (to.query.ref && affiliateRef != to.query.ref) setViewsIncrease(to.query.ref)
|
||||
|
||||
var vuex_systemList: any = sessionStorage.getItem("vuex_systemList")
|
||||
if (to.meta.enter == "all") {
|
||||
next();
|
||||
next()
|
||||
} else if (
|
||||
(state.UserHabit?.userDetail?.systemList?.indexOf(to.meta.enter) > -1) || (vuex_systemList?.indexOf(to.meta.enter))
|
||||
state.UserHabit?.userDetail?.systemList?.indexOf(to.meta.enter) > -1 ||
|
||||
vuex_systemList?.indexOf(to.meta.enter)
|
||||
) {
|
||||
next();
|
||||
next()
|
||||
} else {
|
||||
next("/404");
|
||||
next("/404")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if(systemUser == 0){//游客用户只能进入这两个页面
|
||||
});
|
||||
|
||||
// if(systemUser == 0){//游客用户只能进入这两个页面
|
||||
})
|
||||
router.afterEach((to, from) => {
|
||||
store.commit("set_view_loading", false);
|
||||
});
|
||||
export default router;
|
||||
store.commit("set_view_loading", false)
|
||||
})
|
||||
export default router
|
||||
|
||||
@@ -1,529 +0,0 @@
|
||||
<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>
|
||||
@@ -1,202 +0,0 @@
|
||||
<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>
|
||||
@@ -1,233 +0,0 @@
|
||||
<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>
|
||||
@@ -1,276 +0,0 @@
|
||||
<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>
|
||||
@@ -1,177 +0,0 @@
|
||||
<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>
|
||||
@@ -1,156 +0,0 @@
|
||||
<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>
|
||||
@@ -1,81 +0,0 @@
|
||||
<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>
|
||||
@@ -1,370 +0,0 @@
|
||||
<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>
|
||||
@@ -1,82 +0,0 @@
|
||||
<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>
|
||||
@@ -1,191 +0,0 @@
|
||||
<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>
|
||||
@@ -1,268 +0,0 @@
|
||||
<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 '@/tool/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>
|
||||
@@ -1,143 +0,0 @@
|
||||
<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>
|
||||
@@ -373,6 +373,15 @@
|
||||
<i class="fi fi-rs-notebook"></i>
|
||||
<span class="select_item_des">{{ $t('Header.ViewOrders') }}</span>
|
||||
</div>
|
||||
<div class="select_item" @click="onBecomeSeller">
|
||||
<span class="icon"><svg-icon name="seller-sellerIndex" /></span>
|
||||
<span class="select_item_des">{{ $t('Header.BecomeSeller') }}</span>
|
||||
</div>
|
||||
<div class="select_item" @click="onSellerDashboard">
|
||||
<span class="icon"><svg-icon name="seller-sellerIndex" /></span>
|
||||
<span class="select_item_des">{{ $t('Header.SellerDashboard') }}</span>
|
||||
<a-badge :dot="true"></a-badge>
|
||||
</div>
|
||||
<router-link
|
||||
class="select_item"
|
||||
v-if="userDetail.systemList.indexOf(3) >= 0"
|
||||
@@ -1245,6 +1254,12 @@ export default defineComponent({
|
||||
let payOrder = this.$refs.payOrder
|
||||
payOrder.init()
|
||||
},
|
||||
onBecomeSeller(){
|
||||
this.$router.push({ name: 'becomeSeller' })
|
||||
},
|
||||
onSellerDashboard(){
|
||||
this.$router.push({ name: 'brandProfile' })
|
||||
},
|
||||
//教程
|
||||
getTutorial() {
|
||||
let url = 'https://aida-user-manual-chinese.super.site/'
|
||||
@@ -2117,7 +2132,7 @@ export default defineComponent({
|
||||
}
|
||||
> .routerView {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
overflow-y: hidden;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
> .router {
|
||||
|
||||
35
src/views/SellerDashboard/BecomeSeller/index.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div class="become-seller">
|
||||
<seller-header
|
||||
title="Apply to Become a Seller"
|
||||
tip="Join the Stylish Parade and start selling your design work"
|
||||
/>
|
||||
<div class="content">
|
||||
<seller-review v-if="isSubmit" />
|
||||
<seller-apply v-else @submit="isSubmit = true" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from "vue"
|
||||
import sellerHeader from "../seller-header.vue"
|
||||
import sellerReview from "./sellerReview.vue"
|
||||
import sellerApply from "./sellerApply.vue"
|
||||
const isSubmit = ref(false)
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.become-seller {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
> .content {
|
||||
margin-top: 4rem;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
255
src/views/SellerDashboard/BecomeSeller/sellerApply.vue
Normal file
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<div class="seller-apply">
|
||||
<div class="session">
|
||||
<div class="content mini-scrollbar">
|
||||
<div class="title">Brand Information</div>
|
||||
<div class="tip">Share a few details to set up your seller profile</div>
|
||||
<div class="form">
|
||||
<a-form :model="formData" :rules="formRules" layout="vertical" ref="formRef">
|
||||
<a-form-item label="Store Name" name="storeName">
|
||||
<a-input
|
||||
v-model:value="formData.storeName"
|
||||
placeholder="Enter the store name"
|
||||
:maxlength="80"
|
||||
/>
|
||||
<span class="tip-length">{{ formData.storeName.length }}/80</span>
|
||||
</a-form-item>
|
||||
<a-form-item label="Owner’s Full Name" name="fullName">
|
||||
<a-input
|
||||
v-model:value="formData.fullName"
|
||||
placeholder="Enter store owner's full name"
|
||||
/>
|
||||
</a-form-item>
|
||||
<div class="form-group">
|
||||
<a-form-item label="Email" name="email">
|
||||
<a-input
|
||||
type="email"
|
||||
v-model:value="formData.email"
|
||||
placeholder="Enter email"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Phone Number" name="phoneNumber">
|
||||
<a-input
|
||||
type="tel"
|
||||
v-model:value="formData.phoneNumber"
|
||||
placeholder="Enter phone number"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<a-form-item label="Store Description" name="description">
|
||||
<a-textarea
|
||||
v-model:value="formData.description"
|
||||
placeholder="Briefly describe your design style and store features..."
|
||||
:maxlength="500"
|
||||
/>
|
||||
<span class="tip-length">{{ formData.description.length }}/500</span>
|
||||
</a-form-item>
|
||||
<a-form-item label="Portfoilo/Social Media Links">
|
||||
<a-input
|
||||
placeholder="https://"
|
||||
v-for="(v, i) in formData.links"
|
||||
:key="i"
|
||||
v-model:value="formData.links[i]"
|
||||
>
|
||||
<template #prefix>Link {{ i + 1 }}</template>
|
||||
</a-input>
|
||||
<a-input
|
||||
placeholder="https://"
|
||||
v-model:value="newLink"
|
||||
@keyup.enter.prevent="addLink"
|
||||
>
|
||||
<template #prefix>
|
||||
<span @click="addLink" style="cursor: pointer">
|
||||
<svg-icon name="seller-add" size="20" />
|
||||
</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="session">
|
||||
<div class="content">
|
||||
<div class="title">Brand Information</div>
|
||||
<div class="tip">Share a few details to set up your seller profile</div>
|
||||
<div class="agreement">
|
||||
<div class="title">AiDA Seller Agreement</div>
|
||||
<div class="tip">
|
||||
By checking the box below, you agree to comply with the following terms:
|
||||
</div>
|
||||
<ul>
|
||||
<li>Provide accurate and truthful personal and store information</li>
|
||||
<li>Only sell original designs or content with proper licensing</li>
|
||||
<li>Maintain high quality standards for all products</li>
|
||||
<li>Respond to customer inquiries within 48 hours</li>
|
||||
<li>Ship orders within promised timeframes</li>
|
||||
<li>Comply with AiDA's terms of service and community guidelines</li>
|
||||
<li>Pay applicable platform fees and transaction charges</li>
|
||||
<li>Handle customer disputes professionally and fairly</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a-checkbox class="agree-agreement" v-model:checked="isAgreement">
|
||||
I have read and agree to the Seller Agreement, understanding my responsibilities
|
||||
and obligations as a seller on the AiDA platform.
|
||||
</a-checkbox>
|
||||
</div>
|
||||
<div class="btns">
|
||||
<button class="cancel" @click="onCancel">Cancel</button>
|
||||
<button class="submit" :disabled="!isAgreement" @click="onSubmit">
|
||||
Submit Application
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const emit = defineEmits(["submit"])
|
||||
const formRules = {
|
||||
storeName: [{ required: true, message: "Enter the store name" }],
|
||||
fullName: [{ required: true, message: "Enter store owner's full name" }],
|
||||
email: [{ required: true, message: "Enter email" }],
|
||||
phoneNumber: [{ required: true, message: "Enter phone number" }],
|
||||
description: [{ required: true, message: "Enter store description" }]
|
||||
}
|
||||
const formRef = ref(null)
|
||||
const formData = reactive({
|
||||
storeName: "",
|
||||
fullName: "",
|
||||
email: "",
|
||||
phoneNumber: "",
|
||||
description: "",
|
||||
links: ["", ""]
|
||||
})
|
||||
const isAgreement = ref(false)
|
||||
const newLink = ref("")
|
||||
const addLink = () => {
|
||||
formData.links.push(newLink.value)
|
||||
newLink.value = ""
|
||||
}
|
||||
const onCancel = () => {
|
||||
router.back()
|
||||
}
|
||||
const onSubmit = () => {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
console.log(formData)
|
||||
emit("submit")
|
||||
})
|
||||
.catch(() => {
|
||||
console.log("validate failed")
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
@import "@/assets/style/ant-from-style.less";
|
||||
.seller-apply {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 0 10rem;
|
||||
display: flex;
|
||||
gap: 6rem;
|
||||
> .session {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
> .content {
|
||||
max-height: 100%;
|
||||
padding: 2.4rem;
|
||||
border: 1px solid #b0b0b0;
|
||||
border-radius: 2.4rem;
|
||||
overflow-y: auto;
|
||||
|
||||
> .title {
|
||||
font-size: 2.2rem;
|
||||
line-height: 130%;
|
||||
color: #000;
|
||||
margin-bottom: 0.8rem;
|
||||
}
|
||||
> .tip {
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.4rem;
|
||||
line-height: 150%;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
> .form {
|
||||
margin-top: 1.6rem;
|
||||
}
|
||||
> .agreement {
|
||||
padding: 1.6rem;
|
||||
border-radius: 1.2rem;
|
||||
background-color: #f9f9f9;
|
||||
margin-bottom: 2.4rem;
|
||||
> .title {
|
||||
font-size: 1.4rem;
|
||||
color: #000;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
> ul > li,
|
||||
> .tip {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.4rem;
|
||||
color: #737373;
|
||||
}
|
||||
> ul {
|
||||
margin-top: 3rem;
|
||||
padding-left: 2.5rem;
|
||||
> li {
|
||||
margin-bottom: 1rem;
|
||||
list-style-type: disc;
|
||||
}
|
||||
}
|
||||
&:deep(.agree-agreement) {
|
||||
align-items: flex-start;
|
||||
span {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.ant-checkbox-inner,
|
||||
.ant-checkbox-input {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
}
|
||||
.ant-checkbox-inner {
|
||||
border-color: #000 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .btns {
|
||||
margin-top: 3.9rem;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 1.6rem;
|
||||
> button {
|
||||
height: 6rem;
|
||||
border-radius: 6rem;
|
||||
padding: 0 4rem;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
font-size: 1.6rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
&:active:not(:disabled) {
|
||||
opacity: 0.8;
|
||||
}
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
> .cancel {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
border: 0.15rem solid #000;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
126
src/views/SellerDashboard/BecomeSeller/sellerReview.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div class="seller-review">
|
||||
<img class="success" src="@/assets/images/seller/success-1.png" />
|
||||
<div class="title">Application Submitted</div>
|
||||
<div class="tip">
|
||||
Our team will review your application and get back to you within 1–3 business days.
|
||||
You'll receive a notification in your email once a decision has been made.
|
||||
</div>
|
||||
<div class="step-list">
|
||||
<div v-for="v in list" :key="v.title" class="step-item">
|
||||
<img v-show="!v.active" src="@/assets/images/seller/success-0.png" />
|
||||
<img v-show="v.active" src="@/assets/images/seller/success-1.png" />
|
||||
<div class="content">
|
||||
<div class="title">{{ v.title }}</div>
|
||||
<div class="tip">{{ v.tip }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="home-btn" @click="onBackToHome">Back to Homepage</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const list = ref([
|
||||
{
|
||||
title: "Step 1: Submit Application",
|
||||
tip: "Fill out the seller information form and agree to our terms",
|
||||
active: true
|
||||
},
|
||||
{
|
||||
title: "Step 2: Review & Verification",
|
||||
tip: "Our team will review your application (typically 1-3 business days)",
|
||||
active: false
|
||||
},
|
||||
{
|
||||
title: "Step 3: Start Selling",
|
||||
tip: "Once approved, access your seller dashboard and start listing products ",
|
||||
active: false
|
||||
}
|
||||
])
|
||||
const onBackToHome = () => {
|
||||
router.push({ name: "home" })
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.seller-review {
|
||||
margin: 0 auto;
|
||||
width: 60rem;
|
||||
height: 90%;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 2.4rem;
|
||||
> .success {
|
||||
width: 10rem;
|
||||
height: 10rem;
|
||||
padding: 1.2rem;
|
||||
}
|
||||
> .title {
|
||||
font-size: 2.2rem;
|
||||
line-height: 130%;
|
||||
text-align: center;
|
||||
color: #000;
|
||||
}
|
||||
> .tip {
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.8rem;
|
||||
line-height: 170%;
|
||||
text-align: center;
|
||||
color: #585858;
|
||||
}
|
||||
> .step-list {
|
||||
margin: 2.6rem 0;
|
||||
width: 100%;
|
||||
padding: 1.6rem;
|
||||
background-color: #f9f9f9;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.4rem;
|
||||
border-radius: 1.2rem;
|
||||
> .step-item {
|
||||
display: flex;
|
||||
> img {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
margin: 0.2rem;
|
||||
margin-right: 1.2rem;
|
||||
}
|
||||
> .content {
|
||||
flex: 1;
|
||||
font-size: 1.4rem;
|
||||
> .title {
|
||||
font-style: Bold;
|
||||
color: #000;
|
||||
line-height: 150%;
|
||||
}
|
||||
> .tip {
|
||||
font-family: "pingfang_medium";
|
||||
line-height: 170%;
|
||||
color: #737373;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> .home-btn {
|
||||
width: 31rem;
|
||||
height: 6rem;
|
||||
border-radius: 4rem;
|
||||
font-size: 1.6rem;
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
139
src/views/SellerDashboard/BrandProfile/brand-info.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="brand-info">
|
||||
<a-form :model="formData" :rules="isEdit ? formRules : {}" layout="vertical" ref="formRef">
|
||||
<div class="form-group">
|
||||
<a-form-item label="Store Name" name="storeName">
|
||||
<a-input
|
||||
v-model:value="formData.storeName"
|
||||
placeholder="Enter the store name"
|
||||
:maxlength="80"
|
||||
:readonly="!isEdit"
|
||||
/>
|
||||
<span v-show="isEdit" class="tip-length"
|
||||
>{{ formData.storeName.length }}/80</span
|
||||
>
|
||||
</a-form-item>
|
||||
<a-form-item label="Owner’s Full Name" name="fullName">
|
||||
<a-input
|
||||
v-model:value="formData.fullName"
|
||||
placeholder="Enter store owner's full name"
|
||||
:readonly="!isEdit"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<a-form-item label="Email" name="email">
|
||||
<a-input
|
||||
type="email"
|
||||
v-model:value="formData.email"
|
||||
placeholder="Enter email"
|
||||
:readonly="!isEdit"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="Phone Number" name="phoneNumber">
|
||||
<a-input
|
||||
type="tel"
|
||||
v-model:value="formData.phoneNumber"
|
||||
placeholder="Enter phone number"
|
||||
:readonly="!isEdit"
|
||||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<a-form-item label="Portfoilo/Social Media Links">
|
||||
<a-input
|
||||
placeholder="https://"
|
||||
v-for="(v, i) in formData.links"
|
||||
:key="i"
|
||||
v-model:value="formData.links[i]"
|
||||
:readonly="!isEdit"
|
||||
>
|
||||
<template #prefix>Link {{ i + 1 }}</template>
|
||||
</a-input>
|
||||
<a-input
|
||||
placeholder="https://"
|
||||
v-model:value="newLink"
|
||||
@keyup.enter.prevent="addLink"
|
||||
v-if="isEdit"
|
||||
>
|
||||
<template #prefix>
|
||||
<span @click="addLink" style="cursor: pointer">
|
||||
<svg-icon name="seller-add" size="20" />
|
||||
</span>
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="Store Description" name="description">
|
||||
<a-textarea
|
||||
v-model:value="formData.description"
|
||||
placeholder="Briefly describe your design style and store features..."
|
||||
:maxlength="500"
|
||||
:readonly="!isEdit"
|
||||
/>
|
||||
<span v-show="isEdit" class="tip-length"
|
||||
>{{ formData.description.length }}/500</span
|
||||
>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from "vue"
|
||||
import { useRoute, useRouter } from "vue-router"
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const props = defineProps({
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
const formRules = {
|
||||
storeName: [{ required: true, message: "Enter the store name" }],
|
||||
fullName: [{ required: true, message: "Enter store owner's full name" }],
|
||||
email: [{ required: true, message: "Enter email" }],
|
||||
phoneNumber: [{ required: true, message: "Enter phone number" }],
|
||||
description: [{ required: true, message: "Enter store description" }]
|
||||
}
|
||||
|
||||
const formRef = ref(null)
|
||||
const formData = reactive({
|
||||
storeName: "",
|
||||
fullName: "",
|
||||
email: "",
|
||||
phoneNumber: "",
|
||||
description: "",
|
||||
links: ["", ""]
|
||||
})
|
||||
const newLink = ref("")
|
||||
const addLink = () => {
|
||||
formData.links.push(newLink.value)
|
||||
newLink.value = ""
|
||||
}
|
||||
watch(
|
||||
() => props.isEdit,
|
||||
(v) => (v ? edit() : cancel())
|
||||
)
|
||||
const edit = () => {}
|
||||
const cancel = () => {}
|
||||
const submit = async () => {
|
||||
const valid = await formRef.value.validate()
|
||||
if (!valid) return Promise.reject(false)
|
||||
console.log(valid)
|
||||
return valid
|
||||
}
|
||||
defineExpose({
|
||||
submit
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
@import "@/assets/style/ant-from-style.less";
|
||||
.brand-info {
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// overflow: hidden;
|
||||
// padding: 0 10rem;
|
||||
}
|
||||
</style>
|
||||
183
src/views/SellerDashboard/BrandProfile/index.vue
Normal file
@@ -0,0 +1,183 @@
|
||||
<template>
|
||||
<div class="brand-profile-index">
|
||||
<div class="header">
|
||||
<div class="bg">
|
||||
<img v-if="banner" :src="banner" />
|
||||
<div v-else class="null">
|
||||
<span class="icon"><svg-icon name="seller-picture" size="60" /></span>
|
||||
<span class="tip">Your brand banner has not been set up yet.</span>
|
||||
</div>
|
||||
<button>Change Brand Banner</button>
|
||||
</div>
|
||||
<!-- 头像 -->
|
||||
<div class="avatar">
|
||||
<img v-if="avatar" :src="avatar" />
|
||||
<div v-else class="null">
|
||||
<svg-icon name="seller-user" size="48" />
|
||||
</div>
|
||||
<span class="icon">
|
||||
<svg-icon name="seller-camera" size="24" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<brand-info :is-edit="isEdit" ref="brandInfoRef" />
|
||||
</div>
|
||||
<div class="and-profile-footer">
|
||||
<template v-if="isEdit">
|
||||
<div class="btns">
|
||||
<button class="cancel" @click="onCancel">Cancel</button>
|
||||
<button class="submit" @click="onSubmit">Save Change</button>
|
||||
</div>
|
||||
<p class="tip">Changes will be reflected on your Stylish Parade brand page.</p>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="btns">
|
||||
<button class="edit" @click="onEdit">Edit</button>
|
||||
</div>
|
||||
<p class="tip"> </p>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue"
|
||||
import BrandInfo from "./brand-info.vue"
|
||||
const banner = ref("http://118.31.39.42:3000/falls/5bd8065cbb396eb5a8ef0a142605139358734e57.png")
|
||||
const avatar = ref("http://118.31.39.42:3000/falls/20251024140128_10355_1.jpg")
|
||||
const isEdit = ref(false)
|
||||
const brandInfoRef = ref(null)
|
||||
const onEdit = () => {
|
||||
isEdit.value = true
|
||||
}
|
||||
const onCancel = () => {
|
||||
isEdit.value = false
|
||||
}
|
||||
const onSubmit = () => {
|
||||
brandInfoRef.value
|
||||
.submit()
|
||||
.then(() => {
|
||||
isEdit.value = false
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.brand-profile-index {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0 8rem;
|
||||
margin: 0 7rem;
|
||||
> .header {
|
||||
position: relative;
|
||||
margin-bottom: 6rem;
|
||||
> .bg {
|
||||
position: relative;
|
||||
> img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: 1.2rem;
|
||||
}
|
||||
> .null {
|
||||
width: 100%;
|
||||
height: 23rem;
|
||||
border-radius: 1.2rem;
|
||||
border: 1px dashed #b0b0b0;
|
||||
background: #f9f9f9;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
> .tip {
|
||||
margin-top: 1.2rem;
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.6rem;
|
||||
color: rgba(153, 153, 153, 0.6);
|
||||
}
|
||||
}
|
||||
> button {
|
||||
position: absolute;
|
||||
bottom: 1.6rem;
|
||||
right: 1.6rem;
|
||||
padding: 0 2.7rem;
|
||||
border-radius: 4rem;
|
||||
height: 4.5rem;
|
||||
border: none;
|
||||
background-color: #fff;
|
||||
box-shadow: 0.2rem 0.2rem 1.2rem 0 rgba(0, 0, 0, 0.1);
|
||||
font-family: pingfang_medium;
|
||||
font-size: 1.6rem;
|
||||
cursor: pointer;
|
||||
color: #000;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
> .avatar {
|
||||
position: absolute;
|
||||
left: 6rem;
|
||||
bottom: -4rem;
|
||||
> img,
|
||||
> .null {
|
||||
width: 12rem;
|
||||
height: 12rem;
|
||||
border-radius: 1.2rem;
|
||||
border: 0.15rem solid #919191;
|
||||
}
|
||||
> .null {
|
||||
background-color: #f2f1f1;
|
||||
}
|
||||
> .icon {
|
||||
position: absolute;
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: 50%;
|
||||
background: rgba(146, 146, 146, 0.96);
|
||||
right: -1.6rem;
|
||||
bottom: -1.6rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.and-profile-footer {
|
||||
margin: 0 15rem;
|
||||
> .btns {
|
||||
margin-top: 3rem;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-right: 1.6rem;
|
||||
gap: 1.3rem;
|
||||
> button {
|
||||
height: 6rem;
|
||||
border-radius: 6rem;
|
||||
padding: 0 4rem;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
font-size: 1.6rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
&:active:not(:disabled) {
|
||||
opacity: 0.8;
|
||||
}
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
> .cancel {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
border: 0.15rem solid #000;
|
||||
}
|
||||
}
|
||||
> .tip {
|
||||
padding-right: 1.6rem;
|
||||
margin-top: 0.7rem;
|
||||
font-family: pingfang_regular;
|
||||
font-size: 1.4rem;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
88
src/views/SellerDashboard/MyListings/EditDetail/index.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="edit-detail-wrapper">
|
||||
<seller-header
|
||||
title="Edit Listing Details"
|
||||
:breadcrumbs="[
|
||||
{ title: 'My Listings', name: 'myListingsIndex' },
|
||||
{ title: 'Select Collection', name: 'myListingsSelect' },
|
||||
{ title: 'Select Sketch', name: 'myListingsSelectItem' },
|
||||
{ title: 'Edit Listing Details', name: 'EditDetail' }
|
||||
]"
|
||||
>
|
||||
<template #right>
|
||||
<div class="operate-menu flex">
|
||||
<div class="menu-btn flex align-center save">
|
||||
<span>Save Draft</span>
|
||||
<SvgIcon name="CSave" color="#000000" size="16" />
|
||||
</div>
|
||||
<div class="menu-btn flex align-center publish">
|
||||
<span>Publish</span>
|
||||
<SvgIcon name="CPublish" color="#ffffff" size="16" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</seller-header>
|
||||
<div class="edit-detail-content flex space-between">
|
||||
<div class="left">
|
||||
<div class="main-image-container flex">
|
||||
<div class="sketch"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue"
|
||||
import SellerHeader from "../../seller-header.vue"
|
||||
|
||||
const currentIndex = ref(0)
|
||||
const selectList = ref([
|
||||
{
|
||||
sketch: "",
|
||||
mainProductImage: "",
|
||||
cover: "",
|
||||
productImage: [],
|
||||
apparelSketch: [],
|
||||
productName: "",
|
||||
price: "",
|
||||
desc: '',
|
||||
gender: '',
|
||||
category:''
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.c-svg {
|
||||
width: initial;
|
||||
}
|
||||
|
||||
.edit-detail-wrapper {
|
||||
.menu-btn {
|
||||
height: 6rem;
|
||||
border: 0.15rem solid #000000;
|
||||
border-radius: 4rem;
|
||||
text-align: center;
|
||||
line-height: 6rem;
|
||||
padding: 0 2rem;
|
||||
font-weight: 400;
|
||||
font-size: 1.6rem;
|
||||
column-gap: 0.8rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.operate-menu {
|
||||
column-gap: 2rem;
|
||||
|
||||
.publish {
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-detail-content {
|
||||
padding-right: 6.4rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
47
src/views/SellerDashboard/MyListings/createSelect/index.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
|
||||
import sellerHeader from "../../seller-header.vue"
|
||||
|
||||
//const props = defineProps({
|
||||
//})
|
||||
//const emit = defineEmits([
|
||||
//])
|
||||
let data = reactive({
|
||||
})
|
||||
onMounted(()=>{
|
||||
})
|
||||
onUnmounted(()=>{
|
||||
})
|
||||
defineExpose({})
|
||||
const {} = toRefs(data);
|
||||
</script>
|
||||
<template>
|
||||
<div class="myListings-seller">
|
||||
<seller-header
|
||||
title="Select Collection"
|
||||
:breadcrumbs="[
|
||||
{title:'My Listings', name:'myListingsIndex'},
|
||||
{title:'Select Collection', name: 'myListingsSelect' }
|
||||
]"
|
||||
>
|
||||
</seller-header>
|
||||
<div class="content">
|
||||
1231222aaa
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="less">
|
||||
.myListings-seller {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
> .content {
|
||||
margin-top: 2rem;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||