移动端UI
@ -45,6 +45,7 @@
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.3.0",
|
||||
"vite-plugin-vue-devtools": "^8.0.5",
|
||||
"vite-svg-loader": "^5.1.0",
|
||||
"vue-tsc": "^3.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
130
pnpm-lock.yaml
generated
@ -90,6 +90,9 @@ importers:
|
||||
vite-plugin-vue-devtools:
|
||||
specifier: ^8.0.5
|
||||
version: 8.0.5(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2))(vue@3.5.26(typescript@5.9.3))
|
||||
vite-svg-loader:
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0(vue@3.5.26(typescript@5.9.3))
|
||||
vue-tsc:
|
||||
specifier: ^3.2.1
|
||||
version: 3.2.1(typescript@5.9.3)
|
||||
@ -713,6 +716,10 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^2.7.0 || ^3.0.0
|
||||
|
||||
'@trysound/sax@0.2.0':
|
||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
'@tsconfig/node24@24.0.3':
|
||||
resolution: {integrity: sha512-vcERKtKQKHgzt/vfS3Gjasd8SUI2a0WZXpgJURdJsMySpS5+ctgbPfuLj2z/W+w4lAfTWxoN4upKfu2WzIRYnw==}
|
||||
|
||||
@ -1007,6 +1014,10 @@ packages:
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
commander@7.2.0:
|
||||
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
concat-map@0.0.1:
|
||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||
|
||||
@ -1021,11 +1032,30 @@ packages:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
css-select@5.2.2:
|
||||
resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==}
|
||||
|
||||
css-tree@2.2.1:
|
||||
resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==}
|
||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
|
||||
|
||||
css-tree@2.3.1:
|
||||
resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
|
||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
|
||||
|
||||
css-what@6.2.2:
|
||||
resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
csso@5.0.5:
|
||||
resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==}
|
||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'}
|
||||
|
||||
csstype@3.2.3:
|
||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||
|
||||
@ -1060,6 +1090,19 @@ packages:
|
||||
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||
|
||||
domelementtype@2.3.0:
|
||||
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
|
||||
|
||||
domhandler@5.0.3:
|
||||
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
|
||||
engines: {node: '>= 4'}
|
||||
|
||||
domutils@3.2.2:
|
||||
resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==}
|
||||
|
||||
electron-to-chromium@1.5.267:
|
||||
resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==}
|
||||
|
||||
@ -1067,6 +1110,10 @@ packages:
|
||||
resolution: {integrity: sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
entities@4.5.0:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
entities@7.0.0:
|
||||
resolution: {integrity: sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==}
|
||||
engines: {node: '>=0.12'}
|
||||
@ -1429,6 +1476,12 @@ packages:
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
mdn-data@2.0.28:
|
||||
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
||||
|
||||
mdn-data@2.0.30:
|
||||
resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
|
||||
|
||||
memorystream@0.3.1:
|
||||
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
@ -1705,6 +1758,11 @@ packages:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
svgo@3.3.2:
|
||||
resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
synckit@0.11.11:
|
||||
resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
@ -1809,6 +1867,11 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0
|
||||
|
||||
vite-svg-loader@5.1.0:
|
||||
resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==}
|
||||
peerDependencies:
|
||||
vue: '>=3.2.13'
|
||||
|
||||
vite@7.3.0:
|
||||
resolution: {integrity: sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@ -2469,6 +2532,8 @@ snapshots:
|
||||
'@tanstack/virtual-core': 3.13.13
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
|
||||
'@trysound/sax@0.2.0': {}
|
||||
|
||||
'@tsconfig/node24@24.0.3': {}
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
@ -2851,6 +2916,8 @@ snapshots:
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
commander@7.2.0: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
@ -2865,8 +2932,32 @@ snapshots:
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
css-select@5.2.2:
|
||||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
css-what: 6.2.2
|
||||
domhandler: 5.0.3
|
||||
domutils: 3.2.2
|
||||
nth-check: 2.1.1
|
||||
|
||||
css-tree@2.2.1:
|
||||
dependencies:
|
||||
mdn-data: 2.0.28
|
||||
source-map-js: 1.2.1
|
||||
|
||||
css-tree@2.3.1:
|
||||
dependencies:
|
||||
mdn-data: 2.0.30
|
||||
source-map-js: 1.2.1
|
||||
|
||||
css-what@6.2.2: {}
|
||||
|
||||
cssesc@3.0.0: {}
|
||||
|
||||
csso@5.0.5:
|
||||
dependencies:
|
||||
css-tree: 2.2.1
|
||||
|
||||
csstype@3.2.3: {}
|
||||
|
||||
debug@4.4.3:
|
||||
@ -2888,6 +2979,24 @@ snapshots:
|
||||
|
||||
detect-libc@2.1.2: {}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
entities: 4.5.0
|
||||
|
||||
domelementtype@2.3.0: {}
|
||||
|
||||
domhandler@5.0.3:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
|
||||
domutils@3.2.2:
|
||||
dependencies:
|
||||
dom-serializer: 2.0.0
|
||||
domelementtype: 2.3.0
|
||||
domhandler: 5.0.3
|
||||
|
||||
electron-to-chromium@1.5.267: {}
|
||||
|
||||
enhanced-resolve@5.18.4:
|
||||
@ -2895,6 +3004,8 @@ snapshots:
|
||||
graceful-fs: 4.2.11
|
||||
tapable: 2.3.0
|
||||
|
||||
entities@4.5.0: {}
|
||||
|
||||
entities@7.0.0: {}
|
||||
|
||||
error-stack-parser-es@1.0.5: {}
|
||||
@ -3226,6 +3337,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
|
||||
mdn-data@2.0.28: {}
|
||||
|
||||
mdn-data@2.0.30: {}
|
||||
|
||||
memorystream@0.3.1: {}
|
||||
|
||||
merge2@1.4.1: {}
|
||||
@ -3445,6 +3560,16 @@ snapshots:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
svgo@3.3.2:
|
||||
dependencies:
|
||||
'@trysound/sax': 0.2.0
|
||||
commander: 7.2.0
|
||||
css-select: 5.2.2
|
||||
css-tree: 2.3.1
|
||||
css-what: 6.2.2
|
||||
csso: 5.0.5
|
||||
picocolors: 1.1.1
|
||||
|
||||
synckit@0.11.11:
|
||||
dependencies:
|
||||
'@pkgr/core': 0.2.9
|
||||
@ -3564,6 +3689,11 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-svg-loader@5.1.0(vue@3.5.26(typescript@5.9.3)):
|
||||
dependencies:
|
||||
svgo: 3.3.2
|
||||
vue: 3.5.26(typescript@5.9.3)
|
||||
|
||||
vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2):
|
||||
dependencies:
|
||||
esbuild: 0.27.2
|
||||
|
||||
18
src/App.vue
@ -1,9 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { RouterView } from 'vue-router'
|
||||
import 'vue-sonner/style.css'
|
||||
import { Toaster } from '@/components/ui/sonner'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<RouterView />
|
||||
<div>
|
||||
<main>
|
||||
<RouterView />
|
||||
</main>
|
||||
<Toaster
|
||||
position="top-center"
|
||||
:toast-options="{
|
||||
style: {
|
||||
background: '#000000',
|
||||
color: '#ffffff',
|
||||
border: '1px solid rgba(255, 255, 255, 0.1)',
|
||||
},
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
||||
33
src/components/ui/input/Input.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from "vue"
|
||||
import { useVModel } from "@vueuse/core"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const props = defineProps<{
|
||||
defaultValue?: string | number
|
||||
modelValue?: string | number
|
||||
class?: HTMLAttributes["class"]
|
||||
}>()
|
||||
|
||||
const emits = defineEmits<{
|
||||
(e: "update:modelValue", payload: string | number): void
|
||||
}>()
|
||||
|
||||
const modelValue = useVModel(props, "modelValue", emits, {
|
||||
passive: true,
|
||||
defaultValue: props.defaultValue,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<input
|
||||
v-model="modelValue"
|
||||
data-slot="input"
|
||||
:class="cn(
|
||||
'file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
|
||||
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
|
||||
'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
|
||||
props.class,
|
||||
)"
|
||||
>
|
||||
</template>
|
||||
1
src/components/ui/input/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as Input } from "./Input.vue"
|
||||
36
src/components/user-center/DeviceList.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { Laptop, Smartphone } from 'lucide-vue-next'
|
||||
|
||||
interface Device {
|
||||
id: string
|
||||
name: string
|
||||
type: 'mobile' | 'desktop'
|
||||
deviceId: string
|
||||
}
|
||||
|
||||
defineProps<{
|
||||
devices: Device[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center justify-center gap-3">
|
||||
<div
|
||||
v-for="device in devices"
|
||||
:key="device.id"
|
||||
class="h-[76px] rounded-3xl border-2 p-4 text-[10px]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<Smartphone v-if="device.type === 'mobile'" class="h-5 w-5 text-white" />
|
||||
<Laptop v-else class="h-5 w-5 text-white" />
|
||||
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<span class="text-white">设备: {{ device.name }}</span>
|
||||
<span class="font-mono text-[11px] tracking-tighter uppercase"
|
||||
>ID: {{ device.deviceId }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
76
src/components/user-center/PaymentMethod.vue
Normal file
@ -0,0 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
interface PaymentOption {
|
||||
label: string
|
||||
value: number
|
||||
}
|
||||
|
||||
const list = ref<PaymentOption[]>([
|
||||
{ label: '支付宝', value: 1 },
|
||||
{ label: '微信', value: 2 },
|
||||
{ label: '国际银行卡', value: 3 },
|
||||
])
|
||||
|
||||
// 当前选中的值,默认选中第一个
|
||||
const selectedValue = ref(1)
|
||||
|
||||
const handleSelect = (value: number) => {
|
||||
selectedValue.value = value
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="bg-[#A8FF53] px-6 pt-7 font-sans text-black">
|
||||
<h2 class="mb-1 text-center text-2xl font-bold">选择付款方式</h2>
|
||||
|
||||
<div class="flex flex-col gap-4 pt-[43px]">
|
||||
<div
|
||||
v-for="item in list"
|
||||
:key="item.value"
|
||||
@click="handleSelect(item.value)"
|
||||
:class="[
|
||||
'flex h-[66px] cursor-pointer items-center justify-between border-[5px] border-black px-6 transition-all active:scale-[0.98]',
|
||||
'rounded-[32px]', // 超大圆角
|
||||
selectedValue === item.value ? 'bg-[#A8FF53]' : 'bg-[#A8FF53]',
|
||||
]"
|
||||
>
|
||||
<span class="text-xl font-semibold">{{ item.label }}</span>
|
||||
|
||||
<div
|
||||
class="flex h-7 w-7 items-center justify-center rounded-full border-[1px] border-black bg-transparent"
|
||||
>
|
||||
<div
|
||||
v-if="selectedValue === item.value"
|
||||
class="h-3.5 w-3.5 rounded-full bg-black"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-6 pt-[55px]">
|
||||
<h2 class="mb-1 text-center text-2xl font-bold">订单信息</h2>
|
||||
<div class="ml-[11px] pt-[22px] text-[16px] font-semibold">365天套餐</div>
|
||||
<div class="ml-[11px] flex items-center justify-between pt-[22px] text-[16px] font-semibold">
|
||||
<div>订单金额</div>
|
||||
<div>USD 44.99</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-6 pt-[85px] pb-[23px]">
|
||||
<Button
|
||||
class="h-[50px] w-full rounded-[32px] border-none bg-black text-[16px] font-black text-white hover:bg-black/90"
|
||||
>
|
||||
立即支付
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 如果需要特殊的斜体感,可以在这里微调 */
|
||||
span {
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
</style>
|
||||
40
src/components/user-center/PlanCard.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div class="px-6 pt-7 font-sans">
|
||||
<h2 class="mb-1 text-center text-2xl font-bold">套餐选择</h2>
|
||||
<p class="mb-4 text-center text-sm font-[100] text-gray-600">*所有套餐均不限流量不限速度</p>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
v-for="(plan, index) in plans"
|
||||
:key="plan.id"
|
||||
@click="$emit('select', plan.id)"
|
||||
:class="[
|
||||
'relative h-[126px] cursor-pointer overflow-hidden rounded-[40px] border-4 border-black py-4 pl-[45px] transition-all',
|
||||
currentPlanIndex === index ? 'bg-black text-white' : 'bg-[#A8FF53] text-black',
|
||||
]"
|
||||
>
|
||||
<div class="text-2xl font-bold">{{ plan.days }}天</div>
|
||||
<div class="text-[40px] leading-none font-semibold">${{ plan.price }}</div>
|
||||
<div :class="'text-sm'">约${{ plan.daily }}/天</div>
|
||||
<div
|
||||
v-if="plan.discount"
|
||||
:class="[
|
||||
index > 1 ? 'font-semibold' : '',
|
||||
currentPlanIndex === index ? 'bg-[#A8FF53]! text-black' : ' ',
|
||||
]"
|
||||
class="absolute top-[20px] -right-[40px] h-[16px] w-[126px] origin-center rotate-45 bg-black text-center text-[14px] leading-[16px] font-[200] text-[#ADFF5B]"
|
||||
>
|
||||
111 off%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
plans: Array,
|
||||
currentPlanIndex: Number,
|
||||
})
|
||||
defineEmits(['select'])
|
||||
</script>
|
||||
107
src/pages/Help/DownloadMethodList/DownloadMethodList.vue
Normal file
@ -0,0 +1,107 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import ArrowIcon from './arrow-icon.svg?component'
|
||||
import StartIcon from './Star-1.svg?component'
|
||||
|
||||
// 直接在内部定义数据
|
||||
const downloadMethods = ref([
|
||||
{
|
||||
id: 1,
|
||||
title: '创建新“香港Apple ID”',
|
||||
subtitle: '首推',
|
||||
isHot: true,
|
||||
highlight: '',
|
||||
details:
|
||||
'这是最稳定的方式。步骤:1. 访问 Apple 官网... 2. 注册地区选择香港... 3. 无需绑定卡片即可下载。',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '修改已有 Apple ID 至 <香港>',
|
||||
subtitle: '',
|
||||
isHot: false,
|
||||
highlight: '',
|
||||
details: '1. 打开 App Store 个人中心... 2. 点击国家/地区... 3. 更改为香港并填写虚拟地址。',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '使用Hi快提供的公用账号',
|
||||
subtitle: '',
|
||||
isHot: false,
|
||||
highlight: '谨慎选择',
|
||||
details: '注意:千万不要在设置(Settings)中登录公用账号!仅在 App Store 中登录,否则可能锁机。',
|
||||
},
|
||||
])
|
||||
|
||||
const activeId = ref<number | null>(null)
|
||||
|
||||
const toggle = (id: number) => {
|
||||
activeId.value = activeId.value === id ? null : id
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="font-sans text-white">
|
||||
<div class="flex flex-col gap-5">
|
||||
<div
|
||||
v-for="item in downloadMethods"
|
||||
:key="item.id"
|
||||
@click="toggle(item.id)"
|
||||
class="group relative flex cursor-pointer flex-col rounded-[30px] border-[4px] border-white bg-black pt-4 pb-2 transition-all active:scale-[0.97]"
|
||||
>
|
||||
<div class="px-4">
|
||||
<div class="flex flex-wrap items-center gap-x-2 text-sm leading-tight font-bold">
|
||||
<StartIcon v-if="item.isHot" />
|
||||
<span>{{ item.title }}</span>
|
||||
|
||||
<span v-if="item.subtitle" class="font-medium">——{{ item.subtitle }}</span>
|
||||
|
||||
<span v-if="item.highlight" class="font-black text-[#FF00FF]"
|
||||
>——{{ item.highlight }}</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<!-- 打开按钮 -->
|
||||
<div
|
||||
class="mt-2 flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100"
|
||||
>
|
||||
<div v-show="activeId !== item.id" class="flex items-center gap-[10px]">
|
||||
<span class="tracking-tight">点击展开详情</span>
|
||||
<ArrowIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="activeId === item.id" class="px-2">
|
||||
<div
|
||||
class="animate-in fade-in zoom-in-95 border-t-2 border-white pt-[10px] text-[15px] leading-relaxed text-gray-300 duration-200"
|
||||
>
|
||||
<!-- 收起按钮 -->
|
||||
<div class="px-2">
|
||||
<div
|
||||
class="flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100"
|
||||
>
|
||||
<div class="flex items-center gap-[10px]">
|
||||
<span class="tracking-tight">点击收起</span>
|
||||
<ArrowIcon class="rotate-180" />
|
||||
</div>
|
||||
</div>
|
||||
<p class="whitespace-pre-line">{{ item.details }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 针对整体风格进行微调 */
|
||||
.font-bold {
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
/* 移除移动端点击的高亮蓝色框 */
|
||||
div {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
</style>
|
||||
3
src/pages/Help/DownloadMethodList/Star-1.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="19" viewBox="0 0 20 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.5105 0L11.7556 6.90983H19.0211L13.1432 11.1803L15.3884 18.0902L9.5105 13.8197L3.63265 18.0902L5.87779 11.1803L-6.67572e-05 6.90983H7.26536L9.5105 0Z" fill="#ADFF5B"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 282 B |
3
src/pages/Help/DownloadMethodList/arrow-icon.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.35098 0.101416L4.35098 7.62314C4.35079 7.64339 4.34446 7.66314 4.33279 7.6799C4.32112 7.69666 4.30463 7.70968 4.28539 7.71733C4.26615 7.72497 4.24502 7.72689 4.22467 7.72286C4.20431 7.71882 4.18563 7.70901 4.17097 7.69465L0.178818 3.7225C0.164119 3.70767 0.145131 3.69756 0.124387 3.69352C0.103641 3.68948 0.0821265 3.69171 0.0627125 3.6999C0.0432995 3.7081 0.0269087 3.72187 0.0157297 3.73938C0.00455077 3.75689 -0.000885175 3.77731 0.000145746 3.79792L0.105484 7.51912C0.105567 7.53222 0.10832 7.54517 0.113585 7.55723C0.11885 7.56928 0.126521 7.58019 0.136151 7.58933L5.52169 12.9683C5.53164 12.9783 5.54355 12.9863 5.55672 12.9917C5.5699 12.9972 5.58405 13 5.59836 13C5.61267 13 5.62683 12.9972 5.64 12.9917C5.65317 12.9863 5.66508 12.9783 5.67503 12.9683L11.1966 7.61793C11.2067 7.60781 11.2146 7.5958 11.2199 7.58262C11.2252 7.56944 11.2277 7.55536 11.2272 7.54122L11.1672 4.14767C11.1668 4.12768 11.1604 4.10825 11.1488 4.09176C11.1372 4.07527 11.1209 4.06244 11.1019 4.05485C11.083 4.04726 11.0621 4.04523 11.042 4.04901C11.0219 4.0528 11.0033 4.06223 10.9886 4.07616L7.19242 7.67124C7.17788 7.68535 7.15939 7.69494 7.13926 7.69882C7.11914 7.7027 7.0983 7.70069 7.07934 7.69305C7.06039 7.68541 7.04418 7.67247 7.03274 7.65587C7.02131 7.63926 7.01516 7.61973 7.01508 7.59973L7.01508 0.221036C7.01576 0.185813 7.01843 0.150654 7.02308 0.115719C7.02518 0.101361 7.0241 0.0867316 7.0199 0.0728175C7.01571 0.0589035 7.0085 0.0460284 6.99877 0.0350608C6.98904 0.0240932 6.97701 0.0152882 6.96349 0.00923998C6.94998 0.00319171 6.93529 4.07951e-05 6.92041 -1.8826e-07L4.45499 -2.96027e-07C4.4274 -2.97233e-07 4.40095 0.0106846 4.38144 0.0297039C4.36194 0.0487232 4.35098 0.0745188 4.35098 0.101416Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
3
src/pages/Help/FAQAccordion/arrow-icon2.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="11" viewBox="0 0 20 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.664368 0.747314L9.66437 8.74731L18.6644 0.747314" stroke="white" stroke-width="2"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 199 B |
83
src/pages/Help/FAQAccordion/index.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
// 按照你的要求引入 SVG 组件
|
||||
import ArrowIcon from './arrow-icon2.svg?component'
|
||||
|
||||
// 内置 FAQ 数据
|
||||
const faqList = ref([
|
||||
{
|
||||
id: 1,
|
||||
question: '登陆公共 Apple ID 时,出现“双重验证”提示,且要求输入验证码怎么办?',
|
||||
answer:
|
||||
'这是由于有其他用户没有按照教程操作,将公共 Apple ID 绑定手机号码,开启了双重验证所导致。\n\n解决办法:请您先清除浏览器缓存,再刷新本页面,获取新的公共 Apple ID,接着请按照教程一步一步操作。',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
question: '连接成功后依然无法访问海外网站?',
|
||||
answer:
|
||||
'1. 请检查您的系统时间是否为自动同步。\n2. 尝试在 App 设置中切换不同的协议(如 Vless 或 Trojan)。\n3. 确认您的套餐流量是否已耗尽。',
|
||||
},
|
||||
])
|
||||
|
||||
const activeId = ref<number | null>(null)
|
||||
|
||||
const toggle = (id: number) => {
|
||||
activeId.value = activeId.value === id ? null : id
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="] bg-black font-sans text-white">
|
||||
<div class="rounded-[30px]">
|
||||
<div class="flex flex-col">
|
||||
<div v-for="(item, index) in faqList" :key="item.id" class="flex flex-col">
|
||||
<div
|
||||
@click="toggle(item.id)"
|
||||
class="flex cursor-pointer items-center justify-between py-4 transition-opacity active:opacity-70"
|
||||
>
|
||||
<h3 class="pr-5 text-[17px] leading-snug font-bold tracking-tight">
|
||||
{{ item.question }}
|
||||
</h3>
|
||||
|
||||
<ArrowIcon
|
||||
:class="[
|
||||
'mt-1 h-5 w-5 shrink-0 transition-transform duration-300',
|
||||
activeId === item.id ? 'rotate-180' : '',
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<transition
|
||||
enter-active-class="transition-all duration-300 ease-out"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
enter-from-class="max-h-0 opacity-0"
|
||||
enter-to-class="max-h-[500px] opacity-100"
|
||||
leave-from-class="max-h-[500px] opacity-100"
|
||||
leave-to-class="max-h-0 opacity-0"
|
||||
>
|
||||
<div v-if="activeId === item.id" class="overflow-hidden">
|
||||
<div class="pb-6 text-[15px] leading-relaxed text-white/60">
|
||||
<p class="whitespace-pre-line">{{ item.answer }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<div class="h-[4px] w-full bg-[#757575]"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* 针对你 UI 稿件中的特定字体样式 */
|
||||
h3 {
|
||||
/* 还原图中略微紧凑的文字排版 */
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
/* 移除移动端点击灰色高亮 */
|
||||
div {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
</style>
|
||||
@ -1,10 +1,94 @@
|
||||
<template>
|
||||
<div class="container mx-auto p-8">
|
||||
<h1 class="text-3xl font-bold mb-4">Help Page</h1>
|
||||
<p class="text-gray-600">This is the help page content.</p>
|
||||
<div class="min-h-screen bg-black text-white">
|
||||
<!-- Full Width Header -->
|
||||
<div class="h-[88px]">
|
||||
<header
|
||||
class="fixed top-[20px] right-[18px] left-[18px] z-50 flex h-[68px] items-center justify-between rounded-[90px] bg-[#ADFF5B] pr-[30px] pl-6"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Desktop Logo -->
|
||||
<Logo :src="Logo" alt="Hi快VPN" class="hidden h-10 w-auto text-black md:block" />
|
||||
<!-- Mobile Logo -->
|
||||
<MobileLogo
|
||||
:src="MobileLogo"
|
||||
alt="Hi快VPN"
|
||||
class="block h-[28px] w-[67px] text-black md:hidden"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-xl font-[600] text-black">Hi快iOS版本下载教程</div>
|
||||
</header>
|
||||
</div>
|
||||
<div class="px-[18px]">
|
||||
<div class="pt-[34px] pb-[15px] text-center text-xl font-[900]">请选择适用您情形的选项</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<div
|
||||
class="w-1/2 rounded-[32px] border-5 p-[6px]"
|
||||
:class="[activeIndex === 0 ? 'border-white' : 'border-black']"
|
||||
@click="activeIndex = 0"
|
||||
>
|
||||
<Button
|
||||
class="w-full cursor-pointer rounded-[32px] bg-[#ADFF5B] text-black hover:bg-[#ADFF5B]/90"
|
||||
>
|
||||
我只有中国大陆Apple ID
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
class="w-1/2 rounded-[32px] border-5 p-[6px]"
|
||||
:class="[activeIndex === 1 ? 'border-white' : 'border-black']"
|
||||
@click="activeIndex = 1"
|
||||
>
|
||||
<Button
|
||||
class="w-full cursor-pointer rounded-[32px] bg-[#ADFF5B] text-black hover:bg-[#ADFF5B]/90"
|
||||
>
|
||||
我有海外Apple ID
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- tab1 -->
|
||||
<div v-show="activeIndex === 0">
|
||||
<div class="pt-[34px] pb-[15px] text-center text-xl font-[900]">Hi快提供三种下载方式</div>
|
||||
<DownloadMethodList />
|
||||
</div>
|
||||
<div v-show="activeIndex === 1">
|
||||
<div class="pt-[34px] pb-[15px] text-center font-[900]">
|
||||
登陆海外 Apple ID 后再点击下方下载按钮
|
||||
</div>
|
||||
</div>
|
||||
<!-- tab2 -->
|
||||
</div>
|
||||
|
||||
<div class="px-[18px]">
|
||||
<div class="pt-[56px] pb-[15px] text-center text-xl font-[900]">常见问题与解答</div>
|
||||
<div class="px-[24px]">
|
||||
<FAQAccordion />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-[18px] pt-[34px]">
|
||||
<div class="mx-auto w-[240px] text-center font-black text-[#757575]">
|
||||
若您在下载过程中遇到任何问题,
|
||||
<br class="md:hidden" />
|
||||
点击右下角在线客服按钮,
|
||||
<br class="md:hidden" />
|
||||
会有专业客服帮您解决问题
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-[18px] pt-[34px] pb-[calc(50px+env(safe-area-inset-bottom))]">
|
||||
<div class="pb-[15px] text-center text-xl font-[900]">其他客户端下载</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
// Help page logic
|
||||
import Logo from '@/pages/Home/logo.svg?component'
|
||||
import MobileLogo from '@/pages/Home/mobile-logo.svg?component'
|
||||
import DownloadMethodList from './DownloadMethodList/DownloadMethodList.vue'
|
||||
import FAQAccordion from './FAQAccordion/index.vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
|
||||
const activeIndex = ref(0)
|
||||
</script>
|
||||
|
||||
@ -1,26 +1,84 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { toast } from 'vue-sonner'
|
||||
|
||||
const email = ref('')
|
||||
const code = ref('')
|
||||
const countdown = ref(0)
|
||||
|
||||
const handleGetCode = () => {
|
||||
if (!email.value) {
|
||||
toast('请输入邮箱')
|
||||
return
|
||||
}
|
||||
// 模拟倒计时逻辑
|
||||
countdown.value = 60
|
||||
const timer = setInterval(() => {
|
||||
countdown.value--
|
||||
if (countdown.value <= 0) clearInterval(timer)
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
const handleLogin = () => {
|
||||
console.log('登录提交', { email: email.value, code: code.value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid gap-4 py-4">
|
||||
<div class="grid gap-2">
|
||||
<label for="email" class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Email</label>
|
||||
<input
|
||||
id="email"
|
||||
type="email"
|
||||
placeholder="m@example.com"
|
||||
class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
<div class="flex flex-col gap-6 text-black">
|
||||
<div class="overflow-hidden rounded-[20px] bg-[#78788029] px-4">
|
||||
<div class="relative">
|
||||
<Input
|
||||
v-model="email"
|
||||
type="email"
|
||||
placeholder="Email"
|
||||
class="h-[50px] border-none bg-transparent text-base focus-visible:ring-0"
|
||||
/>
|
||||
<div class="absolute bottom-0 left-0 h-[1px] w-full bg-gray-400/30"></div>
|
||||
</div>
|
||||
|
||||
<div class="relative flex items-center">
|
||||
<div class="flex-1">
|
||||
<Input
|
||||
v-model="code"
|
||||
type="text"
|
||||
placeholder="验证码"
|
||||
class="h-[50px] border-none bg-transparent text-base focus-visible:ring-0"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
@click="handleGetCode"
|
||||
:disabled="countdown > 0"
|
||||
class="h-10 rounded-full bg-[#4B94E6] px-[32px] font-bold text-white hover:bg-[#4B94E6]/90"
|
||||
>
|
||||
{{ countdown > 0 ? `${countdown}s` : '获取' }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid gap-2">
|
||||
<label for="password" class="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">Password</label>
|
||||
<input
|
||||
id="password"
|
||||
type="password"
|
||||
class="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
/>
|
||||
|
||||
<div class="flex gap-4 pt-2">
|
||||
<Button
|
||||
variant="secondary"
|
||||
class="h-[48px] flex-1 cursor-pointer rounded-[25px] bg-[#D1D1D1] text-lg font-medium text-[#757575] hover:bg-[#C1C1C1]"
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
<Button
|
||||
@click="handleLogin"
|
||||
class="h-[48px] flex-1 cursor-pointer rounded-[25px] bg-[#A8FF53] text-lg font-medium text-black hover:bg-[#96E64A]"
|
||||
>
|
||||
登陆/注册
|
||||
</Button>
|
||||
</div>
|
||||
<Button type="submit" class="w-full">Sign In</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Button } from '@/components/ui/button'
|
||||
</script>
|
||||
<style scoped>
|
||||
/* 移除 Shadcn Input 的默认边框阴影,保持纯净感 */
|
||||
input:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,10 +1,15 @@
|
||||
<template>
|
||||
<Dialog :open="isOpen" @update:open="setOpen">
|
||||
<DialogContent class="sm:max-w-[425px]">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Login</DialogTitle>
|
||||
<DialogDescription>
|
||||
Enter your credentials to access your account.
|
||||
<DialogContent
|
||||
@pointer-down-outside="(event) => event.preventDefault()"
|
||||
@focus-outside="(event) => event.preventDefault()"
|
||||
class="max-w-[300px] rounded-4xl bg-[#DDDDDD] p-[14px]"
|
||||
:showCloseButton="false"
|
||||
>
|
||||
<DialogHeader class="py-2 pl-2">
|
||||
<DialogTitle class="text-left">登陆Hi快帐户</DialogTitle>
|
||||
<DialogDescription class="text-left text-base text-black">
|
||||
如使用新邮箱地址,将自动为您创建Hi快帐户
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<LoginForm />
|
||||
@ -23,7 +28,7 @@ import {
|
||||
} from '@/components/ui/dialog'
|
||||
import LoginForm from './LoginForm.vue'
|
||||
|
||||
const isOpen = ref(false)
|
||||
const isOpen = ref(true)
|
||||
|
||||
const setOpen = (value: boolean) => {
|
||||
isOpen.value = value
|
||||
@ -39,6 +44,6 @@ const hide = () => {
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
hide
|
||||
hide,
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -29,9 +29,9 @@
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Desktop Logo -->
|
||||
<img :src="Logo" alt="Hi快VPN" class="hidden h-10 w-auto md:block" />
|
||||
<Logo alt="Hi快VPN" class="hidden h-10 w-auto md:block" />
|
||||
<!-- Mobile Logo -->
|
||||
<img :src="MobileLogo" alt="Hi快VPN" class="block h-[28px] w-[67px] w-auto md:hidden" />
|
||||
<MobileLogo alt="Hi快VPN" class="block h-[28px] w-[67px] md:hidden" />
|
||||
</div>
|
||||
<button
|
||||
@click="openLoginModal"
|
||||
@ -107,8 +107,8 @@
|
||||
import { ref } from 'vue'
|
||||
import LoginFormModal from './components/LoginFormModal.vue'
|
||||
import DownloadButton from './components/DownloadButton.vue'
|
||||
import Logo from './logo.svg'
|
||||
import MobileLogo from './mobile-logo.svg'
|
||||
import Logo from './logo.svg?component'
|
||||
import MobileLogo from './mobile-logo.svg?component'
|
||||
import ScreenshotMobile from './screenshot-mobile.png'
|
||||
import { AppleIcon, MonitorIcon, SmartphoneIcon, LocateFixedIcon } from 'lucide-vue-next'
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<svg width="103" height="29" viewBox="0 0 103 29" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.4016 11.4828H17.0339L19.3193 0H26.26L20.5763 28.7559H13.6144L15.8796 17.2933H9.24829L6.96193 28.7559H0L4.88123 4.20849L2.71884 0H12.6668L10.4016 11.4828Z" fill="white"/>
|
||||
<path d="M29.5968 28.7559H22.6561L26.7156 8.2363H33.6708L29.5968 28.7559Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.8974 5.31659L47.9128 6.28534L48.4606 3.90191H52.8411L53.7012 0H60.0375L59.3081 3.90191H67.3656L65.775 13.4087H67.7568L66.9216 18.8301H58.1346L65.775 24.4081L61.4983 28.7559L53.3629 22.3658L44.1319 28.7559L41.9109 26.556L41.4977 28.7559H35.4228L37.8303 16.29L33.6237 15.7134L36.7327 5.46556H39.9206L40.9768 0H46.896L45.8974 5.31659ZM42.6336 22.706L48.9036 18.8301H43.3612L42.6336 22.706ZM46.896 12.7283L44.7086 11.6538L44.3789 13.4087H51.042L52.0069 9.11375H49.4774L46.896 12.7283ZM57.4561 13.4087H59.5945L60.3768 9.11375H58.3172L57.4561 13.4087Z" fill="white"/>
|
||||
<path d="M75.7576 22.3514L78.5379 15.6634H81.5884L76.1459 28.7559H73.0955L72.3103 15.6634H75.3607L75.7576 22.3514Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M85.5412 15.6634C86.4527 15.6725 87.5357 15.7459 88.5464 16.0651C89.0518 16.2202 89.5124 16.4575 89.9275 16.7676C90.7578 17.3971 91.2998 18.3916 91.2999 19.9334C91.2999 21.1832 90.8303 22.4242 89.7564 23.3913C88.6734 24.3584 86.9764 24.9789 84.5215 24.9789H83.7632L83.0501 28.7559H79.9997L82.4994 15.6634H85.5412ZM84.2688 22.3331H85.027C86.7057 22.3331 88.4474 21.6942 88.4474 20.0247C88.4473 18.3279 86.6334 18.3092 85.3067 18.3092H85.0357L84.2688 22.3331Z" fill="white"/>
|
||||
<path d="M98.0504 22.3149L99.3228 15.6634H102.373L99.8735 28.7559H96.8231L94.9462 22.114L93.6824 28.7559H90.6319L93.1317 15.6634H96.1821L98.0504 22.3149Z" fill="white"/>
|
||||
<path d="M34.011 6.52561H27.0539L28.3407 0.0201823H35.3027L34.011 6.52561Z" fill="white"/>
|
||||
<path d="M10.4016 11.4828H17.0339L19.3193 0H26.26L20.5763 28.7559H13.6144L15.8796 17.2933H9.24829L6.96193 28.7559H0L4.88123 4.20849L2.71884 0H12.6668L10.4016 11.4828Z" fill="currentColor"/>
|
||||
<path d="M29.5968 28.7559H22.6561L26.7156 8.2363H33.6708L29.5968 28.7559Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M45.8974 5.31659L47.9128 6.28534L48.4606 3.90191H52.8411L53.7012 0H60.0375L59.3081 3.90191H67.3656L65.775 13.4087H67.7568L66.9216 18.8301H58.1346L65.775 24.4081L61.4983 28.7559L53.3629 22.3658L44.1319 28.7559L41.9109 26.556L41.4977 28.7559H35.4228L37.8303 16.29L33.6237 15.7134L36.7327 5.46556H39.9206L40.9768 0H46.896L45.8974 5.31659ZM42.6336 22.706L48.9036 18.8301H43.3612L42.6336 22.706ZM46.896 12.7283L44.7086 11.6538L44.3789 13.4087H51.042L52.0069 9.11375H49.4774L46.896 12.7283ZM57.4561 13.4087H59.5945L60.3768 9.11375H58.3172L57.4561 13.4087Z" fill="currentColor"/>
|
||||
<path d="M75.7576 22.3514L78.5379 15.6634H81.5884L76.1459 28.7559H73.0955L72.3103 15.6634H75.3607L75.7576 22.3514Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M85.5412 15.6634C86.4527 15.6725 87.5357 15.7459 88.5464 16.0651C89.0518 16.2202 89.5124 16.4575 89.9275 16.7676C90.7578 17.3971 91.2998 18.3916 91.2999 19.9334C91.2999 21.1832 90.8303 22.4242 89.7564 23.3913C88.6734 24.3584 86.9764 24.9789 84.5215 24.9789H83.7632L83.0501 28.7559H79.9997L82.4994 15.6634H85.5412ZM84.2688 22.3331H85.027C86.7057 22.3331 88.4474 21.6942 88.4474 20.0247C88.4473 18.3279 86.6334 18.3092 85.3067 18.3092H85.0357L84.2688 22.3331Z" fill="currentColor"/>
|
||||
<path d="M98.0504 22.3149L99.3228 15.6634H102.373L99.8735 28.7559H96.8231L94.9462 22.114L93.6824 28.7559H90.6319L93.1317 15.6634H96.1821L98.0504 22.3149Z" fill="currentColor"/>
|
||||
<path d="M34.011 6.52561H27.0539L28.3407 0.0201823H35.3027L34.011 6.52561Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
@ -1,18 +1,18 @@
|
||||
<svg width="67" height="28" viewBox="0 0 67 28" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.64761 6.43747H10.3658L11.647 0H15.5382L12.3518 16.1211H8.44879L9.71872 9.69499H6.00106L4.71928 16.1211H0.816284L3.5528 2.35936L2.34052 0H7.91754L6.64761 6.43747Z" fill="white"/>
|
||||
<path d="M17.4089 16.1211H13.5177L15.7936 4.61743H19.6928L17.4089 16.1211Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.5473 2.98059L27.6771 3.52369L27.9842 2.18749H30.4401L30.9223 0H34.4745L34.0656 2.18749H38.5828L37.6911 7.5172H38.8021L38.3339 10.5565H33.4077L37.6911 13.6837L35.2935 16.1211L30.7326 12.5387L25.5575 16.1211L24.3124 14.8879L24.0807 16.1211H20.675L22.0247 9.13249L19.6664 8.80922L21.4094 3.0641H23.1966L23.7887 0H27.1071L26.5473 2.98059ZM24.7176 12.7295L28.2326 10.5565H25.1254L24.7176 12.7295ZM27.1071 7.13574L25.8808 6.53337L25.696 7.5172H29.4314L29.9724 5.10935H28.5543L27.1071 7.13574ZM33.0273 7.5172H34.2261L34.6647 5.10935H33.5101L33.0273 7.5172Z" fill="white"/>
|
||||
<path d="M43.2875 12.5306L44.8462 8.7812H46.5563L43.5052 16.1211H41.7951L41.3549 8.7812H43.065L43.2875 12.5306Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.7724 8.7812C49.2834 8.78632 49.8905 8.82745 50.4572 9.00642C50.7405 9.09336 50.9987 9.2264 51.2314 9.40027C51.6969 9.75318 52.0008 10.3107 52.0008 11.175C52.0008 11.8757 51.7376 12.5715 51.1355 13.1136C50.5284 13.6558 49.577 14.0037 48.2007 14.0037H47.7756L47.3758 16.1211H45.6657L47.0671 8.7812H48.7724ZM48.059 12.5204H48.4841C49.4252 12.5204 50.4017 12.1622 50.4017 11.2262C50.4016 10.275 49.3847 10.2645 48.6409 10.2645H48.489L48.059 12.5204Z" fill="white"/>
|
||||
<path d="M55.7853 12.5102L56.4986 8.7812H58.2088L56.8074 16.1211H55.0972L54.045 12.3976L53.3365 16.1211H51.6264L53.0278 8.7812H54.7379L55.7853 12.5102Z" fill="white"/>
|
||||
<path d="M19.8835 3.65839H15.9832L16.7047 0.0113146H20.6077L19.8835 3.65839Z" fill="white"/>
|
||||
<path d="M2.77626 25.5216C2.5952 25.2235 2.41414 24.9333 2.23308 24.651C1.98412 25.3412 1.6899 25.9373 1.35041 26.4392L0.852494 25.7961C1.19953 25.2471 1.48621 24.6039 1.71253 23.8824C1.41076 23.4588 1.09391 23.0431 0.777052 22.6431V27.349H0V20.3373H6.20133V26.4706C6.20133 27.0196 5.93728 27.2941 5.41673 27.2941H4.66231L4.46616 26.502L5.16023 26.5412C5.33375 26.5412 5.42428 26.4549 5.42428 26.2824V25.3961L4.9339 25.9059C4.73775 25.5451 4.54161 25.1922 4.33037 24.8471C4.05878 25.5373 3.74192 26.1255 3.3798 26.6275L2.88188 25.9843C3.25909 25.4196 3.57595 24.7765 3.83245 24.0392C3.53068 23.5765 3.21383 23.1294 2.88943 22.6902L3.37226 22.2039C3.59104 22.4706 3.83245 22.7843 4.08895 23.1608C4.21721 22.651 4.32282 22.1098 4.40581 21.5373L5.14514 21.6706C5.01689 22.5176 4.84337 23.2941 4.63214 23.9843C4.88864 24.3843 5.15269 24.8235 5.42428 25.2941V21.1216H0.777052V22.5569L1.22216 22.1098C1.44849 22.3608 1.6899 22.6588 1.9464 23.0039C2.05202 22.5333 2.14255 22.0314 2.21045 21.5137L2.93469 21.6471C2.82153 22.4314 2.67819 23.1373 2.50467 23.7804C2.76118 24.1412 3.02522 24.5412 3.29681 24.9804L2.77626 25.5216Z" fill="white"/>
|
||||
<path d="M9.55095 23.6471H11.173V22.298H11.9726V23.6471H13.7003V24.4471H11.9726V26.2824H14.0247V27.0824H9.27936V26.2824H11.173V24.4471H9.55095V23.6471ZM8.23072 24.4314C8.02702 24.6353 7.81579 24.8314 7.597 25.0275L7.09154 24.3451C7.93649 23.6157 8.61547 22.7843 9.12093 21.8588H7.36313V21.0588H9.49814C9.64148 20.7137 9.76219 20.3608 9.86781 20L10.6826 20.102C10.5921 20.4314 10.4864 20.7451 10.3733 21.0588H14.0247V21.8588H10.0262C9.73956 22.4549 9.40007 23.0118 9.00777 23.5294V27.3647H8.23072V24.4314Z" fill="white"/>
|
||||
<path d="M18.272 23.6471V24.4784C17.8722 24.6196 17.4573 24.7451 17.0197 24.8627V26.4549C17.0197 26.9725 16.7557 27.2392 16.2276 27.2392H15.3751L15.2016 26.4627C15.4656 26.4941 15.7146 26.5098 15.956 26.5098C16.1295 26.5098 16.22 26.4157 16.22 26.2431V25.0588C15.7825 25.1529 15.3373 25.2392 14.8696 25.3176L14.7564 24.4941C15.2695 24.4157 15.7598 24.3216 16.22 24.2196V22.8706H14.7489V22.0863H16.22V21.3569C15.8579 21.4353 15.4882 21.498 15.0959 21.5529L14.93 20.7765C15.9711 20.6588 16.9065 20.4314 17.7213 20.0863L17.9929 20.8549C17.6836 20.9725 17.3592 21.0745 17.0197 21.1686V22.0863H18.5663C18.521 21.4824 18.5059 20.8157 18.5059 20.0941H19.2981C19.3056 20.8471 19.3282 21.5059 19.3735 22.0863H21.6292V22.8706H19.4338C19.4791 23.3804 19.547 23.7961 19.63 24.1255C19.6602 24.251 19.6904 24.3608 19.7205 24.4706C20.0298 24.0706 20.3014 23.6235 20.5278 23.1373L21.2067 23.5137C20.8748 24.2196 20.4749 24.8392 20.0148 25.3569C20.0902 25.5451 20.1732 25.7098 20.2562 25.8353C20.4674 26.1804 20.6334 26.3529 20.739 26.3529C20.822 26.3529 20.905 25.9529 20.9955 25.1686L21.6971 25.5529C21.501 26.6745 21.2218 27.2392 20.8522 27.2392C20.5202 27.2392 20.1732 27.0039 19.8186 26.5412C19.6828 26.3608 19.5546 26.1569 19.4414 25.9216C18.9284 26.3608 18.355 26.7059 17.7289 26.9569L17.2913 26.2588C17.9854 25.9922 18.5964 25.6157 19.117 25.1294C19.034 24.8784 18.9586 24.6196 18.8907 24.3529C18.7775 23.9294 18.6945 23.4353 18.6342 22.8706H17.0197V24.0314C17.4573 23.9137 17.8797 23.7882 18.272 23.6471ZM20.1279 20.1647C20.656 20.5098 21.1087 20.8549 21.4859 21.2L20.9201 21.7882C20.6107 21.4431 20.1732 21.0824 19.5998 20.6902L20.1279 20.1647Z" fill="white"/>
|
||||
<path d="M24.6393 23.6471H26.2613V22.298H27.061V23.6471H28.7887V24.4471H27.061V26.2824H29.1131V27.0824H24.3678V26.2824H26.2613V24.4471H24.6393V23.6471ZM23.3191 24.4314C23.1154 24.6353 22.9042 24.8314 22.6854 25.0275L22.1799 24.3451C23.0249 23.6157 23.7039 22.7843 24.2093 21.8588H22.4515V21.0588H24.5865C24.7299 20.7137 24.8506 20.3608 24.9562 20L25.771 20.102C25.6804 20.4314 25.5748 20.7451 25.4617 21.0588H29.1131V21.8588H25.1146C24.8279 22.4549 24.4885 23.0118 24.0962 23.5294V27.3647H23.3191V24.4314Z" fill="white"/>
|
||||
<path d="M30.9689 25.3412C31.1726 25.3412 31.3461 25.4275 31.4819 25.6C31.6102 25.7725 31.6781 26 31.6781 26.2745C31.6781 26.6902 31.5574 27.051 31.331 27.3647C31.0972 27.6706 30.7803 27.8824 30.388 28V27.4824C30.5917 27.4039 30.7652 27.2784 30.9086 27.1059C31.0368 26.9176 31.1047 26.7373 31.1047 26.549C31.0595 26.5647 30.9991 26.5804 30.9161 26.5804C30.7501 26.5804 30.6143 26.5176 30.5012 26.4C30.388 26.2824 30.3352 26.1333 30.3352 25.9608C30.3352 25.7725 30.3956 25.6235 30.5163 25.5137C30.6294 25.3961 30.7803 25.3412 30.9689 25.3412Z" fill="white"/>
|
||||
<path d="M40.4972 25.5216C40.3162 25.2235 40.1351 24.9333 39.9541 24.651C39.7051 25.3412 39.4109 25.9373 39.0714 26.4392L38.5735 25.7961C38.9205 25.2471 39.2072 24.6039 39.4335 23.8824C39.1317 23.4588 38.8149 23.0431 38.498 22.6431V27.349H37.721V20.3373H43.9223V26.4706C43.9223 27.0196 43.6583 27.2941 43.1377 27.2941H42.3833L42.1871 26.502L42.8812 26.5412C43.0547 26.5412 43.1453 26.4549 43.1453 26.2824V25.3961L42.6549 25.9059C42.4587 25.5451 42.2626 25.1922 42.0513 24.8471C41.7798 25.5373 41.4629 26.1255 41.1008 26.6275L40.6029 25.9843C40.9801 25.4196 41.2969 24.7765 41.5534 24.0392C41.2517 23.5765 40.9348 23.1294 40.6104 22.6902L41.0932 22.2039C41.312 22.4706 41.5534 22.7843 41.8099 23.1608C41.9382 22.651 42.0438 22.1098 42.1268 21.5373L42.8661 21.6706C42.7379 22.5176 42.5644 23.2941 42.3531 23.9843C42.6096 24.3843 42.8737 24.8235 43.1453 25.2941V21.1216H38.498V22.5569L38.9431 22.1098C39.1695 22.3608 39.4109 22.6588 39.6674 23.0039C39.773 22.5333 39.8635 22.0314 39.9314 21.5137L40.6557 21.6471C40.5425 22.4314 40.3992 23.1373 40.2257 23.7804C40.4822 24.1412 40.7462 24.5412 41.0178 24.9804L40.4972 25.5216Z" fill="white"/>
|
||||
<path d="M47.5963 21.2H48.8487V20.0941H49.6182V21.2H51.2175V23.5451H51.7079V24.3451H49.8596C50.3047 25.2863 50.9912 26.0627 51.9116 26.6588L51.376 27.3098C50.4556 26.6118 49.7615 25.7569 49.2938 24.7373C48.9317 25.8824 48.2829 26.7373 47.3323 27.302L46.8495 26.6275C47.7397 26.149 48.3281 25.3882 48.6223 24.3451H47.2946V23.5451H48.7808C48.826 23.2314 48.8487 22.902 48.8487 22.5569V21.9608H47.5963V21.2ZM49.6182 21.9608V22.3765C49.6182 22.7843 49.588 23.1765 49.5427 23.5451H50.4631V21.9608H49.6182ZM45.069 21.6314L45.6726 21.6784C45.6575 22.4627 45.5745 23.2078 45.4387 23.9137L44.805 23.7255C44.9559 23.0667 45.0464 22.3686 45.069 21.6314ZM47.1663 21.4275C47.3625 21.9294 47.5435 22.5098 47.6944 23.1608L47.0682 23.3255C46.9551 22.7765 46.8117 22.2431 46.6307 21.7333V27.3176H45.8536V20.102H46.6307V21.6078L47.1663 21.4275Z" fill="white"/>
|
||||
<path d="M55.993 23.6471V24.4784C55.5932 24.6196 55.1782 24.7451 54.7407 24.8627V26.4549C54.7407 26.9725 54.4766 27.2392 53.9485 27.2392H53.0961L52.9225 26.4627C53.1866 26.4941 53.4355 26.5098 53.6769 26.5098C53.8505 26.5098 53.941 26.4157 53.941 26.2431V25.0588C53.5034 25.1529 53.0583 25.2392 52.5906 25.3176L52.4774 24.4941C52.9904 24.4157 53.4808 24.3216 53.941 24.2196V22.8706H52.4699V22.0863H53.941V21.3569C53.5789 21.4353 53.2092 21.498 52.8169 21.5529L52.6509 20.7765C53.692 20.6588 54.6275 20.4314 55.4423 20.0863L55.7139 20.8549C55.4046 20.9725 55.0802 21.0745 54.7407 21.1686V22.0863H56.2872C56.242 21.4824 56.2269 20.8157 56.2269 20.0941H57.019C57.0266 20.8471 57.0492 21.5059 57.0945 22.0863H59.3502V22.8706H57.1548C57.2001 23.3804 57.268 23.7961 57.351 24.1255C57.3812 24.251 57.4113 24.3608 57.4415 24.4706C57.7508 24.0706 58.0224 23.6235 58.2487 23.1373L58.9277 23.5137C58.5958 24.2196 58.1959 24.8392 57.7357 25.3569C57.8112 25.5451 57.8942 25.7098 57.9771 25.8353C58.1884 26.1804 58.3544 26.3529 58.46 26.3529C58.543 26.3529 58.6259 25.9529 58.7165 25.1686L59.4181 25.5529C59.2219 26.6745 58.9428 27.2392 58.5731 27.2392C58.2412 27.2392 57.8942 27.0039 57.5396 26.5412C57.4038 26.3608 57.2755 26.1569 57.1624 25.9216C56.6494 26.3608 56.076 26.7059 55.4498 26.9569L55.0123 26.2588C55.7063 25.9922 56.3174 25.6157 56.838 25.1294C56.755 24.8784 56.6795 24.6196 56.6116 24.3529C56.4985 23.9294 56.4155 23.4353 56.3551 22.8706H54.7407V24.0314C55.1782 23.9137 55.6007 23.7882 55.993 23.6471ZM57.8489 20.1647C58.377 20.5098 58.8296 20.8549 59.2068 21.2L58.641 21.7882C58.3317 21.4431 57.8942 21.0824 57.3208 20.6902L57.8489 20.1647Z" fill="white"/>
|
||||
<path d="M62.6847 21.2H63.9371V20.0941H64.7066V21.2H66.3059V23.5451H66.7963V24.3451H64.948C65.3931 25.2863 66.0796 26.0627 67 26.6588L66.4644 27.3098C65.544 26.6118 64.8499 25.7569 64.3822 24.7373C64.02 25.8824 63.3712 26.7373 62.4207 27.302L61.9378 26.6275C62.8281 26.149 63.4165 25.3882 63.7107 24.3451H62.383V23.5451H63.8692C63.9144 23.2314 63.9371 22.902 63.9371 22.5569V21.9608H62.6847V21.2ZM64.7066 21.9608V22.3765C64.7066 22.7843 64.6764 23.1765 64.6311 23.5451H65.5515V21.9608H64.7066ZM60.1574 21.6314L60.761 21.6784C60.7459 22.4627 60.6629 23.2078 60.5271 23.9137L59.8934 23.7255C60.0443 23.0667 60.1348 22.3686 60.1574 21.6314ZM62.2547 21.4275C62.4509 21.9294 62.6319 22.5098 62.7828 23.1608L62.1566 23.3255C62.0435 22.7765 61.9001 22.2431 61.7191 21.7333V27.3176H60.942V20.102H61.7191V21.6078L62.2547 21.4275Z" fill="white"/>
|
||||
<path d="M6.64761 6.43747H10.3658L11.647 0H15.5382L12.3518 16.1211H8.44879L9.71872 9.69499H6.00106L4.71928 16.1211H0.816284L3.5528 2.35936L2.34052 0H7.91754L6.64761 6.43747Z" fill="currentColor"/>
|
||||
<path d="M17.4089 16.1211H13.5177L15.7936 4.61743H19.6928L17.4089 16.1211Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M26.5473 2.98059L27.6771 3.52369L27.9842 2.18749H30.4401L30.9223 0H34.4745L34.0656 2.18749H38.5828L37.6911 7.5172H38.8021L38.3339 10.5565H33.4077L37.6911 13.6837L35.2935 16.1211L30.7326 12.5387L25.5575 16.1211L24.3124 14.8879L24.0807 16.1211H20.675L22.0247 9.13249L19.6664 8.80922L21.4094 3.0641H23.1966L23.7887 0H27.1071L26.5473 2.98059ZM24.7176 12.7295L28.2326 10.5565H25.1254L24.7176 12.7295ZM27.1071 7.13574L25.8808 6.53337L25.696 7.5172H29.4314L29.9724 5.10935H28.5543L27.1071 7.13574ZM33.0273 7.5172H34.2261L34.6647 5.10935H33.5101L33.0273 7.5172Z" fill="currentColor"/>
|
||||
<path d="M43.2875 12.5306L44.8462 8.7812H46.5563L43.5052 16.1211H41.7951L41.3549 8.7812H43.065L43.2875 12.5306Z" fill="currentColor"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.7724 8.7812C49.2834 8.78632 49.8905 8.82745 50.4572 9.00642C50.7405 9.09336 50.9987 9.2264 51.2314 9.40027C51.6969 9.75318 52.0008 10.3107 52.0008 11.175C52.0008 11.8757 51.7376 12.5715 51.1355 13.1136C50.5284 13.6558 49.577 14.0037 48.2007 14.0037H47.7756L47.3758 16.1211H45.6657L47.0671 8.7812H48.7724ZM48.059 12.5204H48.4841C49.4252 12.5204 50.4017 12.1622 50.4017 11.2262C50.4016 10.275 49.3847 10.2645 48.6409 10.2645H48.489L48.059 12.5204Z" fill="currentColor"/>
|
||||
<path d="M55.7853 12.5102L56.4986 8.7812H58.2088L56.8074 16.1211H55.0972L54.045 12.3976L53.3365 16.1211H51.6264L53.0278 8.7812H54.7379L55.7853 12.5102Z" fill="currentColor"/>
|
||||
<path d="M19.8835 3.65839H15.9832L16.7047 0.0113146H20.6077L19.8835 3.65839Z" fill="currentColor"/>
|
||||
<path d="M2.77626 25.5216C2.5952 25.2235 2.41414 24.9333 2.23308 24.651C1.98412 25.3412 1.6899 25.9373 1.35041 26.4392L0.852494 25.7961C1.19953 25.2471 1.48621 24.6039 1.71253 23.8824C1.41076 23.4588 1.09391 23.0431 0.777052 22.6431V27.349H0V20.3373H6.20133V26.4706C6.20133 27.0196 5.93728 27.2941 5.41673 27.2941H4.66231L4.46616 26.502L5.16023 26.5412C5.33375 26.5412 5.42428 26.4549 5.42428 26.2824V25.3961L4.9339 25.9059C4.73775 25.5451 4.54161 25.1922 4.33037 24.8471C4.05878 25.5373 3.74192 26.1255 3.3798 26.6275L2.88188 25.9843C3.25909 25.4196 3.57595 24.7765 3.83245 24.0392C3.53068 23.5765 3.21383 23.1294 2.88943 22.6902L3.37226 22.2039C3.59104 22.4706 3.83245 22.7843 4.08895 23.1608C4.21721 22.651 4.32282 22.1098 4.40581 21.5373L5.14514 21.6706C5.01689 22.5176 4.84337 23.2941 4.63214 23.9843C4.88864 24.3843 5.15269 24.8235 5.42428 25.2941V21.1216H0.777052V22.5569L1.22216 22.1098C1.44849 22.3608 1.6899 22.6588 1.9464 23.0039C2.05202 22.5333 2.14255 22.0314 2.21045 21.5137L2.93469 21.6471C2.82153 22.4314 2.67819 23.1373 2.50467 23.7804C2.76118 24.1412 3.02522 24.5412 3.29681 24.9804L2.77626 25.5216Z" fill="currentColor"/>
|
||||
<path d="M9.55095 23.6471H11.173V22.298H11.9726V23.6471H13.7003V24.4471H11.9726V26.2824H14.0247V27.0824H9.27936V26.2824H11.173V24.4471H9.55095V23.6471ZM8.23072 24.4314C8.02702 24.6353 7.81579 24.8314 7.597 25.0275L7.09154 24.3451C7.93649 23.6157 8.61547 22.7843 9.12093 21.8588H7.36313V21.0588H9.49814C9.64148 20.7137 9.76219 20.3608 9.86781 20L10.6826 20.102C10.5921 20.4314 10.4864 20.7451 10.3733 21.0588H14.0247V21.8588H10.0262C9.73956 22.4549 9.40007 23.0118 9.00777 23.5294V27.3647H8.23072V24.4314Z" fill="currentColor"/>
|
||||
<path d="M18.272 23.6471V24.4784C17.8722 24.6196 17.4573 24.7451 17.0197 24.8627V26.4549C17.0197 26.9725 16.7557 27.2392 16.2276 27.2392H15.3751L15.2016 26.4627C15.4656 26.4941 15.7146 26.5098 15.956 26.5098C16.1295 26.5098 16.22 26.4157 16.22 26.2431V25.0588C15.7825 25.1529 15.3373 25.2392 14.8696 25.3176L14.7564 24.4941C15.2695 24.4157 15.7598 24.3216 16.22 24.2196V22.8706H14.7489V22.0863H16.22V21.3569C15.8579 21.4353 15.4882 21.498 15.0959 21.5529L14.93 20.7765C15.9711 20.6588 16.9065 20.4314 17.7213 20.0863L17.9929 20.8549C17.6836 20.9725 17.3592 21.0745 17.0197 21.1686V22.0863H18.5663C18.521 21.4824 18.5059 20.8157 18.5059 20.0941H19.2981C19.3056 20.8471 19.3282 21.5059 19.3735 22.0863H21.6292V22.8706H19.4338C19.4791 23.3804 19.547 23.7961 19.63 24.1255C19.6602 24.251 19.6904 24.3608 19.7205 24.4706C20.0298 24.0706 20.3014 23.6235 20.5278 23.1373L21.2067 23.5137C20.8748 24.2196 20.4749 24.8392 20.0148 25.3569C20.0902 25.5451 20.1732 25.7098 20.2562 25.8353C20.4674 26.1804 20.6334 26.3529 20.739 26.3529C20.822 26.3529 20.905 25.9529 20.9955 25.1686L21.6971 25.5529C21.501 26.6745 21.2218 27.2392 20.8522 27.2392C20.5202 27.2392 20.1732 27.0039 19.8186 26.5412C19.6828 26.3608 19.5546 26.1569 19.4414 25.9216C18.9284 26.3608 18.355 26.7059 17.7289 26.9569L17.2913 26.2588C17.9854 25.9922 18.5964 25.6157 19.117 25.1294C19.034 24.8784 18.9586 24.6196 18.8907 24.3529C18.7775 23.9294 18.6945 23.4353 18.6342 22.8706H17.0197V24.0314C17.4573 23.9137 17.8797 23.7882 18.272 23.6471ZM20.1279 20.1647C20.656 20.5098 21.1087 20.8549 21.4859 21.2L20.9201 21.7882C20.6107 21.4431 20.1732 21.0824 19.5998 20.6902L20.1279 20.1647Z" fill="currentColor"/>
|
||||
<path d="M24.6393 23.6471H26.2613V22.298H27.061V23.6471H28.7887V24.4471H27.061V26.2824H29.1131V27.0824H24.3678V26.2824H26.2613V24.4471H24.6393V23.6471ZM23.3191 24.4314C23.1154 24.6353 22.9042 24.8314 22.6854 25.0275L22.1799 24.3451C23.0249 23.6157 23.7039 22.7843 24.2093 21.8588H22.4515V21.0588H24.5865C24.7299 20.7137 24.8506 20.3608 24.9562 20L25.771 20.102C25.6804 20.4314 25.5748 20.7451 25.4617 21.0588H29.1131V21.8588H25.1146C24.8279 22.4549 24.4885 23.0118 24.0962 23.5294V27.3647H23.3191V24.4314Z" fill="currentColor"/>
|
||||
<path d="M30.9689 25.3412C31.1726 25.3412 31.3461 25.4275 31.4819 25.6C31.6102 25.7725 31.6781 26 31.6781 26.2745C31.6781 26.6902 31.5574 27.051 31.331 27.3647C31.0972 27.6706 30.7803 27.8824 30.388 28V27.4824C30.5917 27.4039 30.7652 27.2784 30.9086 27.1059C31.0368 26.9176 31.1047 26.7373 31.1047 26.549C31.0595 26.5647 30.9991 26.5804 30.9161 26.5804C30.7501 26.5804 30.6143 26.5176 30.5012 26.4C30.388 26.2824 30.3352 26.1333 30.3352 25.9608C30.3352 25.7725 30.3956 25.6235 30.5163 25.5137C30.6294 25.3961 30.7803 25.3412 30.9689 25.3412Z" fill="currentColor"/>
|
||||
<path d="M40.4972 25.5216C40.3162 25.2235 40.1351 24.9333 39.9541 24.651C39.7051 25.3412 39.4109 25.9373 39.0714 26.4392L38.5735 25.7961C38.9205 25.2471 39.2072 24.6039 39.4335 23.8824C39.1317 23.4588 38.8149 23.0431 38.498 22.6431V27.349H37.721V20.3373H43.9223V26.4706C43.9223 27.0196 43.6583 27.2941 43.1377 27.2941H42.3833L42.1871 26.502L42.8812 26.5412C43.0547 26.5412 43.1453 26.4549 43.1453 26.2824V25.3961L42.6549 25.9059C42.4587 25.5451 42.2626 25.1922 42.0513 24.8471C41.7798 25.5373 41.4629 26.1255 41.1008 26.6275L40.6029 25.9843C40.9801 25.4196 41.2969 24.7765 41.5534 24.0392C41.2517 23.5765 40.9348 23.1294 40.6104 22.6902L41.0932 22.2039C41.312 22.4706 41.5534 22.7843 41.8099 23.1608C41.9382 22.651 42.0438 22.1098 42.1268 21.5373L42.8661 21.6706C42.7379 22.5176 42.5644 23.2941 42.3531 23.9843C42.6096 24.3843 42.8737 24.8235 43.1453 25.2941V21.1216H38.498V22.5569L38.9431 22.1098C39.1695 22.3608 39.4109 22.6588 39.6674 23.0039C39.773 22.5333 39.8635 22.0314 39.9314 21.5137L40.6557 21.6471C40.5425 22.4314 40.3992 23.1373 40.2257 23.7804C40.4822 24.1412 40.7462 24.5412 41.0178 24.9804L40.4972 25.5216Z" fill="currentColor"/>
|
||||
<path d="M47.5963 21.2H48.8487V20.0941H49.6182V21.2H51.2175V23.5451H51.7079V24.3451H49.8596C50.3047 25.2863 50.9912 26.0627 51.9116 26.6588L51.376 27.3098C50.4556 26.6118 49.7615 25.7569 49.2938 24.7373C48.9317 25.8824 48.2829 26.7373 47.3323 27.302L46.8495 26.6275C47.7397 26.149 48.3281 25.3882 48.6223 24.3451H47.2946V23.5451H48.7808C48.826 23.2314 48.8487 22.902 48.8487 22.5569V21.9608H47.5963V21.2ZM49.6182 21.9608V22.3765C49.6182 22.7843 49.588 23.1765 49.5427 23.5451H50.4631V21.9608H49.6182ZM45.069 21.6314L45.6726 21.6784C45.6575 22.4627 45.5745 23.2078 45.4387 23.9137L44.805 23.7255C44.9559 23.0667 45.0464 22.3686 45.069 21.6314ZM47.1663 21.4275C47.3625 21.9294 47.5435 22.5098 47.6944 23.1608L47.0682 23.3255C46.9551 22.7765 46.8117 22.2431 46.6307 21.7333V27.3176H45.8536V20.102H46.6307V21.6078L47.1663 21.4275Z" fill="currentColor"/>
|
||||
<path d="M55.993 23.6471V24.4784C55.5932 24.6196 55.1782 24.7451 54.7407 24.8627V26.4549C54.7407 26.9725 54.4766 27.2392 53.9485 27.2392H53.0961L52.9225 26.4627C53.1866 26.4941 53.4355 26.5098 53.6769 26.5098C53.8505 26.5098 53.941 26.4157 53.941 26.2431V25.0588C53.5034 25.1529 53.0583 25.2392 52.5906 25.3176L52.4774 24.4941C52.9904 24.4157 53.4808 24.3216 53.941 24.2196V22.8706H52.4699V22.0863H53.941V21.3569C53.5789 21.4353 53.2092 21.498 52.8169 21.5529L52.6509 20.7765C53.692 20.6588 54.6275 20.4314 55.4423 20.0863L55.7139 20.8549C55.4046 20.9725 55.0802 21.0745 54.7407 21.1686V22.0863H56.2872C56.242 21.4824 56.2269 20.8157 56.2269 20.0941H57.019C57.0266 20.8471 57.0492 21.5059 57.0945 22.0863H59.3502V22.8706H57.1548C57.2001 23.3804 57.268 23.7961 57.351 24.1255C57.3812 24.251 57.4113 24.3608 57.4415 24.4706C57.7508 24.0706 58.0224 23.6235 58.2487 23.1373L58.9277 23.5137C58.5958 24.2196 58.1959 24.8392 57.7357 25.3569C57.8112 25.5451 57.8942 25.7098 57.9771 25.8353C58.1884 26.1804 58.3544 26.3529 58.46 26.3529C58.543 26.3529 58.6259 25.9529 58.7165 25.1686L59.4181 25.5529C59.2219 26.6745 58.9428 27.2392 58.5731 27.2392C58.2412 27.2392 57.8942 27.0039 57.5396 26.5412C57.4038 26.3608 57.2755 26.1569 57.1624 25.9216C56.6494 26.3608 56.076 26.7059 55.4498 26.9569L55.0123 26.2588C55.7063 25.9922 56.3174 25.6157 56.838 25.1294C56.755 24.8784 56.6795 24.6196 56.6116 24.3529C56.4985 23.9294 56.4155 23.4353 56.3551 22.8706H54.7407V24.0314C55.1782 23.9137 55.6007 23.7882 55.993 23.6471ZM57.8489 20.1647C58.377 20.5098 58.8296 20.8549 59.2068 21.2L58.641 21.7882C58.3317 21.4431 57.8942 21.0824 57.3208 20.6902L57.8489 20.1647Z" fill="currentColor"/>
|
||||
<path d="M62.6847 21.2H63.9371V20.0941H64.7066V21.2H66.3059V23.5451H66.7963V24.3451H64.948C65.3931 25.2863 66.0796 26.0627 67 26.6588L66.4644 27.3098C65.544 26.6118 64.8499 25.7569 64.3822 24.7373C64.02 25.8824 63.3712 26.7373 62.4207 27.302L61.9378 26.6275C62.8281 26.149 63.4165 25.3882 63.7107 24.3451H62.383V23.5451H63.8692C63.9144 23.2314 63.9371 22.902 63.9371 22.5569V21.9608H62.6847V21.2ZM64.7066 21.9608V22.3765C64.7066 22.7843 64.6764 23.1765 64.6311 23.5451H65.5515V21.9608H64.7066ZM60.1574 21.6314L60.761 21.6784C60.7459 22.4627 60.6629 23.2078 60.5271 23.9137L59.8934 23.7255C60.0443 23.0667 60.1348 22.3686 60.1574 21.6314ZM62.2547 21.4275C62.4509 21.9294 62.6319 22.5098 62.7828 23.1608L62.1566 23.3255C62.0435 22.7765 61.9001 22.2431 61.7191 21.7333V27.3176H60.942V20.102H61.7191V21.6078L62.2547 21.4275Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
77
src/pages/UserCenter/MobileLayout/index.vue
Normal file
@ -0,0 +1,77 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import PlanCard from '@/components/user-center/PlanCard.vue'
|
||||
import DeviceList from '@/components/user-center/DeviceList.vue'
|
||||
import PaymentMethod from '@/components/user-center/PaymentMethod.vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
// --- Mock Data ---
|
||||
const devices = [
|
||||
{ id: '1', name: 'XXX的 MacBook Pro 15-inch', type: 'desktop' as const, deviceId: '87654321' },
|
||||
{ id: '2', name: 'XXX的 iPhone 15 Pro Max', type: 'mobile' as const, deviceId: '12345678' },
|
||||
]
|
||||
|
||||
const plans = [
|
||||
{ id: 'p1', days: 7, price: 2.79, dailyPrice: '0.39' },
|
||||
{ id: 'p2', days: 30, price: 5.99, dailyPrice: '0.19', discount: '50% off' },
|
||||
{ id: 'p3', days: 90, price: 12.99, dailyPrice: '0.14', discount: '64% off' },
|
||||
{ id: 'p4', days: 365, price: 44.99, dailyPrice: '0.12', discount: '70% off', inverted: true },
|
||||
]
|
||||
|
||||
// --- State ---
|
||||
const selectedPlanId = ref('p2')
|
||||
const selectedPayment = ref('alipay')
|
||||
|
||||
// --- Handlers ---
|
||||
const handlePlanSelect = (id: string) => {
|
||||
selectedPlanId.value = id
|
||||
}
|
||||
const currentPlanIndex = ref(3)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Main Neon Green Card -->
|
||||
<div class="pt-[35px]">
|
||||
<div class="mb-3 ml-[31px] flex h-[60px] items-center gap-3">
|
||||
<img src="../avatar.png" class="size-[60px]" alt="" />
|
||||
<div class="flex h-full flex-col justify-center text-white">
|
||||
<div class="text-xl font-semibold">11emai</div>
|
||||
<div class="text-xs">到期时间: 122222</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-5 flex justify-between pr-[25px] pl-[21px] text-white">
|
||||
<DeviceList :devices="devices" />
|
||||
</div>
|
||||
<div class="overflow-hidden rounded-4xl bg-[#A8FF53]">
|
||||
<PlanCard :plans="plans" :currentPlanIndex="currentPlanIndex" />
|
||||
<div class="pt-2">
|
||||
<PaymentMethod />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pt-8 pb-[calc(50px+env(safe-area-inset-bottom))]">
|
||||
<Button
|
||||
variant="outline"
|
||||
class="mb-[10px] h-[50px] w-full rounded-[32px] border-2 border-[#FF00B7] bg-transparent text-xl font-bold text-[#FF00B7] transition-all hover:bg-[#FF00FF]/90 active:scale-[0.98]"
|
||||
>
|
||||
注销账户
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
class="h-[50px] w-full rounded-[32px] border-2 border-white bg-transparent text-xl font-bold text-white transition-all hover:bg-white/90 active:scale-[0.98]"
|
||||
>
|
||||
退出登录
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Simplified layout font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap');
|
||||
|
||||
.tracking-tight {
|
||||
font-family: 'Inter', 'PingFang SC', sans-serif;
|
||||
}
|
||||
</style>
|
||||
BIN
src/pages/UserCenter/avatar.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
@ -1,10 +1,51 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import MobileLayout from './MobileLayout/index.vue'
|
||||
import Logo from '@/pages/Home/logo.svg?component'
|
||||
import MobileLogo from '@/pages/Home/mobile-logo.svg?component'
|
||||
|
||||
// --- State ---
|
||||
const selectedPlanId = ref('p2')
|
||||
const selectedPayment = ref('alipay')
|
||||
|
||||
// --- Handlers ---
|
||||
const handlePlanSelect = (id: string) => {
|
||||
selectedPlanId.value = id
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-min-vh bg-black">
|
||||
<h1 class="mb-4 text-3xl font-bold">User Center</h1>
|
||||
<p class="text-gray-600">This is the user profile page.</p>
|
||||
<div class="min-h-screen bg-black text-black">
|
||||
<!-- Full Width Header -->
|
||||
<div class="h-[88px]">
|
||||
<header
|
||||
class="fixed top-[20px] right-[18px] left-[18px] z-50 flex h-[68px] items-center justify-between rounded-[90px] bg-[#ADFF5B] pr-[30px] pl-6"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Desktop Logo -->
|
||||
<Logo :src="Logo" alt="Hi快VPN" class="hidden h-10 w-auto text-black md:block" />
|
||||
<!-- Mobile Logo -->
|
||||
<MobileLogo
|
||||
:src="MobileLogo"
|
||||
alt="Hi快VPN"
|
||||
class="block h-[28px] w-[67px] text-black md:hidden"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-xl font-[600]">个人账户</div>
|
||||
</header>
|
||||
</div>
|
||||
<!-- Main Neon Green Card -->
|
||||
<div class="px-[18px]">
|
||||
<MobileLayout />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// User center logic
|
||||
</script>
|
||||
<style scoped>
|
||||
/* Simplified layout font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap');
|
||||
|
||||
.tracking-tight {
|
||||
font-family: 'Inter', 'PingFang SC', sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -4,18 +4,14 @@ import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
|
||||
import svgLoader from 'vite-svg-loader'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
tailwindcss(),
|
||||
vueDevTools(),
|
||||
],
|
||||
plugins: [vue(), tailwindcss(), vueDevTools(), svgLoader()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||