nuxt-layer-core 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/layers/solution/app/components/LinuxIntroSection.vue +280 -0
- package/app/layers/solution/app/components/LinuxVersionsSection.vue +331 -0
- package/app/layers/solution/app/components/UbuntuMark.vue +18 -0
- package/app/layers/solution/app/components/WhyChooseUbuntuSection.vue +141 -0
- package/app/layers/solution/app/composables/useSolutionApi.ts +2 -2
- package/app/layers/solution/app/data/linuxVersions.ts +386 -0
- package/app/layers/solution/app/pages/giai-phap-proxmox/[slug]/index.vue +1 -1
- package/app/layers/solution/app/pages/gioi-thieu-san-pham/[slug]/index.vue +2 -2
- package/app/layers/solution/app/pages/template/[slug]/index.vue +22 -0
- package/app/layers/solution/app/pages/tu-van/[slug]/index.vue +1 -1
- package/package.json +1 -1
- /package/app/layers/solution/app/pages/tu-van/{khoa-hoc-proxmox.vue → khoa-hoc-proxmox.vue.disabled} +0 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section class="relative">
|
|
3
|
+
<!-- Hero -->
|
|
4
|
+
<div class="bg-gradient-to-br from-[#004AC6] to-[#1D4ED8] text-white pt-40 pb-24 overflow-hidden relative">
|
|
5
|
+
<div class="absolute inset-0 opacity-[0.06]"
|
|
6
|
+
style="background-image: radial-gradient(circle, #fff 1px, transparent 1px); background-size: 24px 24px;"></div>
|
|
7
|
+
|
|
8
|
+
<div class="max-w-7xl mx-auto px-6 lg:px-8 grid lg:grid-cols-2 gap-14 items-center relative z-10">
|
|
9
|
+
<div>
|
|
10
|
+
<div
|
|
11
|
+
class="inline-flex items-center gap-2 bg-white/10 backdrop-blur-md px-4 py-2 rounded-[10px] border border-white/20 mb-6">
|
|
12
|
+
<UbuntuMark :size="16" />
|
|
13
|
+
<span class="text-xs font-bold uppercase tracking-widest">
|
|
14
|
+
Hệ điều hành máy chủ · Mã nguồn mở
|
|
15
|
+
</span>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<h1 class="font-['Montserrat'] font-extrabold text-2xl sm:text-[2rem] leading-[1.15] mb-6">
|
|
19
|
+
Linux là nền tảng cho phần lớn<br />
|
|
20
|
+
hạ tầng máy chủ hiện đại
|
|
21
|
+
</h1>
|
|
22
|
+
|
|
23
|
+
<p class="text-blue-100/90 text-lg leading-relaxed mb-8 max-w-xl">
|
|
24
|
+
Miễn phí, mã nguồn mở và được cộng đồng toàn cầu kiểm chứng qua hàng chục năm.
|
|
25
|
+
Trong số các bản phân phối (distro) Linux hiện có, chúng tôi triển khai và hỗ trợ
|
|
26
|
+
chính trên <strong class="text-white">Ubuntu Server</strong> — lựa chọn phù hợp cho phần lớn nhu cầu.
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
<div class="flex flex-wrap gap-4">
|
|
30
|
+
<a href="#phien-ban" @click.prevent="scrollTo('phien-ban')"
|
|
31
|
+
class="bg-white text-[#004AC6] px-7 py-3.5 rounded-[10px] font-bold flex items-center gap-2 hover:bg-blue-50 transition-colors shadow-lg active:scale-95">
|
|
32
|
+
Xem các phiên bản hỗ trợ
|
|
33
|
+
<Icon name="lucide:arrow-right" class="text-[18px]" />
|
|
34
|
+
</a>
|
|
35
|
+
|
|
36
|
+
<a href="#vi-sao-ubuntu" @click.prevent="scrollTo('vi-sao-ubuntu')"
|
|
37
|
+
class="bg-transparent border border-white/40 text-white px-7 py-3.5 rounded-[10px] font-bold hover:bg-white/10 transition-colors">
|
|
38
|
+
Vì sao chọn Ubuntu?
|
|
39
|
+
</a>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<!-- Sơ đồ "lớp nền tảng": Linux/Ubuntu là lớp lõi bên dưới ứng dụng của bạn - minh hoạ đúng nghĩa "nền tảng" thay vì 1 khối UI dashboard chung chung -->
|
|
44
|
+
<div class="relative flex justify-center py-6">
|
|
45
|
+
<div class="linux-glow absolute w-64 h-64 sm:w-72 sm:h-72 bg-orange-400/25 rounded-full blur-3xl -top-10 -left-6"></div>
|
|
46
|
+
<div class="linux-glow linux-glow-delay absolute w-64 h-64 sm:w-72 sm:h-72 bg-sky-300/25 rounded-full blur-3xl -bottom-10 -right-6"></div>
|
|
47
|
+
|
|
48
|
+
<div class="stack-float relative w-full max-w-sm">
|
|
49
|
+
<!-- đường dẫn năng lượng chạy dọc, nối các lớp lại với nhau -->
|
|
50
|
+
<div class="absolute left-6 top-6 bottom-6 w-px bg-gradient-to-b from-white/0 via-white/25 to-white/0"></div>
|
|
51
|
+
<div class="absolute left-[23px] top-6 bottom-6 w-[3px] overflow-hidden rounded-full">
|
|
52
|
+
<div class="stack-flow absolute left-0 w-[3px] h-20 bg-gradient-to-b from-transparent via-orange-300 to-transparent"></div>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div class="flex flex-col gap-4">
|
|
56
|
+
<div
|
|
57
|
+
v-for="(layer, i) in stackLayers"
|
|
58
|
+
:key="layer.title"
|
|
59
|
+
class="stack-layer relative flex items-center gap-4"
|
|
60
|
+
:style="{ animationDelay: `${i * 150}ms` }"
|
|
61
|
+
>
|
|
62
|
+
<div class="relative z-10 w-12 h-12 rounded-2xl flex items-center justify-center shrink-0"
|
|
63
|
+
:class="layer.highlight
|
|
64
|
+
? 'bg-white text-[#004AC6] shadow-lg shadow-black/20 ring-4 ring-white/25'
|
|
65
|
+
: 'bg-white/10 border border-white/20 backdrop-blur-md'"
|
|
66
|
+
>
|
|
67
|
+
<UbuntuMark v-if="layer.mark" :size="22" :stroke="layer.highlight ? '#004AC6' : '#fff'"
|
|
68
|
+
:accent="layer.highlight ? '#004AC6' : '#fff'" />
|
|
69
|
+
<Icon v-else :name="layer.icon" class="w-5 h-5" :class="layer.highlight ? '' : 'text-white'" />
|
|
70
|
+
</div>
|
|
71
|
+
|
|
72
|
+
<div class="flex-1 rounded-xl px-4 py-3 backdrop-blur-md transition-all"
|
|
73
|
+
:class="layer.highlight
|
|
74
|
+
? 'bg-white/15 border border-white/40 shadow-lg'
|
|
75
|
+
: 'bg-white/5 border border-white/10'"
|
|
76
|
+
>
|
|
77
|
+
<p class="text-sm font-bold flex items-center gap-2">
|
|
78
|
+
{{ layer.title }}
|
|
79
|
+
<span v-if="layer.highlight"
|
|
80
|
+
class="text-[9px] font-bold uppercase tracking-wide bg-white/20 rounded-full px-2 py-0.5">
|
|
81
|
+
Khuyến nghị
|
|
82
|
+
</span>
|
|
83
|
+
</p>
|
|
84
|
+
<p class="text-[11.5px] text-white/60 mt-0.5">{{ layer.desc }}</p>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
|
|
93
|
+
<!-- Stats + benefits -->
|
|
94
|
+
<div class="bg-[#F7F9FB]">
|
|
95
|
+
<div class="relative -mt-8 z-10 max-w-7xl mx-auto px-6 lg:px-8">
|
|
96
|
+
<div class="hero-stats bg-white rounded-xl shadow-xl border border-slate-100 py-8 px-6">
|
|
97
|
+
<div class="grid grid-cols-2 sm:grid-cols-4 gap-8 sm:divide-x divide-slate-200">
|
|
98
|
+
<div v-for="stat in stats" :key="stat.label" class="text-center">
|
|
99
|
+
<div class="font-['Montserrat'] font-extrabold text-2xl sm:text-3xl text-[#004AC6]">
|
|
100
|
+
{{ stat.value }}
|
|
101
|
+
</div>
|
|
102
|
+
<div class="text-slate-500 text-xs sm:text-sm font-medium mt-1">
|
|
103
|
+
{{ stat.label }}
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<div class="max-w-7xl mx-auto px-6 lg:px-8 py-24">
|
|
111
|
+
<div class="text-center mb-16">
|
|
112
|
+
<h2 class="text-[#004AC6] font-bold uppercase tracking-widest text-sm mb-2">Vì sao dùng Linux</h2>
|
|
113
|
+
<h3 class="font-['Montserrat'] font-extrabold text-2xl sm:text-3xl text-slate-900 mb-4">
|
|
114
|
+
Nền tảng đáng tin cậy cho mọi quy mô hệ thống
|
|
115
|
+
</h3>
|
|
116
|
+
<p class="text-slate-500 max-w-2xl mx-auto">
|
|
117
|
+
Từ máy chủ web đơn giản đến hạ tầng cloud quy mô lớn, Linux là lựa chọn hàng đầu
|
|
118
|
+
của các nhà cung cấp dịch vụ và doanh nghiệp công nghệ trên thế giới.
|
|
119
|
+
</p>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
123
|
+
<div
|
|
124
|
+
v-for="(item, i) in benefits"
|
|
125
|
+
:key="item.title"
|
|
126
|
+
:data-delay="i * 100"
|
|
127
|
+
class="linux-benefit-card bg-white p-8 rounded-xl border border-slate-200 hover:shadow-xl hover:border-blue-200 transition-all"
|
|
128
|
+
>
|
|
129
|
+
<div class="w-11 h-11 rounded-[10px] bg-blue-50 flex items-center justify-center mb-6 text-[#004AC6]">
|
|
130
|
+
<Icon :name="item.icon" />
|
|
131
|
+
</div>
|
|
132
|
+
<h4 class="font-bold text-lg text-slate-900 mb-3">{{ item.title }}</h4>
|
|
133
|
+
<p class="text-sm text-slate-500 leading-relaxed">{{ item.desc }}</p>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</section>
|
|
139
|
+
</template>
|
|
140
|
+
|
|
141
|
+
<script setup>
|
|
142
|
+
const { scrollTo } = useScrollToSection()
|
|
143
|
+
|
|
144
|
+
useScrollAnimate('.hero-stats', 'fade-up')
|
|
145
|
+
useScrollAnimate('.linux-benefit-card', 'scale-up')
|
|
146
|
+
|
|
147
|
+
// Các lớp trong sơ đồ "nền tảng": từ ứng dụng trên cùng xuống tới phần cứng dưới cùng, Ubuntu là lớp được khuyến nghị
|
|
148
|
+
const stackLayers = [
|
|
149
|
+
{
|
|
150
|
+
title: 'Ứng dụng & dịch vụ của bạn',
|
|
151
|
+
desc: 'Website, API, database, workload của riêng bạn',
|
|
152
|
+
icon: 'lucide:layout-grid',
|
|
153
|
+
highlight: false,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
title: 'Ubuntu Server LTS',
|
|
157
|
+
desc: 'Hệ điều hành được chúng tôi khuyến nghị triển khai',
|
|
158
|
+
mark: true,
|
|
159
|
+
highlight: true,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
title: 'Linux Kernel',
|
|
163
|
+
desc: 'Lõi hệ điều hành, quản lý tiến trình và tài nguyên hệ thống',
|
|
164
|
+
icon: 'lucide:cpu',
|
|
165
|
+
highlight: false,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
title: 'Phần cứng máy chủ',
|
|
169
|
+
desc: 'CPU, RAM, lưu trữ SSD/NVMe vật lý',
|
|
170
|
+
icon: 'lucide:server',
|
|
171
|
+
highlight: false,
|
|
172
|
+
},
|
|
173
|
+
]
|
|
174
|
+
|
|
175
|
+
const stats = [
|
|
176
|
+
{ value: '96%', label: 'Top 1M website chạy trên Linux' },
|
|
177
|
+
{ value: '3', label: 'Phiên bản Ubuntu đang hỗ trợ' },
|
|
178
|
+
{ value: '10+', label: 'Năm hỗ trợ bảo mật (Ubuntu LTS)' },
|
|
179
|
+
{ value: '24/7', label: 'Đội ngũ vận hành hỗ trợ' },
|
|
180
|
+
]
|
|
181
|
+
|
|
182
|
+
const benefits = [
|
|
183
|
+
{
|
|
184
|
+
icon: 'lucide:code-2',
|
|
185
|
+
title: 'Mã nguồn mở & miễn phí',
|
|
186
|
+
desc: 'Không tốn chi phí bản quyền, toàn quyền tuỳ biến hệ thống theo nhu cầu riêng của bạn.',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
icon: 'lucide:shield-check',
|
|
190
|
+
title: 'Bảo mật vượt trội',
|
|
191
|
+
desc: 'Cộng đồng và nhà phát triển liên tục rà soát, vá lỗi nhanh chóng ngay khi phát hiện.',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
icon: 'lucide:gauge',
|
|
195
|
+
title: 'Hiệu năng & ổn định',
|
|
196
|
+
desc: 'Tiêu tốn ít tài nguyên hơn, phù hợp chạy liên tục nhiều năm không cần khởi động lại.',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
icon: 'lucide:users',
|
|
200
|
+
title: 'Cộng đồng hỗ trợ toàn cầu',
|
|
201
|
+
desc: 'Hàng triệu tài liệu, diễn đàn và chuyên gia sẵn sàng hỗ trợ khi bạn gặp sự cố.',
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
icon: 'lucide:sliders-horizontal',
|
|
205
|
+
title: 'Khả năng tuỳ biến cao',
|
|
206
|
+
desc: 'Cài đặt đúng những gì cần dùng, dễ dàng tối ưu cho từng loại ứng dụng cụ thể.',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
icon: 'lucide:piggy-bank',
|
|
210
|
+
title: 'Tiết kiệm chi phí',
|
|
211
|
+
desc: 'Không phát sinh phí license theo số lượng máy chủ, tối ưu chi phí khi mở rộng quy mô.',
|
|
212
|
+
},
|
|
213
|
+
]
|
|
214
|
+
</script>
|
|
215
|
+
|
|
216
|
+
<style scoped>
|
|
217
|
+
.linux-glow {
|
|
218
|
+
animation: linux-glow-drift 8s ease-in-out infinite;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.linux-glow-delay {
|
|
222
|
+
animation-delay: -4s;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
@keyframes linux-glow-drift {
|
|
226
|
+
0%, 100% {
|
|
227
|
+
transform: translate(0, 0) scale(1);
|
|
228
|
+
opacity: 0.6;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
50% {
|
|
232
|
+
transform: translate(12px, -12px) scale(1.1);
|
|
233
|
+
opacity: 0.9;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.stack-float {
|
|
238
|
+
animation: stack-float-y 6s ease-in-out infinite;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
@keyframes stack-float-y {
|
|
242
|
+
0%, 100% {
|
|
243
|
+
transform: translateY(0);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
50% {
|
|
247
|
+
transform: translateY(-8px);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.stack-layer {
|
|
252
|
+
animation: stack-layer-in 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
@keyframes stack-layer-in {
|
|
256
|
+
from {
|
|
257
|
+
opacity: 0;
|
|
258
|
+
transform: translateX(-16px);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
to {
|
|
262
|
+
opacity: 1;
|
|
263
|
+
transform: translateX(0);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.stack-flow {
|
|
268
|
+
animation: stack-flow-y 3s linear infinite;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@keyframes stack-flow-y {
|
|
272
|
+
0% {
|
|
273
|
+
transform: translateY(-100%);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
100% {
|
|
277
|
+
transform: translateY(340%);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
</style>
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section id="phien-ban" ref="sectionRoot" class="py-24 bg-[#F7F9FB] overflow-hidden"
|
|
3
|
+
:class="{ 'versions-revealed': revealed }">
|
|
4
|
+
<div class="max-w-6xl mx-auto px-6 lg:px-8">
|
|
5
|
+
<div class="text-center mb-12 versions-header">
|
|
6
|
+
<h2 class="text-[#004AC6] font-bold uppercase tracking-widest text-sm mb-2">Phiên bản hỗ trợ</h2>
|
|
7
|
+
<h3 class="font-['Montserrat'] font-extrabold text-2xl sm:text-4xl text-slate-900 mb-4">
|
|
8
|
+
Chọn phiên bản Ubuntu<br class="hidden sm:block" />
|
|
9
|
+
phù hợp với hệ thống của bạn
|
|
10
|
+
</h3>
|
|
11
|
+
<p class="text-slate-500 max-w-2xl mx-auto leading-relaxed">
|
|
12
|
+
Mỗi phiên bản Ubuntu có vòng đời hỗ trợ khác nhau. Chọn một phiên bản để triển khai,
|
|
13
|
+
sau đó chọn gói dịch vụ tương ứng bên dưới.
|
|
14
|
+
</p>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<!-- Version cards -->
|
|
18
|
+
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-16">
|
|
19
|
+
<button
|
|
20
|
+
v-for="version in resolvedVersions"
|
|
21
|
+
:key="version.id"
|
|
22
|
+
type="button"
|
|
23
|
+
@click="activeVersionId = version.id"
|
|
24
|
+
class="version-reveal relative text-left bg-white rounded-2xl border p-6 flex flex-col gap-4 transition-all duration-300 cursor-pointer"
|
|
25
|
+
:style="{ '--i': 0 }"
|
|
26
|
+
:class="activeVersionId === version.id
|
|
27
|
+
? 'border-[#004AC6] ring-1 ring-[#004AC6]/25 shadow-[0_12px_30px_-8px_rgba(0,74,198,0.25)]'
|
|
28
|
+
: 'border-slate-200 hover:border-blue-200 hover:shadow-lg'
|
|
29
|
+
"
|
|
30
|
+
>
|
|
31
|
+
<span
|
|
32
|
+
v-if="activeVersionId === version.id"
|
|
33
|
+
class="absolute -top-2.5 -right-2.5 w-7 h-7 rounded-full bg-[#004AC6] text-white flex items-center justify-center shadow-md"
|
|
34
|
+
>
|
|
35
|
+
<Icon name="lucide:check" class="w-4 h-4" />
|
|
36
|
+
</span>
|
|
37
|
+
|
|
38
|
+
<div class="flex items-center justify-between">
|
|
39
|
+
<UbuntuMark :size="32" :stroke="toneOf(version).icon" :accent="toneOf(version).icon" />
|
|
40
|
+
<span
|
|
41
|
+
class="text-[11px] font-bold uppercase tracking-wide px-2.5 py-1 rounded-full text-white"
|
|
42
|
+
:class="toneOf(version).pill"
|
|
43
|
+
>
|
|
44
|
+
{{ version.badge }}
|
|
45
|
+
</span>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
<div>
|
|
49
|
+
<h4 class="font-bold text-lg text-slate-900">Ubuntu {{ version.version }}</h4>
|
|
50
|
+
<p class="text-sm font-semibold" :class="toneOf(version).text">{{ version.codename }}</p>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<p class="text-sm text-slate-500 leading-relaxed grow">{{ version.desc }}</p>
|
|
54
|
+
|
|
55
|
+
<div class="text-xs text-slate-400 space-y-1 pt-3 border-t border-slate-100">
|
|
56
|
+
<p>Ra mắt: {{ version.releaseDate }}</p>
|
|
57
|
+
<p class="font-semibold text-slate-600">{{ version.supportUntil }}</p>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<span
|
|
61
|
+
class="mt-1 inline-flex items-center justify-center gap-2 w-full py-2.5 rounded-xl font-bold text-sm transition-all duration-300"
|
|
62
|
+
:class="activeVersionId === version.id
|
|
63
|
+
? 'bg-[#004AC6] text-white shadow-lg shadow-blue-500/25'
|
|
64
|
+
: 'border border-slate-200 text-slate-600'
|
|
65
|
+
"
|
|
66
|
+
>
|
|
67
|
+
<Icon name="lucide:arrow-right" class="w-4 h-4" />
|
|
68
|
+
Triển khai
|
|
69
|
+
</span>
|
|
70
|
+
</button>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<!-- Product groups for the selected version -->
|
|
74
|
+
<div class="text-center mb-10">
|
|
75
|
+
<h4 class="font-['Montserrat'] font-extrabold text-xl sm:text-2xl text-slate-900">
|
|
76
|
+
Nhóm sản phẩm hỗ trợ trên Ubuntu {{ activeVersion.version }}
|
|
77
|
+
</h4>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<Transition name="fade-swap" mode="out-in">
|
|
81
|
+
<div :key="activeVersionId" class="flex flex-col gap-14">
|
|
82
|
+
<div
|
|
83
|
+
v-for="(group, gi) in activeVersion.groups"
|
|
84
|
+
:key="group.id"
|
|
85
|
+
class="version-reveal"
|
|
86
|
+
:style="{ '--i': gi + 1 }"
|
|
87
|
+
>
|
|
88
|
+
<div class="flex items-start gap-3 mb-6">
|
|
89
|
+
<div class="w-10 h-10 rounded-[10px] bg-blue-50 flex items-center justify-center text-[#004AC6] shrink-0">
|
|
90
|
+
<Icon :name="group.icon" class="w-5 h-5" />
|
|
91
|
+
</div>
|
|
92
|
+
<div>
|
|
93
|
+
<h4 class="font-bold text-lg text-slate-900">{{ group.name }}</h4>
|
|
94
|
+
<p class="text-sm text-slate-500 mt-0.5">{{ group.desc }}</p>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
99
|
+
<div
|
|
100
|
+
v-for="pkg in group.packages"
|
|
101
|
+
:key="pkg.id"
|
|
102
|
+
class="relative bg-white rounded-2xl flex flex-col overflow-hidden transition-all duration-300 ease-out"
|
|
103
|
+
:class="pkg.highlight
|
|
104
|
+
? 'ring-1 ring-[#004AC6]/15 shadow-[0_8px_30px_-6px_rgba(0,74,198,0.25)] hover:shadow-[0_20px_45px_-10px_rgba(0,74,198,0.35)] hover:-translate-y-1'
|
|
105
|
+
: 'ring-1 ring-slate-200 shadow-[0_2px_10px_-2px_rgba(15,23,42,0.06)] hover:ring-blue-200 hover:shadow-[0_12px_30px_-8px_rgba(15,23,42,0.12)] hover:-translate-y-1'
|
|
106
|
+
"
|
|
107
|
+
>
|
|
108
|
+
<div
|
|
109
|
+
v-if="pkg.highlight"
|
|
110
|
+
class="bg-gradient-to-r from-[#004AC6] to-[#1D63E0] text-white text-[11px] font-bold py-2 text-center uppercase tracking-widest flex items-center justify-center gap-1.5"
|
|
111
|
+
>
|
|
112
|
+
<Icon name="lucide:star" class="w-3.5 h-3.5" />
|
|
113
|
+
Phổ biến nhất
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<div class="p-6 flex flex-col gap-4 grow">
|
|
117
|
+
<div>
|
|
118
|
+
<h5 class="font-bold text-slate-900 mb-1.5">{{ pkg.name }}</h5>
|
|
119
|
+
<p class="text-slate-500 text-sm leading-relaxed">{{ pkg.desc }}</p>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<div class="pb-1">
|
|
123
|
+
<span class="font-['Montserrat'] font-extrabold text-xl text-slate-900">
|
|
124
|
+
{{ formatPrice(pkg.price) }}đ
|
|
125
|
+
</span>
|
|
126
|
+
<span class="text-slate-400 text-sm">{{ pkg.unit }}</span>
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
<div class="flex flex-wrap gap-1.5">
|
|
130
|
+
<span
|
|
131
|
+
v-for="tag in pkg.tags"
|
|
132
|
+
:key="tag"
|
|
133
|
+
class="text-[11px] font-medium text-slate-500 bg-slate-50 border border-slate-100 rounded-md px-2 py-1"
|
|
134
|
+
>
|
|
135
|
+
{{ tag }}
|
|
136
|
+
</span>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<ul class="flex flex-col gap-2 pt-3 border-t border-slate-100">
|
|
140
|
+
<li
|
|
141
|
+
v-for="feature in pkg.features"
|
|
142
|
+
:key="feature"
|
|
143
|
+
class="flex items-start gap-2 text-sm text-slate-600"
|
|
144
|
+
>
|
|
145
|
+
<Icon name="lucide:check" class="w-4 h-4 text-[#004AC6] mt-0.5 shrink-0" />
|
|
146
|
+
{{ feature }}
|
|
147
|
+
</li>
|
|
148
|
+
</ul>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div class="p-6 pt-2">
|
|
152
|
+
<button
|
|
153
|
+
type="button"
|
|
154
|
+
@click="handleSelectPackage(pkg, group)"
|
|
155
|
+
class="w-full py-3 rounded-xl font-bold text-sm transition-all duration-300 cursor-pointer"
|
|
156
|
+
:class="pkg.highlight
|
|
157
|
+
? 'bg-[#004AC6] text-white shadow-lg shadow-blue-500/25 hover:bg-[#1D4ED8] hover:shadow-blue-500/40'
|
|
158
|
+
: 'border border-slate-200 text-slate-600 hover:border-[#004AC6] hover:text-[#004AC6] hover:bg-blue-50/50'
|
|
159
|
+
"
|
|
160
|
+
>
|
|
161
|
+
Tư vấn gói này
|
|
162
|
+
</button>
|
|
163
|
+
</div>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</Transition>
|
|
169
|
+
</div>
|
|
170
|
+
</section>
|
|
171
|
+
</template>
|
|
172
|
+
|
|
173
|
+
<script setup>
|
|
174
|
+
// Data giả dùng khi chưa cấu hình CMS - đã tắt vì CMS đã có data thật, giữ lại để bật lại khi cần
|
|
175
|
+
// import { ubuntuVersions as fallbackVersions } from '../data/linuxVersions'
|
|
176
|
+
|
|
177
|
+
const props = defineProps({
|
|
178
|
+
activeVersionId: { type: String, default: '' },
|
|
179
|
+
// groupsItem0X: JSON thông tin 1 phiên bản Ubuntu (id, version, codename, badge, badgeTone, recommended, releaseDate, supportUntil, desc)
|
|
180
|
+
groupsItem01: { type: Object, default: null },
|
|
181
|
+
groupsItem02: { type: Object, default: null },
|
|
182
|
+
groupsItem03: { type: Object, default: null },
|
|
183
|
+
// itemId0X_groups_0Y: JSON 1 nhóm sản phẩm (id, name, icon, desc, packages[]) thuộc phiên bản groupsItem0Y
|
|
184
|
+
itemId01Groups01: { type: Object, default: null },
|
|
185
|
+
itemId02Groups01: { type: Object, default: null },
|
|
186
|
+
itemId03Groups01: { type: Object, default: null },
|
|
187
|
+
itemId01Groups02: { type: Object, default: null },
|
|
188
|
+
itemId02Groups02: { type: Object, default: null },
|
|
189
|
+
itemId03Groups02: { type: Object, default: null },
|
|
190
|
+
itemId01Groups03: { type: Object, default: null },
|
|
191
|
+
itemId02Groups03: { type: Object, default: null },
|
|
192
|
+
itemId03Groups03: { type: Object, default: null },
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
const emit = defineEmits(['select-package'])
|
|
196
|
+
|
|
197
|
+
useScrollAnimate('.versions-header', 'fade-up')
|
|
198
|
+
|
|
199
|
+
// Chuẩn hoá 1 nhóm sản phẩm từ CMS (item_id_0X_groups_0Y)
|
|
200
|
+
const normalizeGroup = (raw) => {
|
|
201
|
+
if (!raw || typeof raw !== 'object' || !raw.name) return null
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
id: raw.id || raw.name,
|
|
205
|
+
name: raw.name,
|
|
206
|
+
icon: raw.icon || 'lucide:server-cog',
|
|
207
|
+
desc: raw.desc || '',
|
|
208
|
+
packages: Array.isArray(raw.packages) ? raw.packages : [],
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Ghép 1 phiên bản Ubuntu (groups_item_0X) + 3 nhóm sản phẩm của nó (item_id_0X_groups_0Y)
|
|
213
|
+
// Không có data CMS cho slot nào -> bỏ qua slot đó (không dùng data giả để fallback nữa)
|
|
214
|
+
const buildVersion = (meta, groupSlots) => {
|
|
215
|
+
if (!meta || typeof meta !== 'object' || !meta.id) return null
|
|
216
|
+
|
|
217
|
+
const groups = groupSlots.map(normalizeGroup).filter(Boolean)
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
...meta,
|
|
221
|
+
groups,
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const resolvedVersions = computed(() =>
|
|
226
|
+
[
|
|
227
|
+
buildVersion(props.groupsItem01, [props.itemId01Groups01, props.itemId02Groups01, props.itemId03Groups01]),
|
|
228
|
+
buildVersion(props.groupsItem02, [props.itemId01Groups02, props.itemId02Groups02, props.itemId03Groups02]),
|
|
229
|
+
buildVersion(props.groupsItem03, [props.itemId01Groups03, props.itemId02Groups03, props.itemId03Groups03]),
|
|
230
|
+
].filter(Boolean)
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
const isValidVersion = (id) => resolvedVersions.value.some((v) => v.id === id)
|
|
234
|
+
|
|
235
|
+
const activeVersionId = ref(
|
|
236
|
+
isValidVersion(props.activeVersionId)
|
|
237
|
+
? props.activeVersionId
|
|
238
|
+
: resolvedVersions.value.find((v) => v.recommended)?.id || resolvedVersions.value[0]?.id || ''
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
const emptyVersion = { version: '', codename: '', badge: '', badgeTone: 'slate', releaseDate: '', supportUntil: '', desc: '', groups: [] }
|
|
242
|
+
|
|
243
|
+
const activeVersion = computed(
|
|
244
|
+
() =>
|
|
245
|
+
resolvedVersions.value.find((v) => v.id === activeVersionId.value) ||
|
|
246
|
+
resolvedVersions.value[0] ||
|
|
247
|
+
emptyVersion
|
|
248
|
+
)
|
|
249
|
+
|
|
250
|
+
const badgeToneMap = {
|
|
251
|
+
primary: { pill: 'bg-[#004AC6]', text: 'text-[#004AC6]', icon: '#004AC6' },
|
|
252
|
+
amber: { pill: 'bg-amber-500', text: 'text-amber-600', icon: '#d97706' },
|
|
253
|
+
slate: { pill: 'bg-slate-500', text: 'text-slate-600', icon: '#475569' },
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const toneOf = (version) => badgeToneMap[version.badgeTone] || badgeToneMap.slate
|
|
257
|
+
|
|
258
|
+
function handleSelectPackage(pkg, group) {
|
|
259
|
+
emit('select-package', {
|
|
260
|
+
id: pkg.id,
|
|
261
|
+
name: pkg.name,
|
|
262
|
+
level: `Ubuntu ${activeVersion.value.version} · ${group.name}`,
|
|
263
|
+
duration: pkg.unit,
|
|
264
|
+
icon: 'lucide:server-cog',
|
|
265
|
+
})
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function formatPrice(value) {
|
|
269
|
+
if (!value && value !== 0) return ''
|
|
270
|
+
return new Intl.NumberFormat('vi-VN').format(value)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const sectionRoot = ref(null)
|
|
274
|
+
const revealed = ref(false)
|
|
275
|
+
|
|
276
|
+
onMounted(() => {
|
|
277
|
+
const observer = new IntersectionObserver(
|
|
278
|
+
(entries) => {
|
|
279
|
+
for (const entry of entries) {
|
|
280
|
+
if (entry.isIntersecting) {
|
|
281
|
+
revealed.value = true
|
|
282
|
+
observer.disconnect()
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
{ threshold: 0.15 }
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
if (sectionRoot.value) observer.observe(sectionRoot.value)
|
|
290
|
+
onUnmounted(() => observer.disconnect())
|
|
291
|
+
})
|
|
292
|
+
</script>
|
|
293
|
+
|
|
294
|
+
<style scoped>
|
|
295
|
+
.version-reveal {
|
|
296
|
+
animation: version-group-in 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
297
|
+
animation-delay: calc(var(--i, 0) * 120ms);
|
|
298
|
+
animation-play-state: paused;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
.versions-revealed .version-reveal {
|
|
302
|
+
animation-play-state: running;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
@keyframes version-group-in {
|
|
306
|
+
from {
|
|
307
|
+
opacity: 0;
|
|
308
|
+
transform: translateY(24px);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
to {
|
|
312
|
+
opacity: 1;
|
|
313
|
+
transform: translateY(0);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.fade-swap-enter-active,
|
|
318
|
+
.fade-swap-leave-active {
|
|
319
|
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.fade-swap-enter-from {
|
|
323
|
+
opacity: 0;
|
|
324
|
+
transform: translateY(10px);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.fade-swap-leave-to {
|
|
328
|
+
opacity: 0;
|
|
329
|
+
transform: translateY(-6px);
|
|
330
|
+
}
|
|
331
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg :width="size" :height="size" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
|
3
|
+
<circle cx="24" cy="24" r="19" :stroke="stroke" stroke-width="2" opacity="0.35" />
|
|
4
|
+
<path d="M25.5 5.3A18.7 18.7 0 0 1 40 24" :stroke="stroke" stroke-width="2" stroke-linecap="round" opacity="0.7" />
|
|
5
|
+
<path d="M22.5 42.7A18.7 18.7 0 0 1 8 24" :stroke="stroke" stroke-width="2" stroke-linecap="round" opacity="0.7" />
|
|
6
|
+
<circle cx="25" cy="5" r="4" :fill="accent" />
|
|
7
|
+
<circle cx="7" cy="30" r="4" :fill="accent" />
|
|
8
|
+
<circle cx="41" cy="30" r="4" :fill="accent" />
|
|
9
|
+
</svg>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<script setup>
|
|
13
|
+
defineProps({
|
|
14
|
+
size: { type: [Number, String], default: 28 },
|
|
15
|
+
stroke: { type: String, default: 'currentColor' },
|
|
16
|
+
accent: { type: String, default: 'currentColor' },
|
|
17
|
+
})
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section id="vi-sao-ubuntu" ref="sectionRoot" class="py-24 bg-white overflow-hidden"
|
|
3
|
+
:class="{ 'ubuntu-revealed': revealed }">
|
|
4
|
+
<div class="max-w-7xl mx-auto px-6 lg:px-8">
|
|
5
|
+
<div class="grid lg:grid-cols-[0.9fr_1.1fr] gap-14 items-center mb-16">
|
|
6
|
+
<div class="ubuntu-reveal" style="--i: 0">
|
|
7
|
+
<div class="w-14 h-14 rounded-2xl bg-blue-50 flex items-center justify-center text-[#004AC6] mb-5">
|
|
8
|
+
<UbuntuMark :size="30" />
|
|
9
|
+
</div>
|
|
10
|
+
<h2 class="text-[#004AC6] font-bold uppercase tracking-widest text-sm mb-2">Khuyến nghị</h2>
|
|
11
|
+
<h3 class="font-['Montserrat'] font-extrabold text-2xl sm:text-4xl text-slate-900 mb-4 leading-tight">
|
|
12
|
+
Vì sao nên chọn<br />Ubuntu Server?
|
|
13
|
+
</h3>
|
|
14
|
+
<p class="text-slate-500 leading-relaxed mb-6">
|
|
15
|
+
Trong số các bản phân phối đang hỗ trợ, Ubuntu Server LTS là lựa chọn mặc định của chúng tôi
|
|
16
|
+
cho phần lớn khách hàng nhờ sự cân bằng giữa độ ổn định, tính tương thích và cộng đồng hỗ trợ.
|
|
17
|
+
</p>
|
|
18
|
+
<a href="#phien-ban" @click.prevent="scrollTo('phien-ban')"
|
|
19
|
+
class="inline-flex items-center gap-2 text-[#004AC6] font-bold text-sm hover:gap-3 transition-all">
|
|
20
|
+
Xem các gói dịch vụ trên Ubuntu
|
|
21
|
+
<Icon name="lucide:arrow-right" class="w-4 h-4" />
|
|
22
|
+
</a>
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div class="ubuntu-reveal grid grid-cols-2 gap-4" style="--i: 1">
|
|
26
|
+
<div
|
|
27
|
+
v-for="stat in highlightStats"
|
|
28
|
+
:key="stat.label"
|
|
29
|
+
class="bg-[#F7F9FB] rounded-2xl border border-slate-100 p-6 text-center"
|
|
30
|
+
>
|
|
31
|
+
<div class="font-['Montserrat'] font-extrabold text-2xl text-[#004AC6] mb-1">{{ stat.value }}</div>
|
|
32
|
+
<div class="text-slate-500 text-xs font-medium leading-relaxed">{{ stat.label }}</div>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
38
|
+
<div
|
|
39
|
+
v-for="(reason, i) in reasons"
|
|
40
|
+
:key="reason.title"
|
|
41
|
+
class="ubuntu-reveal bg-white p-7 rounded-xl border border-slate-200 hover:shadow-xl hover:border-blue-200 transition-all"
|
|
42
|
+
:style="{ '--i': i + 2 }"
|
|
43
|
+
>
|
|
44
|
+
<div class="w-11 h-11 rounded-[10px] bg-blue-50 flex items-center justify-center mb-5 text-[#004AC6]">
|
|
45
|
+
<Icon :name="reason.icon" />
|
|
46
|
+
</div>
|
|
47
|
+
<h4 class="font-bold text-slate-900 mb-2">{{ reason.title }}</h4>
|
|
48
|
+
<p class="text-sm text-slate-500 leading-relaxed">{{ reason.desc }}</p>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
</section>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script setup>
|
|
56
|
+
const { scrollTo } = useScrollToSection()
|
|
57
|
+
|
|
58
|
+
const sectionRoot = ref(null)
|
|
59
|
+
const revealed = ref(false)
|
|
60
|
+
|
|
61
|
+
onMounted(() => {
|
|
62
|
+
const observer = new IntersectionObserver(
|
|
63
|
+
(entries) => {
|
|
64
|
+
for (const entry of entries) {
|
|
65
|
+
if (entry.isIntersecting) {
|
|
66
|
+
revealed.value = true
|
|
67
|
+
observer.disconnect()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{ threshold: 0.15 }
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
if (sectionRoot.value) observer.observe(sectionRoot.value)
|
|
75
|
+
onUnmounted(() => observer.disconnect())
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const highlightStats = [
|
|
79
|
+
{ value: '5 năm', label: 'Hỗ trợ bảo mật miễn phí (LTS)' },
|
|
80
|
+
{ value: '10 năm', label: 'Hỗ trợ mở rộng với Ubuntu Pro' },
|
|
81
|
+
{ value: '#1', label: 'Distro phổ biến nhất trên cloud' },
|
|
82
|
+
{ value: '30M+', label: 'Server đang chạy Ubuntu' },
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
const reasons = [
|
|
86
|
+
{
|
|
87
|
+
icon: 'lucide:calendar-check',
|
|
88
|
+
title: 'Vòng đời hỗ trợ dài (LTS)',
|
|
89
|
+
desc: 'Mỗi bản LTS được hỗ trợ cập nhật bảo mật miễn phí 5 năm, hạn chế rủi ro khi vận hành lâu dài.',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
icon: 'lucide:puzzle',
|
|
93
|
+
title: 'Tương thích rộng',
|
|
94
|
+
desc: 'Hầu hết phần mềm, driver và dịch vụ cloud đều hỗ trợ Ubuntu đầu tiên trước các distro khác.',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
icon: 'lucide:container',
|
|
98
|
+
title: 'Chuẩn cho Docker & Kubernetes',
|
|
99
|
+
desc: 'Là base image phổ biến nhất cho container, dễ dàng triển khai lên mọi nền tảng container hoá.',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
icon: 'lucide:refresh-cw-off',
|
|
103
|
+
title: 'Vá bảo mật không cần khởi động lại',
|
|
104
|
+
desc: 'Hỗ trợ Livepatch giúp cập nhật kernel bảo mật mà không làm gián đoạn dịch vụ đang chạy.',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
icon: 'lucide:book-open',
|
|
108
|
+
title: 'Tài liệu & cộng đồng lớn nhất',
|
|
109
|
+
desc: 'Dễ dàng tìm hướng dẫn, giải pháp cho hầu hết mọi vấn đề gặp phải trong quá trình vận hành.',
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
icon: 'lucide:terminal',
|
|
113
|
+
title: 'Dễ quản trị',
|
|
114
|
+
desc: 'Công cụ quản lý gói (APT, Snap) và cấu hình mạng (Netplan) đơn giản, thân thiện với người mới.',
|
|
115
|
+
},
|
|
116
|
+
]
|
|
117
|
+
</script>
|
|
118
|
+
|
|
119
|
+
<style scoped>
|
|
120
|
+
.ubuntu-reveal {
|
|
121
|
+
animation: ubuntu-card-in 0.6s cubic-bezier(0.16, 1, 0.3, 1) both;
|
|
122
|
+
animation-delay: calc(var(--i, 0) * 100ms);
|
|
123
|
+
animation-play-state: paused;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.ubuntu-revealed .ubuntu-reveal {
|
|
127
|
+
animation-play-state: running;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@keyframes ubuntu-card-in {
|
|
131
|
+
from {
|
|
132
|
+
opacity: 0;
|
|
133
|
+
transform: translateY(24px);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
to {
|
|
137
|
+
opacity: 1;
|
|
138
|
+
transform: translateY(0);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
</style>
|
|
@@ -29,8 +29,8 @@ export const useSolutionApi = () => {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// Tạm thời: dò slug path theo cấp bất kỳ (slug/slug2/slug3), lấy object đầu tiên rồi gọi resume theo profileId
|
|
32
|
-
const getSlugData = async (slug: string) => {
|
|
33
|
-
const list = await handleGetSlugPathView(slug, 'giai-phap')
|
|
32
|
+
const getSlugData = async (slug: string, type: string) => {
|
|
33
|
+
const list = await handleGetSlugPathView(slug, type ||'giai-phap')
|
|
34
34
|
console.log("🚀 ~ getSlugData ~ list:", list)
|
|
35
35
|
|
|
36
36
|
const first = list?.[0]
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
// Dữ liệu giới thiệu các phiên bản Ubuntu đang được hỗ trợ + nhóm sản phẩm/gói dịch vụ triển khai trên đó
|
|
2
|
+
// Mỗi phiên bản có bộ nhóm sản phẩm/gói riêng (giá, cấu hình khác nhau chút) để khi chọn version khác,
|
|
3
|
+
// danh sách gói bên dưới thực sự đổi theo, dễ quan sát thay vì dùng chung 1 bộ dữ liệu.
|
|
4
|
+
export const ubuntuVersions = [
|
|
5
|
+
{
|
|
6
|
+
id: 'ubuntu-24-04',
|
|
7
|
+
version: '24.04 LTS',
|
|
8
|
+
codename: 'Noble Numbat',
|
|
9
|
+
badge: 'Khuyến nghị',
|
|
10
|
+
badgeTone: 'primary',
|
|
11
|
+
recommended: true,
|
|
12
|
+
releaseDate: 'Tháng 4, 2024',
|
|
13
|
+
supportUntil: 'Hỗ trợ đến 2029',
|
|
14
|
+
desc: 'Phiên bản hỗ trợ dài hạn mới nhất, lý tưởng cho môi trường doanh nghiệp và máy chủ sản xuất.',
|
|
15
|
+
groups: [
|
|
16
|
+
{
|
|
17
|
+
id: 'cloud-server',
|
|
18
|
+
name: 'Máy chủ ảo (Cloud Server)',
|
|
19
|
+
icon: 'lucide:server-cog',
|
|
20
|
+
desc: 'Khởi tạo máy chủ ảo chạy Ubuntu 24.04 LTS chỉ trong vài phút, toàn quyền root.',
|
|
21
|
+
packages: [
|
|
22
|
+
{
|
|
23
|
+
id: 'smart-cloud-server-24-04',
|
|
24
|
+
name: 'Smart Cloud Server',
|
|
25
|
+
desc: 'Cloud server phổ thông, dễ mở rộng theo nhu cầu',
|
|
26
|
+
unit: '/tháng',
|
|
27
|
+
price: 109000,
|
|
28
|
+
tags: ['1 vCPU', '2 GB RAM', '40 GB NVMe'],
|
|
29
|
+
features: ['Cài sẵn Ubuntu 24.04 LTS', 'Snapshot theo yêu cầu', 'IP public riêng'],
|
|
30
|
+
highlight: false,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: 'dedicated-cloud-server-24-04',
|
|
34
|
+
name: 'Dedicated Cloud Server',
|
|
35
|
+
desc: 'Tài nguyên riêng, không chia sẻ với khách hàng khác',
|
|
36
|
+
unit: '/tháng',
|
|
37
|
+
price: 950000,
|
|
38
|
+
tags: ['8 vCPU', '16 GB RAM', '200 GB NVMe'],
|
|
39
|
+
features: ['Hiệu năng ổn định 100%', 'Backup tự động hàng ngày', 'Kernel Livepatch bật sẵn'],
|
|
40
|
+
highlight: true,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'linux-cloud-server-24-04',
|
|
44
|
+
name: 'Linux Cloud Server',
|
|
45
|
+
desc: 'Tối ưu riêng cho khối lượng công việc Linux',
|
|
46
|
+
unit: '/tháng',
|
|
47
|
+
price: 269000,
|
|
48
|
+
tags: ['4 vCPU', '8 GB RAM', '100 GB NVMe'],
|
|
49
|
+
features: ['Tối ưu kernel 6.8 cho Ubuntu', 'Hỗ trợ kỹ thuật 24/7'],
|
|
50
|
+
highlight: false,
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'hosting-email',
|
|
56
|
+
name: 'Hosting & Email',
|
|
57
|
+
icon: 'lucide:globe',
|
|
58
|
+
desc: 'Dịch vụ hosting và email chạy trên nền Ubuntu 24.04 LTS, quản trị đơn giản.',
|
|
59
|
+
packages: [
|
|
60
|
+
{
|
|
61
|
+
id: 'web-hosting-24-04',
|
|
62
|
+
name: 'Web Hosting',
|
|
63
|
+
desc: 'Hosting chia sẻ cho website vừa và nhỏ',
|
|
64
|
+
unit: '/tháng',
|
|
65
|
+
price: 55000,
|
|
66
|
+
tags: ['5 GB SSD', '1 domain', 'Free SSL'],
|
|
67
|
+
features: ['PHP 8.3 / MySQL 8 mới nhất', 'Sao lưu hàng tuần'],
|
|
68
|
+
highlight: false,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 'cloud-directadmin-24-04',
|
|
72
|
+
name: 'Cloud DirectAdmin',
|
|
73
|
+
desc: 'Hosting quản trị qua giao diện DirectAdmin',
|
|
74
|
+
unit: '/tháng',
|
|
75
|
+
price: 219000,
|
|
76
|
+
tags: ['20 GB SSD', 'Unlimited domain', 'DirectAdmin'],
|
|
77
|
+
features: ['Giao diện quản trị trực quan', 'Cài đặt ứng dụng 1-click'],
|
|
78
|
+
highlight: true,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'email-hosting-24-04',
|
|
82
|
+
name: 'Email Hosting',
|
|
83
|
+
desc: 'Email doanh nghiệp theo tên miền riêng',
|
|
84
|
+
unit: '/tháng',
|
|
85
|
+
price: 32000,
|
|
86
|
+
tags: ['10 GB/hộp thư', 'Chống spam', 'Webmail'],
|
|
87
|
+
features: ['Đồng bộ đa thiết bị', 'Chống virus, spam tự động'],
|
|
88
|
+
highlight: false,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'advanced-infra',
|
|
94
|
+
name: 'Hạ tầng nâng cao',
|
|
95
|
+
icon: 'lucide:layers',
|
|
96
|
+
desc: 'Giải pháp hạ tầng linh hoạt cho khối lượng công việc lớn trên Ubuntu 24.04 LTS.',
|
|
97
|
+
packages: [
|
|
98
|
+
{
|
|
99
|
+
id: 'elastic-cloud-24-04',
|
|
100
|
+
name: 'Elastic Cloud',
|
|
101
|
+
desc: 'Tự động co giãn tài nguyên theo tải thực tế',
|
|
102
|
+
unit: '/tháng',
|
|
103
|
+
price: 650000,
|
|
104
|
+
tags: ['Auto-scaling', 'Load Balancer', 'SSD NVMe'],
|
|
105
|
+
features: ['Mở rộng tức thời khi tăng traffic', 'Thanh toán theo mức dùng thực tế'],
|
|
106
|
+
highlight: false,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
id: 'private-cloud-24-04',
|
|
110
|
+
name: 'Private Cloud',
|
|
111
|
+
desc: 'Hạ tầng cloud riêng biệt, không chia sẻ tài nguyên',
|
|
112
|
+
unit: '/tháng',
|
|
113
|
+
price: 5200000,
|
|
114
|
+
tags: ['Dedicated hardware', 'Ceph storage', 'SDN riêng'],
|
|
115
|
+
features: ['Cách ly hoàn toàn với khách hàng khác', 'Tùy biến cấu hình theo yêu cầu'],
|
|
116
|
+
highlight: true,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 'gpu-cloud-desktop-24-04',
|
|
120
|
+
name: 'GPU Cloud Desktop',
|
|
121
|
+
desc: 'Máy trạm ảo có GPU cho xử lý đồ hoạ, AI',
|
|
122
|
+
unit: '/tháng',
|
|
123
|
+
price: 2190000,
|
|
124
|
+
tags: ['GPU rời', '16 GB RAM', 'Ubuntu Desktop 24.04'],
|
|
125
|
+
features: ['Truy cập từ xa mọi lúc', 'Cấu hình GPU theo nhu cầu'],
|
|
126
|
+
highlight: false,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
id: 'ubuntu-23-10',
|
|
134
|
+
version: '23.10',
|
|
135
|
+
codename: 'Mantic Minotaur',
|
|
136
|
+
badge: 'Ổn định',
|
|
137
|
+
badgeTone: 'amber',
|
|
138
|
+
recommended: false,
|
|
139
|
+
releaseDate: 'Tháng 10, 2023',
|
|
140
|
+
supportUntil: 'Hỗ trợ đến 07/2024',
|
|
141
|
+
desc: 'Phiên bản trung gian với các tính năng mới nhất, phù hợp cho người dùng muốn trải nghiệm đầu tiên.',
|
|
142
|
+
groups: [
|
|
143
|
+
{
|
|
144
|
+
id: 'cloud-server',
|
|
145
|
+
name: 'Máy chủ ảo (Cloud Server)',
|
|
146
|
+
icon: 'lucide:server-cog',
|
|
147
|
+
desc: 'Khởi tạo máy chủ ảo chạy Ubuntu 23.10 chỉ trong vài phút, toàn quyền root.',
|
|
148
|
+
packages: [
|
|
149
|
+
{
|
|
150
|
+
id: 'smart-cloud-server-23-10',
|
|
151
|
+
name: 'Smart Cloud Server',
|
|
152
|
+
desc: 'Cloud server phổ thông, dùng thử tính năng mới trước bản LTS',
|
|
153
|
+
unit: '/tháng',
|
|
154
|
+
price: 99000,
|
|
155
|
+
tags: ['1 vCPU', '2 GB RAM', '40 GB SSD'],
|
|
156
|
+
features: ['Cài sẵn Ubuntu 23.10', 'Snapshot theo yêu cầu'],
|
|
157
|
+
highlight: false,
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
id: 'dedicated-cloud-server-23-10',
|
|
161
|
+
name: 'Dedicated Cloud Server',
|
|
162
|
+
desc: 'Tài nguyên riêng, phù hợp môi trường staging',
|
|
163
|
+
unit: '/tháng',
|
|
164
|
+
price: 890000,
|
|
165
|
+
tags: ['8 vCPU', '16 GB RAM', '200 GB SSD'],
|
|
166
|
+
features: ['Hiệu năng ổn định 100%', 'Backup tự động hàng ngày'],
|
|
167
|
+
highlight: true,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: 'linux-cloud-server-23-10',
|
|
171
|
+
name: 'Linux Cloud Server',
|
|
172
|
+
desc: 'Trải nghiệm kernel và gói phần mềm mới nhất',
|
|
173
|
+
unit: '/tháng',
|
|
174
|
+
price: 249000,
|
|
175
|
+
tags: ['4 vCPU', '8 GB RAM', '100 GB SSD'],
|
|
176
|
+
features: ['Kernel 6.5 mới nhất', 'Hỗ trợ kỹ thuật giờ hành chính'],
|
|
177
|
+
highlight: false,
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: 'hosting-email',
|
|
183
|
+
name: 'Hosting & Email',
|
|
184
|
+
icon: 'lucide:globe',
|
|
185
|
+
desc: 'Dịch vụ hosting và email chạy trên nền Ubuntu 23.10.',
|
|
186
|
+
packages: [
|
|
187
|
+
{
|
|
188
|
+
id: 'web-hosting-23-10',
|
|
189
|
+
name: 'Web Hosting',
|
|
190
|
+
desc: 'Hosting chia sẻ cho website vừa và nhỏ',
|
|
191
|
+
unit: '/tháng',
|
|
192
|
+
price: 49000,
|
|
193
|
+
tags: ['5 GB SSD', '1 domain', 'Free SSL'],
|
|
194
|
+
features: ['PHP 8.2 / MySQL 8', 'Sao lưu hàng tuần'],
|
|
195
|
+
highlight: false,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: 'cloud-directadmin-23-10',
|
|
199
|
+
name: 'Cloud DirectAdmin',
|
|
200
|
+
desc: 'Hosting quản trị qua giao diện DirectAdmin',
|
|
201
|
+
unit: '/tháng',
|
|
202
|
+
price: 199000,
|
|
203
|
+
tags: ['20 GB SSD', '10 domain', 'DirectAdmin'],
|
|
204
|
+
features: ['Giao diện quản trị trực quan', 'Cài đặt ứng dụng 1-click'],
|
|
205
|
+
highlight: true,
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
id: 'email-hosting-23-10',
|
|
209
|
+
name: 'Email Hosting',
|
|
210
|
+
desc: 'Email doanh nghiệp theo tên miền riêng',
|
|
211
|
+
unit: '/tháng',
|
|
212
|
+
price: 29000,
|
|
213
|
+
tags: ['10 GB/hộp thư', 'Chống spam', 'Webmail'],
|
|
214
|
+
features: ['Đồng bộ đa thiết bị', 'Chống virus, spam tự động'],
|
|
215
|
+
highlight: false,
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
id: 'advanced-infra',
|
|
221
|
+
name: 'Hạ tầng nâng cao',
|
|
222
|
+
icon: 'lucide:layers',
|
|
223
|
+
desc: 'Giải pháp hạ tầng linh hoạt cho khối lượng công việc lớn trên Ubuntu 23.10.',
|
|
224
|
+
packages: [
|
|
225
|
+
{
|
|
226
|
+
id: 'elastic-cloud-23-10',
|
|
227
|
+
name: 'Elastic Cloud',
|
|
228
|
+
desc: 'Tự động co giãn tài nguyên theo tải thực tế',
|
|
229
|
+
unit: '/tháng',
|
|
230
|
+
price: 590000,
|
|
231
|
+
tags: ['Auto-scaling', 'Load Balancer', 'SSD'],
|
|
232
|
+
features: ['Mở rộng tức thời khi tăng traffic'],
|
|
233
|
+
highlight: false,
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
id: 'private-cloud-23-10',
|
|
237
|
+
name: 'Private Cloud',
|
|
238
|
+
desc: 'Hạ tầng cloud riêng biệt, không chia sẻ tài nguyên',
|
|
239
|
+
unit: '/tháng',
|
|
240
|
+
price: 4900000,
|
|
241
|
+
tags: ['Dedicated hardware', 'Ceph storage'],
|
|
242
|
+
features: ['Cách ly hoàn toàn với khách hàng khác'],
|
|
243
|
+
highlight: true,
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
id: 'gpu-cloud-desktop-23-10',
|
|
247
|
+
name: 'GPU Cloud Desktop',
|
|
248
|
+
desc: 'Máy trạm ảo có GPU cho xử lý đồ hoạ, AI',
|
|
249
|
+
unit: '/tháng',
|
|
250
|
+
price: 1990000,
|
|
251
|
+
tags: ['GPU rời', '16 GB RAM', 'Ubuntu Desktop 23.10'],
|
|
252
|
+
features: ['Truy cập từ xa mọi lúc'],
|
|
253
|
+
highlight: false,
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
id: 'ubuntu-22-04',
|
|
261
|
+
version: '22.04 LTS',
|
|
262
|
+
codename: 'Jammy Jellyfish',
|
|
263
|
+
badge: 'LTS',
|
|
264
|
+
badgeTone: 'slate',
|
|
265
|
+
recommended: false,
|
|
266
|
+
releaseDate: 'Tháng 4, 2022',
|
|
267
|
+
supportUntil: 'Hỗ trợ đến 2027',
|
|
268
|
+
desc: 'Phiên bản LTS trước, vẫn được hỗ trợ đầy đủ và được nhiều tổ chức tin dùng.',
|
|
269
|
+
groups: [
|
|
270
|
+
{
|
|
271
|
+
id: 'cloud-server',
|
|
272
|
+
name: 'Máy chủ ảo (Cloud Server)',
|
|
273
|
+
icon: 'lucide:server-cog',
|
|
274
|
+
desc: 'Khởi tạo máy chủ ảo chạy Ubuntu 22.04 LTS, phù hợp hệ thống đã kiểm chứng lâu dài.',
|
|
275
|
+
packages: [
|
|
276
|
+
{
|
|
277
|
+
id: 'smart-cloud-server-22-04',
|
|
278
|
+
name: 'Smart Cloud Server',
|
|
279
|
+
desc: 'Cloud server phổ thông, giá ưu đãi cho hệ thống cũ',
|
|
280
|
+
unit: '/tháng',
|
|
281
|
+
price: 89000,
|
|
282
|
+
tags: ['1 vCPU', '2 GB RAM', '40 GB SSD'],
|
|
283
|
+
features: ['Cài sẵn Ubuntu 22.04 LTS', 'Snapshot theo yêu cầu'],
|
|
284
|
+
highlight: false,
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
id: 'dedicated-cloud-server-22-04',
|
|
288
|
+
name: 'Dedicated Cloud Server',
|
|
289
|
+
desc: 'Tài nguyên riêng, tương thích phần mềm legacy',
|
|
290
|
+
unit: '/tháng',
|
|
291
|
+
price: 790000,
|
|
292
|
+
tags: ['8 vCPU', '16 GB RAM', '200 GB SSD'],
|
|
293
|
+
features: ['Hiệu năng ổn định 100%', 'Backup tự động hàng ngày'],
|
|
294
|
+
highlight: true,
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 'linux-cloud-server-22-04',
|
|
298
|
+
name: 'Linux Cloud Server',
|
|
299
|
+
desc: 'Đã kiểm chứng ổn định qua nhiều năm vận hành',
|
|
300
|
+
unit: '/tháng',
|
|
301
|
+
price: 219000,
|
|
302
|
+
tags: ['4 vCPU', '8 GB RAM', '100 GB SSD'],
|
|
303
|
+
features: ['Kernel 5.15 LTS ổn định', 'Hỗ trợ kỹ thuật 24/7'],
|
|
304
|
+
highlight: false,
|
|
305
|
+
},
|
|
306
|
+
],
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: 'hosting-email',
|
|
310
|
+
name: 'Hosting & Email',
|
|
311
|
+
icon: 'lucide:globe',
|
|
312
|
+
desc: 'Dịch vụ hosting và email chạy trên nền Ubuntu 22.04 LTS.',
|
|
313
|
+
packages: [
|
|
314
|
+
{
|
|
315
|
+
id: 'web-hosting-22-04',
|
|
316
|
+
name: 'Web Hosting',
|
|
317
|
+
desc: 'Hosting chia sẻ cho website vừa và nhỏ',
|
|
318
|
+
unit: '/tháng',
|
|
319
|
+
price: 45000,
|
|
320
|
+
tags: ['5 GB SSD', '1 domain', 'Free SSL'],
|
|
321
|
+
features: ['PHP 8.1 / MySQL 8', 'Sao lưu hàng tuần'],
|
|
322
|
+
highlight: false,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
id: 'cloud-directadmin-22-04',
|
|
326
|
+
name: 'Cloud DirectAdmin',
|
|
327
|
+
desc: 'Hosting quản trị qua giao diện DirectAdmin',
|
|
328
|
+
unit: '/tháng',
|
|
329
|
+
price: 179000,
|
|
330
|
+
tags: ['20 GB SSD', 'Unlimited domain', 'DirectAdmin'],
|
|
331
|
+
features: ['Giao diện quản trị trực quan', 'Cài đặt ứng dụng 1-click'],
|
|
332
|
+
highlight: true,
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
id: 'email-hosting-22-04',
|
|
336
|
+
name: 'Email Hosting',
|
|
337
|
+
desc: 'Email doanh nghiệp theo tên miền riêng',
|
|
338
|
+
unit: '/tháng',
|
|
339
|
+
price: 25000,
|
|
340
|
+
tags: ['10 GB/hộp thư', 'Chống spam', 'Webmail'],
|
|
341
|
+
features: ['Đồng bộ đa thiết bị', 'Chống virus, spam tự động'],
|
|
342
|
+
highlight: false,
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
id: 'advanced-infra',
|
|
348
|
+
name: 'Hạ tầng nâng cao',
|
|
349
|
+
icon: 'lucide:layers',
|
|
350
|
+
desc: 'Giải pháp hạ tầng linh hoạt, đã kiểm chứng ổn định trên Ubuntu 22.04 LTS.',
|
|
351
|
+
packages: [
|
|
352
|
+
{
|
|
353
|
+
id: 'elastic-cloud-22-04',
|
|
354
|
+
name: 'Elastic Cloud',
|
|
355
|
+
desc: 'Tự động co giãn tài nguyên theo tải thực tế',
|
|
356
|
+
unit: '/tháng',
|
|
357
|
+
price: 530000,
|
|
358
|
+
tags: ['Auto-scaling', 'Load Balancer', 'SSD'],
|
|
359
|
+
features: ['Mở rộng tức thời khi tăng traffic'],
|
|
360
|
+
highlight: false,
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
id: 'private-cloud-22-04',
|
|
364
|
+
name: 'Private Cloud',
|
|
365
|
+
desc: 'Hạ tầng cloud riêng biệt, không chia sẻ tài nguyên',
|
|
366
|
+
unit: '/tháng',
|
|
367
|
+
price: 4500000,
|
|
368
|
+
tags: ['Dedicated hardware', 'Ceph storage'],
|
|
369
|
+
features: ['Cách ly hoàn toàn với khách hàng khác'],
|
|
370
|
+
highlight: true,
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
id: 'gpu-cloud-desktop-22-04',
|
|
374
|
+
name: 'GPU Cloud Desktop',
|
|
375
|
+
desc: 'Máy trạm ảo có GPU cho xử lý đồ hoạ, AI',
|
|
376
|
+
unit: '/tháng',
|
|
377
|
+
price: 1790000,
|
|
378
|
+
tags: ['GPU rời', '16 GB RAM', 'Ubuntu Desktop 22.04'],
|
|
379
|
+
features: ['Truy cập từ xa mọi lúc'],
|
|
380
|
+
highlight: false,
|
|
381
|
+
},
|
|
382
|
+
],
|
|
383
|
+
},
|
|
384
|
+
],
|
|
385
|
+
},
|
|
386
|
+
]
|
|
@@ -8,12 +8,12 @@ const slug = computed(() => route.params.slug as string)
|
|
|
8
8
|
|
|
9
9
|
const { data } = await useAsyncData(
|
|
10
10
|
`slug-${slug.value}`,
|
|
11
|
-
() => getSlugData(slug.value),
|
|
11
|
+
() => getSlugData(slug.value, 'giai-phap'),
|
|
12
12
|
{ server: true }
|
|
13
13
|
)
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
|
-
<template>
|
|
16
|
+
<template>{{ data }}
|
|
17
17
|
<DynamicPageSections
|
|
18
18
|
:field-resumes="data?.resumeData?.fieldResumes"
|
|
19
19
|
:target-c-t-a="data?.productData?.targetCTA"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
definePageMeta({ layout: 'default' })
|
|
3
|
+
|
|
4
|
+
const route = useRoute()
|
|
5
|
+
const { getSlugData } = useSolutionApi()
|
|
6
|
+
|
|
7
|
+
const slug = computed(() => route.params.slug as string)
|
|
8
|
+
|
|
9
|
+
const { data } = await useAsyncData(
|
|
10
|
+
`slug-${slug.value}`,
|
|
11
|
+
() => getSlugData(slug.value, 'gioi-thieu-template'),
|
|
12
|
+
{ server: true }
|
|
13
|
+
)
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<template>
|
|
17
|
+
<DynamicPageSections
|
|
18
|
+
:field-resumes="data?.resumeData?.fieldResumes"
|
|
19
|
+
:target-c-t-a="data?.productData?.targetCTA"
|
|
20
|
+
:slug="data?.productData?.slug || slug"
|
|
21
|
+
/>
|
|
22
|
+
</template>
|
package/package.json
CHANGED
/package/app/layers/solution/app/pages/tu-van/{khoa-hoc-proxmox.vue → khoa-hoc-proxmox.vue.disabled}
RENAMED
|
File without changes
|