nuxt-layer-core 2.0.1

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.
Files changed (78) hide show
  1. package/.claude/settings.local.json +8 -0
  2. package/app/app.config.ts +5 -0
  3. package/app/app.vue +11 -0
  4. package/app/assets/css/main.css +113 -0
  5. package/app/components/.gitkeep +0 -0
  6. package/app/components/ui/sonner/Sonner.vue +62 -0
  7. package/app/components/ui/sonner/index.ts +1 -0
  8. package/app/composables/.gitkeep +0 -0
  9. package/app/layers/solution/app/assets/proxmox-css/main.css +89 -0
  10. package/app/layers/solution/app/assets/proxmox-css/proxmox-utils.css +68 -0
  11. package/app/layers/solution/app/components/ClusterDiagram.vue +72 -0
  12. package/app/layers/solution/app/components/CoursesSection.vue +246 -0
  13. package/app/layers/solution/app/components/CtaSection.vue +329 -0
  14. package/app/layers/solution/app/components/FeaturesSection.vue +67 -0
  15. package/app/layers/solution/app/components/HeroSection.vue +144 -0
  16. package/app/layers/solution/app/components/PricingPlansSection.vue +434 -0
  17. package/app/layers/solution/app/components/RegistrationForm.vue +256 -0
  18. package/app/layers/solution/app/components/TestimonialsSection.vue +58 -0
  19. package/app/layers/solution/app/components/TheFooter.vue +61 -0
  20. package/app/layers/solution/app/components/TheHeader.vue +189 -0
  21. package/app/layers/solution/app/components/proxmox/AppIcon.vue +45 -0
  22. package/app/layers/solution/app/components/proxmox/ComparisonSection.vue +54 -0
  23. package/app/layers/solution/app/components/proxmox/FaqSection.vue +58 -0
  24. package/app/layers/solution/app/components/proxmox/HciOverviewSection.vue +37 -0
  25. package/app/layers/solution/app/components/proxmox/HeroSection.vue +74 -0
  26. package/app/layers/solution/app/components/proxmox/TestimonialsSection.vue +44 -0
  27. package/app/layers/solution/app/components/proxmox/TrainingBenefitsSection.vue +37 -0
  28. package/app/layers/solution/app/components/proxmox/VeFeaturesSection.vue +55 -0
  29. package/app/layers/solution/app/composables/useActiveSection.ts +47 -0
  30. package/app/layers/solution/app/composables/useAuthApi.ts +244 -0
  31. package/app/layers/solution/app/composables/useAuthState.ts +16 -0
  32. package/app/layers/solution/app/composables/useCookie.ts +79 -0
  33. package/app/layers/solution/app/composables/useCookieHelper.ts +81 -0
  34. package/app/layers/solution/app/composables/useCrmApi.ts +32 -0
  35. package/app/layers/solution/app/composables/useDynamicCollection.ts +23 -0
  36. package/app/layers/solution/app/composables/useScrollAnimate.ts +40 -0
  37. package/app/layers/solution/app/composables/useScrollToSection.ts +13 -0
  38. package/app/layers/solution/app/composables/useSolutionApi.ts +55 -0
  39. package/app/layers/solution/app/composables/useToast.ts +14 -0
  40. package/app/layers/solution/app/data/proxmox-content.ts +158 -0
  41. package/app/layers/solution/app/images/Proxmox HCI.png +0 -0
  42. package/app/layers/solution/app/images/image_from_https_hercules_cdn.com_file_6dztkvkfnip0ud23tzzvu57c.png +0 -0
  43. package/app/layers/solution/app/layouts/default.vue +5 -0
  44. package/app/layers/solution/app/nuxt.config.ts +9 -0
  45. package/app/layers/solution/app/pages/cap-nhat-thong-tin/index.vue +302 -0
  46. package/app/layers/solution/app/pages/dang-ky/index.vue +627 -0
  47. package/app/layers/solution/app/pages/dang-nhap/index.vue +208 -0
  48. package/app/layers/solution/app/pages/doi-mat-khau/index.vue +237 -0
  49. package/app/layers/solution/app/pages/giai-phap-proxmox/[slug]/index.vue +37 -0
  50. package/app/layers/solution/app/pages/giai-phap-proxmox/[slug]/proxmox-hci/index.vue +45 -0
  51. package/app/layers/solution/app/pages/giai-phap-proxmox/dang-ky-khoa-hoc/[slug].vue +131 -0
  52. package/app/layers/solution/app/pages/quen-mat-khau/index.vue +136 -0
  53. package/app/layers/solution/app/pages/xac-thuc/index.vue +320 -0
  54. package/app/layers/solution/app/plugins/reveal.ts +56 -0
  55. package/app/layers/solution/app/public/images/image_from_https_hercules_cdn.com_file_6dztkvkfnip0ud23tzzvu57c.png +0 -0
  56. package/app/layers/solution/app/public/images/logo-lvs-1300x330.png +0 -0
  57. package/app/layouts/auth.vue +71 -0
  58. package/app/lib/utils.ts +7 -0
  59. package/app/middleware/.gitkeep +0 -0
  60. package/app/modules/layer-route-priority.ts +60 -0
  61. package/app/pages/index.vue +9 -0
  62. package/app/pages/san-pham-proxmox.vue +8 -0
  63. package/app/plugins/.gitkeep +0 -0
  64. package/app/plugins/sdk.ts +29 -0
  65. package/app/stores/.gitkeep +0 -0
  66. package/app/types/sdk.d.ts +15 -0
  67. package/components.json +24 -0
  68. package/nuxt.config.ts +104 -0
  69. package/package.json +52 -0
  70. package/public/.gitkeep +0 -0
  71. package/server/api/.gitkeep +0 -0
  72. package/server/utils/.gitkeep +0 -0
  73. package/tailwind.config.js +96 -0
  74. package/tsconfig.base.json +18 -0
  75. package/tsconfig.json +18 -0
  76. package/website-longvan-1.1.6.tgz +0 -0
  77. package/website-longvan-1.1.7.tgz +0 -0
  78. package/website-longvan-1.1.8.tgz +0 -0
@@ -0,0 +1,58 @@
1
+ <script setup lang="ts">
2
+ import { faqItems } from "../../data/proxmox-content"
3
+
4
+ const openIndex = ref<number | null>(0)
5
+
6
+ function toggle(i: number) {
7
+ openIndex.value = openIndex.value === i ? null : i
8
+ }
9
+ </script>
10
+
11
+ <template>
12
+ <section class="bg-[#F7F9FB] py-20 sm:py-28">
13
+ <div class="mx-auto max-w-3xl px-6 lg:px-8">
14
+ <div class="text-center">
15
+ <div v-reveal class="inline-flex items-center rounded-full bg-blue-50 px-4 py-1.5 text-sm font-medium text-blue-600 ring-1 ring-inset ring-blue-100">
16
+ FAQ
17
+ </div>
18
+ <h2 v-reveal="{ delay: 60 }" class="mt-5 text-3xl font-extrabold tracking-tight text-slate-900 sm:text-4xl">
19
+ Câu hỏi thường gặp
20
+ </h2>
21
+ </div>
22
+
23
+ <div class="mt-12 space-y-3">
24
+ <div
25
+ v-for="(item, i) in faqItems"
26
+ :key="item.question"
27
+ v-reveal="{ delay: 80 + i * 60 }"
28
+ class="overflow-hidden rounded-xl border border-slate-200 bg-white"
29
+ >
30
+ <button
31
+ type="button"
32
+ class="flex w-full items-center justify-between gap-4 px-6 py-4 text-left text-[15px] font-semibold text-slate-800"
33
+ :aria-expanded="openIndex === i"
34
+ @click="toggle(i)"
35
+ >
36
+ {{ item.question }}
37
+ <ProxmoxAppIcon
38
+ name="chevronDown"
39
+ class="h-4 w-4 shrink-0 text-slate-400 transition-transform duration-300"
40
+ :class="{ 'rotate-180 text-blue-600': openIndex === i }"
41
+ />
42
+ </button>
43
+
44
+ <div
45
+ class="grid transition-all duration-300 ease-in-out"
46
+ :style="{ gridTemplateRows: openIndex === i ? '1fr' : '0fr' }"
47
+ >
48
+ <div class="overflow-hidden">
49
+ <p class="px-6 pb-5 text-sm leading-relaxed text-slate-500">
50
+ {{ item.answer }}
51
+ </p>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ </section>
58
+ </template>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { hciOverviewCards } from "../../data/proxmox-content"
3
+ </script>
4
+
5
+ <template>
6
+ <section class="bg-[#F7F9FB] py-20 sm:py-28">
7
+ <div class="mx-auto max-w-6xl px-6 lg:px-8">
8
+ <div class="mx-auto max-w-3xl text-center">
9
+ <div v-reveal class="inline-flex items-center rounded-full bg-blue-50 px-4 py-1.5 text-sm font-medium text-blue-600 ring-1 ring-inset ring-blue-100">
10
+ HCI là gì?
11
+ </div>
12
+ <h2 v-reveal="{ delay: 60 }" class="mt-5 text-3xl font-extrabold tracking-tight text-slate-900 sm:text-4xl">
13
+ Proxmox HCI — Hạ tầng hội tụ
14
+ <span class="text-blue-600">dựa trên Proxmox VE</span>
15
+ </h2>
16
+ <p v-reveal="{ delay: 120 }" class="mt-5 leading-relaxed text-slate-600">
17
+ HCI (Hyper-Converged Infrastructure) hợp nhất compute, storage và network vào một platform phần mềm duy nhất — loại bỏ SAN riêng biệt, đơn giản hóa vận hành và giảm chi phí đáng kể.
18
+ </p>
19
+ </div>
20
+
21
+ <div class="mt-14 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
22
+ <div
23
+ v-for="(card, i) in hciOverviewCards"
24
+ :key="card.title"
25
+ v-reveal="{ delay: 100 + i * 70 }"
26
+ class="rounded-2xl border border-slate-200 bg-white p-7 transition hover:-translate-y-1 hover:border-blue-200 hover:shadow-lg hover:shadow-blue-900/5"
27
+ >
28
+ <span class="flex h-11 w-11 items-center justify-center rounded-xl bg-blue-50 text-blue-600">
29
+ <ProxmoxAppIcon :name="card.icon" class="h-5 w-5" />
30
+ </span>
31
+ <p class="mt-4 font-semibold text-slate-900">{{ card.title }}</p>
32
+ <p class="mt-2 text-sm leading-relaxed text-slate-500">{{ card.desc }}</p>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </section>
37
+ </template>
@@ -0,0 +1,74 @@
1
+ <script setup lang="ts">
2
+ import { heroStats } from "../../data/proxmox-content"
3
+ const { scrollTo } = useScrollToSection()
4
+ </script>
5
+
6
+ <template>
7
+ <section id="san-pham" class="relative overflow-hidden bg-gradient-to-b from-blue-50/60 via-white to-white">
8
+ <div
9
+ class="bg-grid pointer-events-none absolute inset-0 [mask-image:radial-gradient(ellipse_60%_60%_at_50%_0%,black,transparent)]" />
10
+
11
+ <div class="relative mx-auto max-w-7xl px-6 pt-20 pb-16 sm:pt-28 sm:pb-24 lg:px-8">
12
+ <div class="grid grid-cols-1 items-center gap-10 lg:grid-cols-2 lg:gap-12">
13
+ <!-- Left: copy -->
14
+ <div>
15
+ <div v-reveal
16
+ class="inline-flex items-center rounded-full bg-blue-50 px-4 py-1.5 text-sm font-medium text-blue-600 ring-1 ring-inset ring-blue-100">
17
+ Giải pháp Hạ tầng Siêu hội tụ hàng đầu
18
+ </div>
19
+
20
+ <h1 v-reveal="{ delay: 80 }"
21
+ class="mt-6 text-4xl font-extrabold tracking-tight text-slate-900 sm:text-5xl lg:text-[3.4rem] lg:leading-[1.1]">
22
+ Proxmox HCI —
23
+ <span class="block text-blue-600">Hạ tầng siêu hội tụ</span>
24
+ toàn diện
25
+ </h1>
26
+
27
+ <p v-reveal="{ delay: 160 }" class="mt-6 max-w-xl text-lg leading-relaxed text-slate-600">
28
+ Tích hợp KVM, Ceph Storage, SDN và HA Cluster vào một nền tảng duy nhất. Giải pháp hoàn hảo giúp doanh
29
+ nghiệp tối ưu chi phí, nâng cao hiệu suất và đảm bảo tính sẵn sàng cao.
30
+ </p>
31
+
32
+ <a v-reveal="{ delay: 220 }" href="#lien-he" @click.prevent="scrollTo('lien-he')"
33
+ class="mt-5 inline-flex items-center gap-2 text-[15px] font-medium text-blue-600 hover:text-blue-700">
34
+ <ProxmoxAppIcon name="calendar" class="h-4 w-4" />
35
+ Triển khai dễ dàng, mở rộng linh hoạt. Nhận tư vấn giải pháp từ chuyên gia Long Vân.
36
+ </a>
37
+
38
+ <div v-reveal="{ delay: 280 }" class="mt-8 flex flex-wrap items-center gap-4">
39
+ <a href="#lien-he" @click.prevent="scrollTo('lien-he')"
40
+ class="inline-flex items-center gap-2 rounded-[10px] bg-blue-600 px-6 py-3.5 text-[15px] font-semibold text-white shadow-sm shadow-blue-600/20 transition hover:bg-blue-700">
41
+ Nhận tư vấn triển khai
42
+ <ProxmoxAppIcon name="arrowRight" class="h-4 w-4" />
43
+ </a>
44
+
45
+ </div>
46
+
47
+ <dl class="mt-9 grid grid-cols-2 border-t border-slate-200 pt-6 sm:grid-cols-4">
48
+ <div v-for="(stat, i) in heroStats" :key="stat.label" class="px-3 first:pl-0 sm:px-5" :class="[
49
+ i === 2 ? 'mt-6 sm:mt-0' : '',
50
+ i === 3 ? 'mt-6 sm:mt-0' : '',
51
+ i > 0 ? 'sm:border-l sm:border-slate-200' : ''
52
+ ]">
53
+ <dt class="text-2xl font-extrabold tracking-tight text-slate-900">
54
+ {{ stat.value }}
55
+ </dt>
56
+
57
+ <dd class="mt-1 max-w-[110px] text-xs leading-5 text-slate-500">
58
+ {{ stat.label }}
59
+ </dd>
60
+ </div>
61
+ </dl>
62
+ </div>
63
+
64
+ <!-- Right: image with floating cards -->
65
+ <div v-reveal="{ type: 'right', delay: 160 }" class="relative flex h-full items-center">
66
+ <div class="w-full overflow-hidden rounded-3xl shadow-2xl shadow-blue-900/10 ring-1 ring-black/5">
67
+ <img src="../../images/Proxmox HCI.png" alt="Datacenter server racks"
68
+ class="block h-auto w-full object-contain" />
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </section>
74
+ </template>
@@ -0,0 +1,44 @@
1
+ <script setup lang="ts">
2
+ import { testimonials } from "../../data/proxmox-content"
3
+ </script>
4
+
5
+ <template>
6
+ <section id="khach-hang" class="bg-white py-20 sm:py-28">
7
+ <div class="mx-auto max-w-6xl px-6 lg:px-8">
8
+ <div class="mx-auto max-w-3xl text-center">
9
+ <div v-reveal class="inline-flex items-center rounded-full bg-blue-50 px-4 py-1.5 text-sm font-medium text-blue-600 ring-1 ring-inset ring-blue-100">
10
+ Học viên nói gì
11
+ </div>
12
+ <h2 v-reveal="{ delay: 60 }" class="mt-5 text-3xl font-extrabold tracking-tight text-slate-900 sm:text-4xl">
13
+ Được tư vấn đúng khóa,
14
+ <span class="text-blue-600">học đúng thứ cần dùng</span>
15
+ </h2>
16
+ </div>
17
+
18
+ <div class="mt-14 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
19
+ <figure
20
+ v-for="(t, i) in testimonials"
21
+ :key="t.name + i"
22
+ v-reveal="{ delay: 100 + i * 90 }"
23
+ class="rounded-2xl border border-slate-200 bg-white p-7"
24
+ >
25
+ <div class="flex gap-0.5 text-amber-400">
26
+ <ProxmoxAppIcon v-for="n in 5" :key="n" name="star" class="h-4 w-4 fill-current" />
27
+ </div>
28
+ <blockquote class="mt-4 text-[15px] italic leading-relaxed text-slate-600">
29
+ “{{ t.quote }}”
30
+ </blockquote>
31
+ <figcaption class="mt-6 flex items-center gap-3 border-t border-slate-100 pt-5">
32
+ <span class="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-blue-100 text-xs font-bold text-blue-600">
33
+ HV
34
+ </span>
35
+ <div class="text-sm">
36
+ <p class="font-semibold text-slate-900">{{ t.name }}</p>
37
+ <p class="text-slate-500">{{ t.role }}</p>
38
+ </div>
39
+ </figcaption>
40
+ </figure>
41
+ </div>
42
+ </div>
43
+ </section>
44
+ </template>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ import { trainingBenefits } from "../../data/proxmox-content"
3
+ </script>
4
+
5
+ <template>
6
+ <section class="bg-[#F7F9FB] py-20 sm:py-28">
7
+ <div class="mx-auto max-w-6xl px-6 lg:px-8">
8
+ <div class="mx-auto max-w-3xl text-center">
9
+ <div v-reveal class="inline-flex items-center rounded-full bg-blue-50 px-4 py-1.5 text-sm font-medium text-blue-600 ring-1 ring-inset ring-blue-100">
10
+ Lợi ích đào tạo
11
+ </div>
12
+ <h2 v-reveal="{ delay: 60 }" class="mt-5 text-3xl font-extrabold tracking-tight text-slate-900 sm:text-4xl">
13
+ Vì sao nên tham gia
14
+ <span class="text-blue-600">đào tạo Proxmox VE?</span>
15
+ </h2>
16
+ <p v-reveal="{ delay: 120 }" class="mt-5 leading-relaxed text-slate-600">
17
+ Đầu tư một lần vào đào tạo bài bản giúp bạn tối ưu năng lực vận hành, cắt giảm chi phí hạ tầng và tạo bước đệm bứt phá trên con đường sự nghiệp.
18
+ </p>
19
+ </div>
20
+
21
+ <div class="mt-14 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3">
22
+ <div
23
+ v-for="(item, i) in trainingBenefits"
24
+ :key="item.title"
25
+ v-reveal="{ delay: 100 + i * 70 }"
26
+ class="rounded-2xl border border-slate-200 bg-white p-7 transition hover:-translate-y-1 hover:border-blue-200 hover:shadow-lg hover:shadow-blue-900/5"
27
+ >
28
+ <span class="flex h-11 w-11 items-center justify-center rounded-xl bg-blue-50 text-blue-600">
29
+ <ProxmoxAppIcon :name="item.icon" class="h-5 w-5" />
30
+ </span>
31
+ <p class="mt-4 font-semibold text-slate-900">{{ item.title }}</p>
32
+ <p class="mt-2 text-sm leading-relaxed text-slate-500">{{ item.desc }}</p>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </section>
37
+ </template>
@@ -0,0 +1,55 @@
1
+ <script setup lang="ts">
2
+ import { veFeatureList, veFeatureCards } from "../../data/proxmox-content"
3
+ </script>
4
+
5
+ <template>
6
+ <section id="giai-phap" class="bg-white mx-auto max-w-7xl px-6 py-20 sm:py-28 lg:px-8">
7
+ <div class="grid grid-cols-1 items-start gap-16 lg:grid-cols-2">
8
+ <!-- Left copy -->
9
+ <div>
10
+ <div v-reveal class="inline-flex items-center rounded-full bg-blue-50 px-4 py-1.5 text-sm font-medium text-blue-600 ring-1 ring-inset ring-blue-100">
11
+ Nền tảng ảo hóa
12
+ </div>
13
+
14
+ <h2 v-reveal="{ delay: 60 }" class="mt-5 text-3xl font-extrabold tracking-tight text-slate-900 sm:text-4xl sm:leading-tight">
15
+ Proxmox VE — Nền tảng ảo hóa
16
+ <span class="text-blue-600">hàng đầu thế giới</span>
17
+ </h2>
18
+
19
+ <p v-reveal="{ delay: 120 }" class="mt-5 leading-relaxed text-slate-600">
20
+ Proxmox VE là nền tảng ảo hóa mã nguồn mở mạnh mẽ, cho phép doanh nghiệp triển khai và quản lý VM & Container tập trung trên một giao diện web duy nhất. Được hàng nghìn doanh nghiệp toàn cầu tin dùng thay thế VMware vSphere với chi phí gần như bằng 0.
21
+ </p>
22
+
23
+ <ul class="mt-7 space-y-4">
24
+ <li
25
+ v-for="(item, i) in veFeatureList"
26
+ :key="item.text"
27
+ v-reveal="{ delay: 160 + i * 60 }"
28
+ class="flex items-center gap-3"
29
+ >
30
+ <span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-blue-50 text-blue-600">
31
+ <ProxmoxAppIcon :name="item.icon" class="h-4 w-4" />
32
+ </span>
33
+ <span class="text-[15px] text-slate-700">{{ item.text }}</span>
34
+ </li>
35
+ </ul>
36
+ </div>
37
+
38
+ <!-- Right card grid -->
39
+ <div class="grid grid-cols-2 gap-5">
40
+ <div
41
+ v-for="(card, i) in veFeatureCards"
42
+ :key="card.title"
43
+ v-reveal="{ type: 'scale', delay: 100 + i * 70 }"
44
+ class="rounded-2xl border border-slate-200 bg-slate-50/60 p-6 transition hover:-translate-y-1 hover:border-blue-200 hover:bg-white hover:shadow-lg hover:shadow-blue-900/5"
45
+ >
46
+ <span class="flex h-11 w-11 items-center justify-center rounded-xl bg-white text-blue-600 shadow-sm ring-1 ring-slate-200">
47
+ <ProxmoxAppIcon :name="card.icon" class="h-5 w-5" />
48
+ </span>
49
+ <p class="mt-4 font-semibold text-slate-900">{{ card.title }}</p>
50
+ <p class="mt-1 text-sm text-slate-500">{{ card.desc }}</p>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ </section>
55
+ </template>
@@ -0,0 +1,47 @@
1
+ export function useActiveSection(sectionIds: string[]) {
2
+ const activeSection = ref(sectionIds[0] || '')
3
+
4
+ onMounted(() => {
5
+ const sections = sectionIds
6
+ .map(id => document.getElementById(id))
7
+ .filter(Boolean) as HTMLElement[]
8
+
9
+ if (!sections.length) return
10
+
11
+ function update() {
12
+ let maxVisibleHeight = 0
13
+ let maxId = activeSection.value
14
+
15
+ const viewportHeight = window.innerHeight
16
+
17
+ for (let i = 0; i < sections.length; i++) {
18
+ const el = sections[i]
19
+ const rect = el.getBoundingClientRect()
20
+
21
+ const visibleTop = Math.max(0, rect.top)
22
+ const visibleBottom = Math.min(viewportHeight, rect.bottom)
23
+ const visibleHeight = Math.max(0, visibleBottom - visibleTop)
24
+
25
+ if (visibleHeight > maxVisibleHeight) {
26
+ maxVisibleHeight = visibleHeight
27
+ maxId = el.id
28
+ }
29
+ }
30
+
31
+ if (window.scrollY < 50 && sections[0]) {
32
+ activeSection.value = sections[0].id
33
+ return
34
+ }
35
+
36
+ if (maxVisibleHeight > 0) {
37
+ activeSection.value = maxId
38
+ }
39
+ }
40
+
41
+ update()
42
+ window.addEventListener('scroll', update, { passive: true })
43
+ onUnmounted(() => window.removeEventListener('scroll', update))
44
+ })
45
+
46
+ return activeSection
47
+ }
@@ -0,0 +1,244 @@
1
+ export const useAuthApi = () => {
2
+ const { $sdk } = useNuxtApp()
3
+
4
+ // ==========================
5
+ // LOGIN / REGISTER
6
+ // ==========================
7
+
8
+ const login = (data: {
9
+ username: string
10
+ password: string
11
+ type?: string
12
+ otpCode?: string
13
+ }) => {
14
+ return $sdk.auth.login(data)
15
+ }
16
+
17
+ const register = (data: {
18
+ username: string
19
+ fullName: string
20
+ }) => {
21
+ return $sdk.auth.register(data as any)
22
+ }
23
+
24
+ const logout = (accessToken: string, partyId: string) => {
25
+ return $sdk.auth.logout(accessToken, partyId)
26
+ }
27
+
28
+ const getUserByToken = (token: string) => {
29
+ return $sdk.auth.getUserDetail(token)
30
+ }
31
+
32
+ const getUserLoginByToken = (token: string) => {
33
+ return $sdk.auth.getUserLoginByToken(token)
34
+ }
35
+
36
+ const updateInfo = (
37
+ accessToken: string,
38
+ updateUserRequest: { fullName: string; phone: string; email?: string },
39
+ type: string,
40
+ password: string
41
+ ) => {
42
+ return $sdk.auth.updateInfo(accessToken, updateUserRequest, type, password)
43
+ }
44
+
45
+ const getAccessTokenByOTP = (
46
+ code: string,
47
+ phone: string,
48
+ method: string
49
+ ) => {
50
+ return $sdk.auth.getAccessTokenByOTP(code, phone, method)
51
+ }
52
+
53
+ // ==========================
54
+ // USER LOGIN
55
+ // ==========================
56
+
57
+ const getUserLoginByUserLoginId = (userLoginId: string) => {
58
+ return $sdk.auth.getUserLoginByUserLoginId(userLoginId)
59
+ }
60
+
61
+ const checkUsernameExisted = (username: string) => {
62
+ return $sdk.auth.checkUsernameExisted(username)
63
+ }
64
+
65
+ const createUserLogin = (phone: string) => {
66
+ return $sdk.auth.createUserLogin(phone)
67
+ }
68
+
69
+ const linkingUserLoginAndUserDetail = (
70
+ userLoginId: string,
71
+ partyId: string
72
+ ) => {
73
+ return $sdk.auth.linkingUserLoginAndUserDetail(
74
+ userLoginId,
75
+ partyId
76
+ )
77
+ }
78
+
79
+ const createUserDetail = (userLoginId: string) => {
80
+ return $sdk.auth.createUserDetail(userLoginId)
81
+ }
82
+
83
+ // ==========================
84
+ // OTP
85
+ // ==========================
86
+
87
+ const sendOTP = (
88
+ phone: string,
89
+ method: "sms" | "zalo"
90
+ ) => {
91
+ return $sdk.auth.sendOTP(phone, method)
92
+ }
93
+
94
+ const validateOTP = (
95
+ code: string,
96
+ phone: string,
97
+ method: string
98
+ ) => {
99
+ return $sdk.auth.validateOTP(code, phone, method)
100
+ }
101
+
102
+ // ==========================
103
+ // RESET PASSWORD
104
+ // ==========================
105
+
106
+ const createResetKey = (userLoginId: string) => {
107
+ return $sdk.auth.createResetKey(userLoginId)
108
+ }
109
+
110
+ const checkResetKey = (key: string) => {
111
+ return $sdk.auth.checkResetKey(key)
112
+ }
113
+
114
+ const resetPassword = (
115
+ username: string,
116
+ newPassword: string,
117
+ accessToken: string
118
+ ) => {
119
+ return $sdk.auth.resetPassword(username, newPassword, accessToken)
120
+ }
121
+
122
+ // ==========================
123
+ // USER
124
+ // ==========================
125
+
126
+ const updateCustomer = (
127
+ partyId: string,
128
+ body: any,
129
+ updatedBy: string
130
+ ) => {
131
+ return $sdk.user.updateCustomer(
132
+ partyId,
133
+ body,
134
+ updatedBy
135
+ )
136
+ }
137
+
138
+ const updateProfile = (
139
+ userLoginId: string,
140
+ fullName: string,
141
+ phone: string,
142
+ email: string
143
+ ) => {
144
+ return $sdk.auth.updateProfile(
145
+ userLoginId,
146
+ fullName,
147
+ phone,
148
+ email
149
+ )
150
+ }
151
+
152
+ const getPhoneByPartyId = (partyId: string) => {
153
+ return $sdk.auth.getPhoneByPartyId(partyId)
154
+ }
155
+
156
+ // ==========================
157
+ // SOCIAL LOGIN
158
+ // ==========================
159
+
160
+ const loginGoogle = (redirectUrl: string, redirectUrlError: string, serviceOperator: string, appId: string, deviceId: string) => {
161
+ return $sdk.auth.loginGoogle(redirectUrl, redirectUrlError, serviceOperator, appId, deviceId)
162
+ }
163
+
164
+ const loginFacebook = (redirectUrl: string, redirectUrlError: string, serviceOperator: string, appId: string, deviceId: string) => {
165
+ return $sdk.auth.loginFacebook(redirectUrl, redirectUrlError, serviceOperator, appId, deviceId)
166
+ }
167
+
168
+ const loginZalo = (redirectUrl: string, redirectUrlError: string, serviceOperator: string, appId: string, deviceId: string) => {
169
+ return $sdk.auth.loginZalo(redirectUrl, redirectUrlError, serviceOperator, appId, deviceId)
170
+ }
171
+
172
+ // ==========================
173
+ // ORDER
174
+ // ==========================
175
+
176
+ const setOrderToken = (token: string) => {
177
+ return $sdk.order.setToken(token)
178
+ }
179
+
180
+ const findCampaignActionGiftVoucher = () => {
181
+ return $sdk.order.findCampaignActionGiftVoucher()
182
+ }
183
+
184
+ // ==========================
185
+ // CRM CAMPAIGN
186
+ // ==========================
187
+
188
+ const setCampaignToken = (token: string) => {
189
+ return $sdk.crm_camping.setToken(token)
190
+ }
191
+
192
+ const addCustomerToVoucher = (
193
+ userId: string,
194
+ voucherCode: string
195
+ ) => {
196
+ return $sdk.crm_camping.addCustomerToVoucher(
197
+ userId,
198
+ voucherCode
199
+ )
200
+ }
201
+
202
+ return {
203
+ // login / register
204
+ login,
205
+ register,
206
+ logout,
207
+ getUserByToken,
208
+ getUserLoginByToken,
209
+ updateInfo,
210
+ getAccessTokenByOTP,
211
+
212
+ // user login
213
+ getUserLoginByUserLoginId,
214
+ checkUsernameExisted,
215
+ createUserLogin,
216
+ linkingUserLoginAndUserDetail,
217
+ createUserDetail,
218
+
219
+ // otp
220
+ sendOTP,
221
+ validateOTP,
222
+
223
+ // reset
224
+ createResetKey,
225
+ checkResetKey,
226
+ resetPassword,
227
+
228
+ // user
229
+ updateCustomer,
230
+ updateProfile,
231
+ getPhoneByPartyId,
232
+
233
+ // social
234
+ loginGoogle,
235
+ loginFacebook,
236
+ loginZalo,
237
+
238
+ // voucher
239
+ setOrderToken,
240
+ findCampaignActionGiftVoucher,
241
+ setCampaignToken,
242
+ addCustomerToVoucher,
243
+ }
244
+ }
@@ -0,0 +1,16 @@
1
+ export const useAuthState = () => {
2
+ const isLoggedIn = useState('auth-logged-in', () => false)
3
+ const userName = useState('auth-user-name', () => '')
4
+
5
+ function setUser(name: string) {
6
+ isLoggedIn.value = true
7
+ userName.value = name
8
+ }
9
+
10
+ function clearUser() {
11
+ isLoggedIn.value = false
12
+ userName.value = ''
13
+ }
14
+
15
+ return { isLoggedIn, userName, setUser, clearUser }
16
+ }