init docter service
BIN
Archive.zip
Normal file
17
eslint.config.js
Normal file
@ -0,0 +1,17 @@
|
||||
import js from '@eslint/js'
|
||||
import pluginVue from 'eslint-plugin-vue'
|
||||
|
||||
export default [
|
||||
{
|
||||
name: 'app/files-to-lint',
|
||||
files: ['**/*.{js,mjs,jsx,vue}'],
|
||||
},
|
||||
|
||||
{
|
||||
name: 'app/files-to-ignore',
|
||||
ignores: ['**/dist/**', '**/dist-ssr/**', '**/coverage/**'],
|
||||
},
|
||||
|
||||
js.configs.recommended,
|
||||
...pluginVue.configs['flat/essential'],
|
||||
]
|
||||
19
index.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
<title>Solnus | Legal Service Solutions</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
9
jsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
|
||||
}
|
||||
4071
package-lock.json
generated
Normal file
24
package.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "vue-project",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint . --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.6.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.14.0",
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
"eslint": "^9.14.0",
|
||||
"eslint-plugin-vue": "^9.30.0",
|
||||
"vite": "^6.0.5",
|
||||
"vite-plugin-vue-devtools": "^7.6.8"
|
||||
}
|
||||
}
|
||||
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
24
src/App.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<script setup>
|
||||
import BackToTop from "./components/button/BackToTop.vue";
|
||||
import Footer from "./components/footer/Footer.vue";
|
||||
import Navigation from "./components/Navigation.vue";
|
||||
import NotificationFeed from "./components/NotificationFeed.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header>
|
||||
<Navigation />
|
||||
</header>
|
||||
|
||||
<router-view />
|
||||
|
||||
<footer id="kontak">
|
||||
<Footer />
|
||||
</footer>
|
||||
|
||||
<BackToTop />
|
||||
<NotificationFeed />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
3
src/assets/add-on.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.66667 1V14.3333M12.6667 2.66667L2.66667 12.6667M14.3333 7.66667H1M12.6667 12.6667L2.66667 2.66667" stroke="#494949" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 297 B |
BIN
src/assets/background-hero.png
Normal file
|
After Width: | Height: | Size: 234 KiB |
BIN
src/assets/background_hero.png
Normal file
|
After Width: | Height: | Size: 3.2 MiB |
5
src/assets/base.css
Normal file
@ -0,0 +1,5 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: "Poppins", serif;
|
||||
}
|
||||
BIN
src/assets/business-hero.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
10
src/assets/check-circle.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_163_2725)">
|
||||
<path d="M6.25008 9.99984L8.75008 12.4998L13.7501 7.49984M18.3334 9.99984C18.3334 14.6022 14.6025 18.3332 10.0001 18.3332C5.39771 18.3332 1.66675 14.6022 1.66675 9.99984C1.66675 5.39746 5.39771 1.6665 10.0001 1.6665C14.6025 1.6665 18.3334 5.39746 18.3334 9.99984Z" stroke="#494949" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_163_2725">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 595 B |
BIN
src/assets/hero.png
Normal file
|
After Width: | Height: | Size: 618 KiB |
BIN
src/assets/icon-check.png
Normal file
|
After Width: | Height: | Size: 190 KiB |
BIN
src/assets/icon-pt.png
Normal file
|
After Width: | Height: | Size: 258 KiB |
BIN
src/assets/icon-question.png
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
src/assets/icon_check.png
Normal file
|
After Width: | Height: | Size: 929 B |
BIN
src/assets/icon_law.png
Normal file
|
After Width: | Height: | Size: 686 B |
BIN
src/assets/logo-solnus.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
1
src/assets/logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
|
||||
|
After Width: | Height: | Size: 276 B |
4
src/assets/main.css
Normal file
@ -0,0 +1,4 @@
|
||||
@import './base.css';
|
||||
|
||||
|
||||
|
||||
BIN
src/assets/package-bronze.png
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
src/assets/package-gold.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
src/assets/package-platinum.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
src/assets/package-silver.png
Normal file
|
After Width: | Height: | Size: 62 KiB |
BIN
src/assets/salad.jpg
Normal file
|
After Width: | Height: | Size: 136 KiB |
BIN
src/assets/service_legal.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
src/assets/spaghetti.jpg
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
src/assets/steak.jpg
Normal file
|
After Width: | Height: | Size: 71 KiB |
10
src/assets/x-circle.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_163_2734)">
|
||||
<path d="M12.5001 7.49984L7.50008 12.4998M7.50008 7.49984L12.5001 12.4998M18.3334 9.99984C18.3334 14.6022 14.6025 18.3332 10.0001 18.3332C5.39771 18.3332 1.66675 14.6022 1.66675 9.99984C1.66675 5.39746 5.39771 1.6665 10.0001 1.6665C14.6025 1.6665 18.3334 5.39746 18.3334 9.99984Z" stroke="#EE0000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_163_2734">
|
||||
<rect width="20" height="20" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 611 B |
350
src/components/Navigation.vue
Normal file
@ -0,0 +1,350 @@
|
||||
<template>
|
||||
<header>
|
||||
<nav class="navbar">
|
||||
<div class="left">
|
||||
<router-link to="/">
|
||||
<img src="@/assets/logo-solnus.png" class="logo" />
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="right">
|
||||
<ul class="nav-links" :class="{ active: isMenuOpen }">
|
||||
<li><a href="#solusi" @click.prevent="scrollToSection('solusi')" :class="{ 'active-link': activeSection === 'solusi' }">Solusi</a></li>
|
||||
<li class="dropdown" ref="dropdownRef">
|
||||
<button type="button" class="dropdown-toggle" @click="toggleDropdown" :class="{ 'active-link': $route.path.startsWith('/packages') }">
|
||||
Paket Layanan
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-left: 4px; transition: transform 0.2s;" :style="{ transform: showDropdown ? 'rotate(180deg)' : 'rotate(0deg)' }">
|
||||
<path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="dropdown-menu" :class="{ show: showDropdown }">
|
||||
<router-link to="/packages" @click="closeMenu">Semua Paket</router-link>
|
||||
<router-link to="/packages/pendirian" @click="closeMenu">Paket Pendirian</router-link>
|
||||
<router-link to="/packages/perubahan" @click="closeMenu">Paket Perubahan & Pembubaran</router-link>
|
||||
<router-link to="/packages/property" @click="closeMenu">Paket Property</router-link>
|
||||
<router-link to="/packages/khusus" @click="closeMenu">Paket Khusus</router-link>
|
||||
<router-link to="/packages/umum" @click="closeMenu">Paket Umum</router-link>
|
||||
<router-link to="/packages/lainnya" @click="closeMenu">Paket Lainnya</router-link>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#faq" @click.prevent="scrollToSection('faq')" :class="{ 'active-link': activeSection === 'faq' }">
|
||||
FAQ
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="#kontak" @click.prevent="scrollToSection('kontak')" :class="{ 'active-link': activeSection === 'kontak' }">Kontak Kami</a></li>
|
||||
<li>
|
||||
<a
|
||||
:href="whatsAppUrl"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="consult-btn"
|
||||
>
|
||||
Konsultasi Gratis
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="hamburger" @click="toggleMenu">
|
||||
<div class="bar"></div>
|
||||
<div class="bar"></div>
|
||||
<div class="bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isMenuOpen: false,
|
||||
activeSection: '',
|
||||
showDropdown: false,
|
||||
whatsAppUrl: 'https://wa.me/6281234567890',
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggleMenu() {
|
||||
this.isMenuOpen = !this.isMenuOpen;
|
||||
},
|
||||
closeMenu() {
|
||||
this.isMenuOpen = false;
|
||||
this.showDropdown = false;
|
||||
},
|
||||
toggleDropdown() {
|
||||
this.showDropdown = !this.showDropdown;
|
||||
},
|
||||
scrollToSection(sectionId) {
|
||||
this.closeMenu();
|
||||
|
||||
// If not on home page, navigate to home first
|
||||
if (this.$route.path !== '/') {
|
||||
this.$router.push('/').then(() => {
|
||||
// Wait for DOM to be fully rendered
|
||||
setTimeout(() => {
|
||||
this.performScroll(sectionId);
|
||||
}, 100);
|
||||
});
|
||||
} else {
|
||||
this.performScroll(sectionId);
|
||||
}
|
||||
},
|
||||
performScroll(sectionId) {
|
||||
const element = document.getElementById(sectionId);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
},
|
||||
handleScroll() {
|
||||
// Only track sections on home page
|
||||
if (this.$route.path !== '/') {
|
||||
this.activeSection = '';
|
||||
return;
|
||||
}
|
||||
|
||||
const sections = ['solusi', 'faq', 'konsultasi', 'kontak'];
|
||||
const scrollPosition = window.scrollY + 100;
|
||||
|
||||
for (const sectionId of sections) {
|
||||
const element = document.getElementById(sectionId);
|
||||
if (element) {
|
||||
const offsetTop = element.offsetTop;
|
||||
const offsetBottom = offsetTop + element.offsetHeight;
|
||||
|
||||
if (scrollPosition >= offsetTop && scrollPosition < offsetBottom) {
|
||||
this.activeSection = sectionId;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.activeSection = '';
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// Close menu when clicking on any nav link
|
||||
const navLinks = this.$el.querySelectorAll('.nav-links a');
|
||||
navLinks.forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
this.closeMenu();
|
||||
});
|
||||
});
|
||||
|
||||
// Track scroll position for active section
|
||||
window.addEventListener('scroll', this.handleScroll);
|
||||
this.handleScroll();
|
||||
},
|
||||
beforeUnmount() {
|
||||
window.removeEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.navbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
padding: 10px 16px;
|
||||
background: white;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
z-index: 1000;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 140px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 48px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 50px;
|
||||
align-items: center;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.nav-links li a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.nav-links li a:hover {
|
||||
color: #FF6640;
|
||||
}
|
||||
|
||||
.nav-links li a.router-link-active,
|
||||
.nav-links li a.router-link-exact-active,
|
||||
.nav-links li a.active-link {
|
||||
color: #FF6640;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
background: none;
|
||||
border: none;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
left: 0;
|
||||
background: white;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
padding: 8px 0;
|
||||
margin: 0;
|
||||
min-width: 260px;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.dropdown-menu.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dropdown-menu a {
|
||||
display: block;
|
||||
padding: 12px 20px;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dropdown-menu a:hover {
|
||||
background: #f9fafb;
|
||||
color: #FF6640;
|
||||
}
|
||||
|
||||
.dropdown-menu a.router-link-active,
|
||||
.dropdown-menu a.router-link-exact-active {
|
||||
color: #FF6640;
|
||||
background: #fff5f3;
|
||||
}
|
||||
|
||||
.consult-btn {
|
||||
padding: 10px 22px;
|
||||
border: 2px solid #FF6640;
|
||||
border-radius: 8px;
|
||||
font-weight: bold;
|
||||
color: #FF6640;
|
||||
white-space: nowrap; /* prevent wrapping */
|
||||
}
|
||||
|
||||
.consult-btn:hover {
|
||||
background: #FF6640;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
cursor: pointer;
|
||||
margin-left: 12px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.bar {
|
||||
width: 28px;
|
||||
height: 3px;
|
||||
background: #333;
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 768px) {
|
||||
.navbar {
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.right {
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
top: 57px;
|
||||
left: 0;
|
||||
background: white;
|
||||
width: 100%;
|
||||
padding: 8px 0 16px;
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
||||
gap: 0;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.nav-links.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
display: flex;
|
||||
margin-right: 27px;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
padding: 12px 20px;
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
position: static;
|
||||
transform: none;
|
||||
box-shadow: none;
|
||||
border-left: 3px solid #FF6640;
|
||||
background: #f9fafb;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nav-links > li > a {
|
||||
display: block;
|
||||
padding: 12px 20px;
|
||||
}
|
||||
|
||||
.consult-btn {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
margin: 12px auto 4px;
|
||||
min-width: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
339
src/components/NotificationFeed.vue
Normal file
@ -0,0 +1,339 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
|
||||
const notifications = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Nanda Permadi",
|
||||
action: "Telah melakukan konsultasi hari ini",
|
||||
timeAgo: "45 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Rina Aulia",
|
||||
action: "Baru saja mendaftar paket pendirian PT",
|
||||
timeAgo: "10 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Budi Santoso",
|
||||
action: "Mengajukan pertanyaan seputar NIB & OSS",
|
||||
timeAgo: "30 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Siti Marlina",
|
||||
action: "Menjadwalkan sesi konsultasi pajak",
|
||||
timeAgo: "1 jam yang lalu"
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Agus Pratama",
|
||||
action: "Mengirim dokumen pendirian CV",
|
||||
timeAgo: "50 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Annisa Safitri",
|
||||
action: "Telah melakukan konsultasi hari ini",
|
||||
timeAgo: "Baru saja"
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "Mega Silviawati",
|
||||
action: "Berkonsultasi mengenai saham PT",
|
||||
timeAgo: "5 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "Ahmad Agus",
|
||||
action: "Mengirimkan dokumen pendirian firma",
|
||||
timeAgo: "8 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
name: "Julianto Harahap",
|
||||
action: "Baru saja mendaftar paket pembuatan web",
|
||||
timeAgo: "12 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: "Ayu Lestari",
|
||||
action: "Mengirimkan dokumen pendirian PT PMA",
|
||||
timeAgo: "15 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
name: "Kevin Arianto",
|
||||
action: "Berkonsultasi mengenai surat keterangan waris",
|
||||
timeAgo: "18 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 12,
|
||||
name: "Deviani",
|
||||
action: "Berkonsultasi mengenai jual beli apartemen",
|
||||
timeAgo: "20 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
name: "Amalia Rosalin",
|
||||
action: "Mengajukan pertanyaan seputar balik nama waris",
|
||||
timeAgo: "22 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
name: "Citra Puspitawati",
|
||||
action: "Berkonsultasi mengenai perjanjian sewa ruko",
|
||||
timeAgo: "25 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 15,
|
||||
name: "Intan Senjawati",
|
||||
action: "Telah melakukan konsultasi hari ini",
|
||||
timeAgo: "28 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 16,
|
||||
name: "Ranny Zahra",
|
||||
action: "Mengirimkan dokumen pendirian perkumpulan",
|
||||
timeAgo: "32 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 17,
|
||||
name: "Bayu Kusmawadi",
|
||||
action: "Berkonsultasi mengenai legalisasi dokumen PT",
|
||||
timeAgo: "35 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 18,
|
||||
name: "Daniel Guntarto",
|
||||
action: "Mengajukan pertanyaan seputar legalisir dokumen",
|
||||
timeAgo: "38 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 19,
|
||||
name: "Derry Dharmawan",
|
||||
action: "Mengirimkan dokumen jual beli saham PT",
|
||||
timeAgo: "40 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
name: "Erlangga Nasution",
|
||||
action: "Mengirimkan dokumen pendirian yayasan",
|
||||
timeAgo: "42 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 21,
|
||||
name: "Olivia Hanum",
|
||||
action: "Baru saja mendaftar pendirian PT perorangan",
|
||||
timeAgo: "47 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 22,
|
||||
name: "Kirana Putri",
|
||||
action: "Mengajukan pertanyaan seputar perubahan PT",
|
||||
timeAgo: "48 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 23,
|
||||
name: "Mayang Saputri",
|
||||
action: "Berkonsultasi mengenai KBLI",
|
||||
timeAgo: "52 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 24,
|
||||
name: "Reyza Putra",
|
||||
action: "Telah melakukan konsultasi hari ini",
|
||||
timeAgo: "55 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 25,
|
||||
name: "Jericho Ethan",
|
||||
action: "Mengajukan pertanyaan seputar pembuatan NPWP",
|
||||
timeAgo: "58 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 26,
|
||||
name: "Michael Alvaro",
|
||||
action: "Mengirimkan dokumen pembubaran PT",
|
||||
timeAgo: "1 jam yang lalu"
|
||||
},
|
||||
{
|
||||
id: 27,
|
||||
name: "Yudis Setiawan",
|
||||
action: "Berkonsultasi mengenai PKKPR",
|
||||
timeAgo: "Baru saja"
|
||||
},
|
||||
{
|
||||
id: 28,
|
||||
name: "Christian Salim",
|
||||
action: "Telah melakukan konsultasi hari ini",
|
||||
timeAgo: "6 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 29,
|
||||
name: "Mevy Fanggidae",
|
||||
action: "Mengirimkan dokumen perubahan PT PMA",
|
||||
timeAgo: "14 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 30,
|
||||
name: "Melinda Julianti",
|
||||
action: "Mengajukan pertanyaan seputar perubahan yayasan",
|
||||
timeAgo: "26 menit yang lalu"
|
||||
},
|
||||
{
|
||||
id: 31,
|
||||
name: "Kevin Nakmofa",
|
||||
action: "Mengirimkan dokumen pendirian koperasi",
|
||||
timeAgo: "36 menit yang lalu"
|
||||
}
|
||||
];
|
||||
|
||||
const currentIndex = ref(0);
|
||||
const isVisible = ref(true);
|
||||
|
||||
let intervalId;
|
||||
|
||||
const close = () => {
|
||||
isVisible.value = false;
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const cycleNotification = () => {
|
||||
if (!isVisible.value) return;
|
||||
// Trigger leave animation first
|
||||
isVisible.value = false;
|
||||
setTimeout(() => {
|
||||
currentIndex.value =
|
||||
(currentIndex.value + 1) % notifications.length;
|
||||
isVisible.value = true;
|
||||
}, 220);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
intervalId = setInterval(() => {
|
||||
cycleNotification();
|
||||
}, 8000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<transition name="toast-fade">
|
||||
<aside
|
||||
v-if="isVisible"
|
||||
class="notification"
|
||||
aria-live="polite"
|
||||
>
|
||||
<div class="content">
|
||||
<div class="header">
|
||||
<span class="name">
|
||||
{{ notifications[currentIndex].name }}
|
||||
</span>
|
||||
<button
|
||||
class="close-btn"
|
||||
type="button"
|
||||
aria-label="Tutup notifikasi"
|
||||
@click="close"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
<p class="action">
|
||||
{{ notifications[currentIndex].action }}
|
||||
</p>
|
||||
<p class="time">
|
||||
{{ notifications[currentIndex].timeAgo }}
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.notification {
|
||||
position: fixed;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
max-width: 320px;
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 18px 45px rgba(15, 23, 42, 0.25);
|
||||
border: 1px solid #e5e7eb;
|
||||
z-index: 1200;
|
||||
overflow: hidden;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 14px 18px 16px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.action {
|
||||
margin: 0;
|
||||
color: #6b7280;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.time {
|
||||
margin: 6px 0 0;
|
||||
color: #9ca3af;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
color: #6b7280;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.close-btn:hover {
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.toast-fade-enter-active,
|
||||
.toast-fade-leave-active {
|
||||
transition: opacity 0.25s ease, transform 0.25s ease;
|
||||
}
|
||||
|
||||
.toast-fade-enter-from,
|
||||
.toast-fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(16px);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.notification {
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
bottom: 16px;
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
46
src/components/button/BackToTop.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
|
||||
const showButton = ref(false);
|
||||
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
};
|
||||
|
||||
const handleScroll = () => {
|
||||
showButton.value = window.scrollY > 0;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener("scroll", handleScroll);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button v-if="showButton" @click="scrollToTop">↑</button>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
button {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background-color: #f8b400;;
|
||||
color: black;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #c39004;;
|
||||
}
|
||||
</style>
|
||||
102
src/components/footer/Footer.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<footer class="footer">
|
||||
<div class="footer-wrapper">
|
||||
<div class="container">
|
||||
<div class="grid">
|
||||
<div class="col brand">
|
||||
<div class="logo">
|
||||
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="28" height="28" rx="6" fill="#FF6640"/>
|
||||
<path d="M8 10h12M8 14h12M8 18h8" stroke="#fff" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<span class="logo-text">Solnus</span>
|
||||
</div>
|
||||
<p class="tagline">Urus Legalitas Bisnis Tanpa Ribet.<br/>Dari pendirian PT, CV, hingga Yayasan,<br/>semua proses hukum kini lebih cepat,<br/>aman, dan transparan bersama tim<br/>profesional berpengalaman.</p>
|
||||
<div class="contact"><a href="https://wa.me/6282297638822">0822-9763-8822</a> | <a href="mailto:admin@solnus.id ">admin@solnus.id </a></div>
|
||||
|
||||
<div class="social">
|
||||
<a href="https://linkedin.com/in/solnus" aria-label="LinkedIn">
|
||||
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>
|
||||
</a>
|
||||
<a href="https://facebook.com/solnus" aria-label="Facebook">
|
||||
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M22 12.07C22 6.51 17.52 2 12 2S2 6.51 2 12.07c0 5.02 3.66 9.19 8.44 9.93v-7.03H8.08v-2.9h2.36V9.41c0-2.33 1.38-3.62 3.5-3.62.99 0 2.02.18 2.02.18v2.25h-1.14c-1.12 0-1.47.7-1.47 1.42v1.7h2.5l-.4 2.9h-2.1V22c4.78-.74 8.44-4.91 8.44-9.93z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<a href="https://instagram.com/solnus" aria-label="Instagram">
|
||||
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/></svg>
|
||||
</a>
|
||||
<a href="https://solnus.id" aria-label="Website">
|
||||
<svg width="20" height="20" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm6.93 9h-2.95a15.71 15.71 0 0 0-1.22-5.19A8.01 8.01 0 0 1 18.93 11zM12 4c.83 0 2.3 1.99 2.88 5H9.12C9.7 5.99 11.17 4 12 4zM8.24 5.81A15.71 15.71 0 0 0 7.02 11H4.07a8.01 8.01 0 0 1 4.17-5.19zM4.07 13h2.95c.14 1.84.61 3.58 1.22 5.19A8.01 8.01 0 0 1 4.07 13zM12 20c-.83 0-2.3-1.99-2.88-5h5.76C14.3 18.01 12.83 20 12 20zm3.76-1.19c.61-1.61 1.08-3.35 1.22-5.19h2.95a8.01 8.01 0 0 1-4.17 5.19z"/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col">
|
||||
<h3 class="title">Layanan</h3>
|
||||
<ul class="links">
|
||||
<li>
|
||||
<router-link :to="{ name: 'PackagesPendirian' }">
|
||||
Pendirian PT (Perseroan Terbatas)
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'PackagesPendirian' }">
|
||||
Pendirian CV (Commanditaire Vennootschap)
|
||||
</router-link>
|
||||
</li>
|
||||
<li>
|
||||
<router-link :to="{ name: 'PackagesPendirian' }">
|
||||
Pendirian Yayasan
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="container">
|
||||
<div class="bottom-content">
|
||||
<span>© 2025 All Rights Reserved | PT Solusi Legal Nusantara</span>
|
||||
<a href="#" class="privacy">Privacy Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.footer { background: #fff; border-top: 1px solid #e5e7eb; }
|
||||
.footer-wrapper { padding: 60px 20px 0; }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.grid { display: grid; gap: 48px; grid-template-columns: 1fr; }
|
||||
@media (min-width: 768px) {
|
||||
.grid {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
.col { }
|
||||
.brand { }
|
||||
.logo { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
|
||||
.logo-text { font-size: 24px; font-weight: 800; color: #FF6640; }
|
||||
.tagline { font-size: 14px; line-height: 1.7; color: #6b7280; margin: 0 0 20px; }
|
||||
.contact { font-size: 16px; font-weight: 600; color: #111827; margin-bottom: 16px; }
|
||||
.social { display: flex; gap: 12px; }
|
||||
.social a { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; color: #6b7280; transition: color .2s; }
|
||||
.social a:hover { color: #111827; }
|
||||
.title { font-size: 16px; font-weight: 700; color: #111827; margin: 0 0 16px; }
|
||||
.links { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
|
||||
.links a { color: #6b7280; text-decoration: none; font-size: 14px; transition: color .2s; }
|
||||
.links a:hover { color: #111827; }
|
||||
.bottom { background: #111827; margin-top: 48px; padding: 20px; }
|
||||
.bottom-content { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; color: #9ca3af; font-size: 14px; }
|
||||
.privacy { color: #9ca3af; text-decoration: none; }
|
||||
.privacy:hover { color: #fff; }
|
||||
@media (max-width: 640px) { .bottom-content { flex-direction: column; text-align: center; } }
|
||||
</style>
|
||||
48
src/components/main/CallToAction.vue
Normal file
@ -0,0 +1,48 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
title: { type: String, default: 'Jangan biarkan bisnis hanya Anda berdiri di atas dokumen yang lemah.' },
|
||||
buttonText: { type: String, default: 'Konsultasi Gratis' }
|
||||
})
|
||||
|
||||
const whatsAppUrl = 'https://wa.me/6281234567890'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="cta">
|
||||
<div class="overlay"></div>
|
||||
<div class="container">
|
||||
<h2 class="title">{{ title }}</h2>
|
||||
<a
|
||||
:href="whatsAppUrl"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
class="btn"
|
||||
>
|
||||
{{ buttonText }}
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.cta {
|
||||
padding: 80px 20px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
background-image: url('@/assets/business-hero.png');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.65);
|
||||
z-index: 1;
|
||||
}
|
||||
.container { max-width: 800px; margin: 0 auto; position: relative; z-index: 2; }
|
||||
.title { color: #fff; font-size: 28px; font-weight: 700; line-height: 1.4; margin: 0 0 24px; }
|
||||
.btn { padding: 14px 32px; background: #FF6640; color: #fff; border: none; border-radius: 6px; font-weight: 600; font-size: 16px; cursor: pointer; transition: background .2s; }
|
||||
.btn:hover { background: #e85a30; }
|
||||
@media (min-width: 768px) { .title { font-size: 36px; } }
|
||||
</style>
|
||||
174
src/components/main/ContactUs.vue
Normal file
@ -0,0 +1,174 @@
|
||||
<template>
|
||||
<section class="contact">
|
||||
<h2 class="contact-title">{{ heading }}</h2>
|
||||
<p class="contact-description">
|
||||
{{ subheading }}
|
||||
</p>
|
||||
|
||||
<div class="contact-items">
|
||||
<article
|
||||
v-for="item in contactItems"
|
||||
:key="item.id"
|
||||
class="item"
|
||||
>
|
||||
<i aria-hidden="true">{{ item.icon }}</i>
|
||||
<div class="details">
|
||||
<h3>{{ item.title }}</h3>
|
||||
<p class="detail-text">{{ item.detail }}</p>
|
||||
<p
|
||||
v-if="item.description"
|
||||
class="detail-subtext"
|
||||
>
|
||||
{{ item.description }}
|
||||
</p>
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const heading = "Hubungi Solnus";
|
||||
const subheading =
|
||||
"Tim kami siap mendampingi legalitas bisnis Anda melalui jalur komunikasi yang paling nyaman.";
|
||||
|
||||
const contactItems = [
|
||||
{
|
||||
id: "phone",
|
||||
icon: "📞",
|
||||
title: "Telepon",
|
||||
detail: "+62 811-2233-4455",
|
||||
description: "Senin - Jumat, 09.00 - 18.00 WIB"
|
||||
},
|
||||
{
|
||||
id: "email",
|
||||
icon: "✉️",
|
||||
title: "Email",
|
||||
detail: "support@solnus.id",
|
||||
description: "Kami membalas dalam 1x24 jam kerja"
|
||||
},
|
||||
{
|
||||
id: "office",
|
||||
icon: "📍",
|
||||
title: "Kantor",
|
||||
detail: "Green Office Park, BSD City",
|
||||
description: "Silakan buat janji sebelum kunjungan"
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.contact {
|
||||
padding: 80px 20px;
|
||||
}
|
||||
|
||||
.contact-title {
|
||||
text-align: center;
|
||||
font-size: 2.2rem;
|
||||
margin-bottom: 10px;
|
||||
color: var(--color-heading);
|
||||
}
|
||||
|
||||
.contact-description {
|
||||
text-align: center;
|
||||
max-width: 640px;
|
||||
margin: 0 auto 40px;
|
||||
color: var(--color-text);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.contact-items {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.item {
|
||||
margin-top: 2rem;
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.details {
|
||||
flex: 1;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
place-items: center;
|
||||
place-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
|
||||
color: var(--color-text);
|
||||
background: var(--color-background-mute);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 500;
|
||||
margin-bottom: 0.4rem;
|
||||
color: var(--color-heading);
|
||||
}
|
||||
|
||||
.detail-text {
|
||||
font-weight: 600;
|
||||
color: var(--color-heading);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.detail-subtext {
|
||||
margin: 0.2rem 0 0;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.contact-items {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.item {
|
||||
margin-top: 0;
|
||||
padding: 0.4rem 0 1rem calc(var(--section-gap) / 2);
|
||||
}
|
||||
|
||||
i {
|
||||
top: calc(50% - 25px);
|
||||
left: -26px;
|
||||
position: absolute;
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-background);
|
||||
border-radius: 8px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.item:before {
|
||||
content: ' ';
|
||||
border-left: 1px solid var(--color-border);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: calc(50% + 25px);
|
||||
height: calc(50% - 25px);
|
||||
}
|
||||
|
||||
.item:after {
|
||||
content: ' ';
|
||||
border-left: 1px solid var(--color-border);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: calc(50% + 25px);
|
||||
height: calc(50% - 25px);
|
||||
}
|
||||
|
||||
.item:first-of-type:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.item:last-of-type:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
337
src/components/main/FaqSection.vue
Normal file
@ -0,0 +1,337 @@
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
|
||||
const faqItems = [
|
||||
{
|
||||
id: "q1",
|
||||
question:
|
||||
"Berapa minimal modal dasar PT Dalam Negeri, PT PMA/PT Asing, PT Perorangan dan CV?",
|
||||
blocks: [
|
||||
{
|
||||
type: "ul",
|
||||
items: [
|
||||
"Minimal modal untuk mendirikan sebuah PT adalah sebesar Rp50.000.000 (lima puluh juta rupiah).",
|
||||
"Minimal modal untuk mendirikan sebuah PT PMA/PT Asing adalah sebesar Rp10.000.000.000 (sepuluh miliar rupiah).",
|
||||
"Pendirian sebuah PT Perorangan tidak memiliki batas minimal dan hanya dibatasi maksimal Rp5.000.000.000 (lima miliar rupiah).",
|
||||
"Pendirian CV tidak memiliki batas minimal dan hanya disesuaikan dengan alokasi finansial badan usaha."
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q2",
|
||||
question: "Bolehkah suami-istri mendirikan PT?",
|
||||
blocks: [
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Boleh, dengan syarat utama suami-istri tersebut ketika mendirikan badan hukum PT sudah memiliki Perjanjian Pemisahan Harta (Perjanjian Kawin), karena tanpa perjanjian tersebut suami-istri dianggap sebagai satu subjek hukum sehingga tidak memenuhi syarat minimal dua pendiri."
|
||||
},
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Alternatif lain adalah melibatkan pihak ketiga sebagai pendiri untuk memenuhi syarat minimal dua pendiri. Untuk jenis badan hukum lain seperti PT Perorangan (jika diizinkan), syaratnya berbeda dan tidak memerlukan dua pendiri."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q3",
|
||||
question:
|
||||
"Berapa modal dasar pendirian Koperasi Simpan Pinjam (KSP) dan koperasi umum yang memiliki unit usaha Simpan Pinjam?",
|
||||
blocks: [
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Minimal modal untuk mendirikan Koperasi Simpan Pinjam (KSP) bervariasi tergantung jenisnya dan wilayah keanggotaannya, mulai dari Rp500.000.000 (lima ratus juta rupiah) untuk KSP Primer di kabupaten/kota hingga Rp3.000.000.000 (tiga miliar rupiah) untuk KSP Sekunder dengan keanggotaan lintas provinsi."
|
||||
},
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Untuk Unit Simpan Pinjam (USP), modal tetap yang terpisah dari aset koperasi minimal sebesar Rp500.000.000 (lima ratus juta rupiah) untuk USP koperasi primer."
|
||||
},
|
||||
{
|
||||
type: "p",
|
||||
text: "Untuk Koperasi Simpan Pinjam (KSP):",
|
||||
strong: true
|
||||
},
|
||||
{
|
||||
type: "p",
|
||||
text: "KSP Primer",
|
||||
strong: true
|
||||
},
|
||||
{
|
||||
type: "ul",
|
||||
items: [
|
||||
"Anggota di wilayah kabupaten/kota: minimal Rp500.000.000.",
|
||||
"Anggota lintas kabupaten/kota dalam satu provinsi: minimal Rp1.000.000.000.",
|
||||
"Anggota lintas provinsi: minimal Rp2.000.000.000."
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "p",
|
||||
text: "KSP Sekunder",
|
||||
strong: true
|
||||
},
|
||||
{
|
||||
type: "ul",
|
||||
items: [
|
||||
"Anggota di wilayah kabupaten/kota: minimal Rp50.000.000.",
|
||||
"Anggota lintas kabupaten/kota dalam satu provinsi: minimal Rp150.000.000.",
|
||||
"Anggota lintas provinsi: minimal Rp500.000.000."
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q4",
|
||||
question: "Bagaimana syarat memilih nama PT?",
|
||||
blocks: [
|
||||
{
|
||||
type: "ul",
|
||||
items: [
|
||||
"Nama Perseroan Terbatas (PT) tidak boleh sama dengan yang lain meskipun bidang usaha dan domisili kedua PT berbeda. Larangan tersebut diatur dalam PP No. 43 Tahun 2011 tentang Tata Cara Pengajuan dan Pemakaian Nama Perseroan Terbatas.",
|
||||
"Nama perusahaan harus terdiri dari minimal 3 (tiga) suku kata dengan berbahasa Indonesia. Hal ini dilakukan untuk membedakan nama perusahaan lokal dan perusahaan dengan modal asing. Pasal 11 PP 43/2011 menyatakan, “Perseroan yang seluruh sahamnya dimiliki oleh warga negara Indonesia atau badan hukum Indonesia wajib memakai Bahasa Indonesia.” Nama juga harus menggunakan huruf latin dan tidak menggunakan angka atau gabungan huruf yang tidak membentuk kata.",
|
||||
"Nama perusahaan harus tidak bertentangan dengan ketertiban umum atau kesusilaan. Dengan demikian, penggunaan nama yang mengandung isu SARA ataupun kebencian dan tidak sesuai dengan norma yang berlaku tidak diperkenankan sesuai dengan Pasal 16 ayat (1) UU Perseroan Terbatas."
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q5",
|
||||
question:
|
||||
"Apakah KBLI Perdagangan Besar dan Eceran dapat digabung dalam satu perusahaan?",
|
||||
blocks: [
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"KBLI Perdagangan Besar dan Eceran tidak dapat digabung. Berdasarkan Peraturan Pemerintah No. 29 Tahun 2021 tentang Penyelenggaraan Bidang Perdagangan, untuk bidang usaha perdagangan besar tidak dapat dijalankan secara bersamaan dengan bidang usaha perdagangan eceran, karena dapat berakibat NIB tidak dapat terbit."
|
||||
},
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Perbedaan antara perdagangan besar dan perdagangan eceran secara konkret bisa dilihat pada perbedaan Klasifikasi Baku Lapangan Usaha Indonesia (KBLI) yang menaunginya. Perdagangan besar memiliki awalan KBLI 46, sementara perdagangan eceran KBLI 47."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q6",
|
||||
question:
|
||||
"Berapa lama masa berlaku sertifikat tanah HGB, HGU & Hak Pakai?",
|
||||
blocks: [
|
||||
{
|
||||
type: "ul",
|
||||
items: [
|
||||
"Sertifikat HGB adalah selama 30 tahun, yang dapat diperpanjang maksimal 20 tahun dan diperbarui maksimal 30 tahun.",
|
||||
"Sertifikat HGU adalah selama 35 tahun, yang dapat diperpanjang maksimal 25 tahun dan diperbarui maksimal 35 tahun.",
|
||||
"Sertifikat Hak Pakai adalah selama 30 tahun, yang dapat diperpanjang maksimal 20 tahun dan diperbarui maksimal 30 tahun."
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q7",
|
||||
question: "Apa itu Roya?",
|
||||
blocks: [
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Roya adalah proses penghapusan catatan hak tanggungan (jaminan utang) dari sertifikat tanah atau bangunan setelah utang yang dijaminkan, seperti Kredit Pemilikan Rumah (KPR), telah lunas. Setelah roya selesai, sertifikat tanah tersebut sepenuhnya bersih dan bebas dari beban utang."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q8",
|
||||
question: "Apa itu Peningkatan Sertifikat Hak Milik?",
|
||||
blocks: [
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Peningkatan hak milik adalah proses mengubah status hak atas tanah dari hak yang lebih rendah seperti Hak Guna Bangunan atau Hak Pakai menjadi Hak Milik. Proses ini dilakukan di kantor Badan Pertanahan Nasional (BPN) dengan menyiapkan dokumen persyaratan, mengisi formulir, membayar biaya, dan menunggu pengukuran ulang jika diperlukan, sebelum akhirnya diterbitkan Sertifikat Hak Milik (SHM) yang baru."
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "q9",
|
||||
question: "Apa itu SHMSRS?",
|
||||
blocks: [
|
||||
{
|
||||
type: "p",
|
||||
text:
|
||||
"Sertifikat Hak Milik atas Satuan Rumah Susun (SHMSRS) adalah bukti kepemilikan unit apartemen atau rumah susun secara perorangan, yang juga mencakup hak atas bagian bersama, benda bersama, dan tanah bersama. Sertifikat ini setara dengan hak milik atas tanah dan bangunan, tetapi di sini hak kepemilikan unit bersifat individual sementara hak atas tanahnya adalah kepemilikan bersama yang proporsional."
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
const activeIndex = ref(0);
|
||||
|
||||
function toggle(index) {
|
||||
activeIndex.value = activeIndex.value === index ? null : index;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="faq" id="faq">
|
||||
<div class="container">
|
||||
<h2 class="headline">
|
||||
Pertanyaan Umum Seputar Legalitas Usaha
|
||||
</h2>
|
||||
<div class="description">
|
||||
Temukan jawaban atas pertanyaan yang paling sering diajukan terkait
|
||||
pendirian badan usaha, perizinan, hingga pengurusan sertifikat.
|
||||
</div>
|
||||
|
||||
<div class="faq-list">
|
||||
<div
|
||||
v-for="(item, index) in faqItems"
|
||||
:key="item.id"
|
||||
class="faq-item"
|
||||
:class="{ active: activeIndex === index }"
|
||||
>
|
||||
<button class="faq-question" type="button" @click="toggle(index)">
|
||||
<span class="faq-icon">
|
||||
{{ activeIndex === index ? "-" : "+" }}
|
||||
</span>
|
||||
<span class="faq-question-text">
|
||||
{{ index + 1 }}. {{ item.question }}
|
||||
</span>
|
||||
</button>
|
||||
<div class="faq-answer" v-show="activeIndex === index">
|
||||
<template v-for="(block, blockIndex) in item.blocks" :key="blockIndex">
|
||||
<p v-if="block.type === 'p'">
|
||||
<strong v-if="block.strong">
|
||||
{{ block.text }}
|
||||
</strong>
|
||||
<template v-else>
|
||||
{{ block.text }}
|
||||
</template>
|
||||
</p>
|
||||
<ul v-else-if="block.type === 'ul'">
|
||||
<li v-for="(line, lineIndex) in block.items" :key="lineIndex">
|
||||
{{ line }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.faq {
|
||||
padding: 80px 20px;
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #193b6a;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
color: #111827;
|
||||
margin: 0 0 12px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 15px;
|
||||
line-height: 1.7;
|
||||
color: #6b7280;
|
||||
text-align: center;
|
||||
max-width: 720px;
|
||||
margin: 0 auto 40px;
|
||||
}
|
||||
|
||||
.faq-list {
|
||||
border-top: 1px solid #e1e5f0;
|
||||
}
|
||||
|
||||
.faq-item {
|
||||
border-bottom: 1px solid #e1e5f0;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.faq-question {
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 12px 0;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 16px;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
color: #193b6a;
|
||||
}
|
||||
|
||||
.faq-question-text {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.faq-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 999px;
|
||||
background-color: #e9f0ff;
|
||||
color: #193b6a;
|
||||
border: 1px solid #c3d4ff;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
flex-shrink: 0;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.faq-item.active .faq-icon {
|
||||
background-color: #193b6a;
|
||||
color: #ffffff;
|
||||
border-color: #193b6a;
|
||||
}
|
||||
|
||||
.faq-answer {
|
||||
padding: 0 0 14px 40px;
|
||||
color: #3c4a6b;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.faq-answer ul {
|
||||
margin: 8px 0 0 18px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.faq-answer p {
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.headline {
|
||||
font-size: 38px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.headline {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
221
src/components/main/Hero.vue
Normal file
@ -0,0 +1,221 @@
|
||||
<template>
|
||||
<section
|
||||
class="hero"
|
||||
:style="heroStyle"
|
||||
>
|
||||
<div class="overlay">
|
||||
<div class="hero-content">
|
||||
<h1 class="headline">{{ headline }}</h1>
|
||||
|
||||
<div class="badges">
|
||||
<button
|
||||
v-for="badge in badges"
|
||||
:key="badge.id"
|
||||
class="badge"
|
||||
:class="badge.variant"
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
:src="badge.icon"
|
||||
:alt="badge.alt"
|
||||
class="icon"
|
||||
/>
|
||||
{{ badge.label }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="description">
|
||||
{{ description }}
|
||||
</p>
|
||||
|
||||
<div class="cta-buttons">
|
||||
<button
|
||||
v-for="button in ctaButtons"
|
||||
:key="button.id"
|
||||
class="cta-button"
|
||||
:class="button.variant"
|
||||
type="button"
|
||||
@click="handleCtaClick(button.id)"
|
||||
>
|
||||
{{ button.label }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
import heroBackground from "@/assets/background_hero.png";
|
||||
import iconLaw from "@/assets/icon_law.png";
|
||||
import iconCheck from "@/assets/icon_check.png";
|
||||
|
||||
const headline = "Urus Legalitas Bisnis Tanpa Ribet";
|
||||
const description =
|
||||
"Dari pendirian PT, CV, hingga Yayasan, semua proses hukum lebih cepat, aman, dan transparan bersama tim profesional berpengalaman Solnus secara online.";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const heroStyle = {
|
||||
backgroundImage: `url(${heroBackground})`
|
||||
};
|
||||
|
||||
const badges = [
|
||||
{
|
||||
id: "law-support",
|
||||
label: "Didampingi Tim Hukum",
|
||||
variant: "primary",
|
||||
icon: iconLaw,
|
||||
alt: "Ikon tim hukum"
|
||||
},
|
||||
{
|
||||
id: "verified-partner",
|
||||
label: "Legal Partner Terverifikasi",
|
||||
variant: "secondary",
|
||||
icon: iconCheck,
|
||||
alt: "Ikon verifikasi legal"
|
||||
}
|
||||
];
|
||||
|
||||
const ctaButtons = [
|
||||
{ id: "consult", label: "Jadwalkan Konsultasi Gratis", variant: "primary" },
|
||||
{ id: "services", label: "Lihat Layanan Solnus", variant: "secondary" }
|
||||
];
|
||||
|
||||
const handleCtaClick = (id) => {
|
||||
if (id === "consult") {
|
||||
window.open("https://wa.me/6281234567890", "_blank");
|
||||
} else if (id === "services") {
|
||||
router.push({ path: "/", hash: "#solusi" });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hero {
|
||||
position: relative;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 40px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
max-width: 900px;
|
||||
margin-top: -40px;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-size: 4rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.badges {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
margin-bottom: 30px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 22px;
|
||||
font-weight: 600;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
cursor: default;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.badge.primary {
|
||||
background-color: #b71c1c;
|
||||
}
|
||||
|
||||
.badge.secondary {
|
||||
background-color: #5e0000;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
padding: 14px 28px;
|
||||
font-size: 1.1rem;
|
||||
border-radius: 10px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.cta-button.primary {
|
||||
background-color: #FF6640;
|
||||
color: black;
|
||||
border-color: #FF6640;
|
||||
}
|
||||
|
||||
.cta-button.primary:hover {
|
||||
background-color: #FF6640;
|
||||
border-color: #FF6640;
|
||||
}
|
||||
|
||||
.cta-button.secondary {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
.cta-button.secondary:hover {
|
||||
background-color: white;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.headline {
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1.05rem;
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
170
src/components/main/Menu.vue
Normal file
@ -0,0 +1,170 @@
|
||||
<template>
|
||||
<section id="menu" class="featured">
|
||||
<h2>Popular Dishes</h2>
|
||||
<div class="dishes">
|
||||
<div
|
||||
v-for="dish in dishes"
|
||||
:key="dish.id"
|
||||
class="dish"
|
||||
>
|
||||
<img
|
||||
:src="dish.image"
|
||||
width="280"
|
||||
height="280"
|
||||
:alt="dish.alt"
|
||||
/>
|
||||
<h3>{{ dish.name }}</h3>
|
||||
<p>{{ dish.description }}</p>
|
||||
<div class="card-actions">
|
||||
<a
|
||||
:href="dish.whatsappLink"
|
||||
class="whatsapp-button"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
WhatsApp
|
||||
</a>
|
||||
<button
|
||||
class="detail-button"
|
||||
type="button"
|
||||
>
|
||||
{{ dish.detailLabel }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import spaghettiImg from "@/assets/spaghetti.jpg";
|
||||
import steakImg from "@/assets/steak.jpg";
|
||||
import saladImg from "@/assets/salad.jpg";
|
||||
|
||||
const whatsappLink = "https://wa.me/1234567890";
|
||||
|
||||
const dishes = [
|
||||
{
|
||||
id: "spaghetti",
|
||||
name: "Spaghetti Carbonara",
|
||||
description: "Classic Italian pasta with creamy sauce and pancetta.",
|
||||
image: spaghettiImg,
|
||||
alt: "Spaghetti Carbonara",
|
||||
whatsappLink,
|
||||
detailLabel: "Detail"
|
||||
},
|
||||
{
|
||||
id: "steak",
|
||||
name: "Grilled Steak",
|
||||
description: "Perfectly grilled steak served with mashed potatoes.",
|
||||
image: steakImg,
|
||||
alt: "Grilled Steak",
|
||||
whatsappLink,
|
||||
detailLabel: "Detail"
|
||||
},
|
||||
{
|
||||
id: "salad",
|
||||
name: "Caesar Salad",
|
||||
description: "Fresh greens tossed in Caesar dressing.",
|
||||
image: saladImg,
|
||||
alt: "Caesar Salad",
|
||||
whatsappLink,
|
||||
detailLabel: "Detail"
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#menu {
|
||||
box-sizing: border-box;
|
||||
padding: 100px 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 50px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.dishes {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0 80px;
|
||||
justify-content: space-evenly;
|
||||
}
|
||||
|
||||
.dish {
|
||||
background-color: white;
|
||||
width: 280px;
|
||||
height: 400px;
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-shadow: 0 0 13px 0 rgba(0, 0, 0, 0.3);
|
||||
transition: 300ms;
|
||||
padding: 0 0 20px;
|
||||
}
|
||||
|
||||
.dish:hover {
|
||||
margin-top: -10px;
|
||||
box-shadow: 0 0 20px 1px rgba(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
img {
|
||||
border-radius: 20px 20px 0 0;
|
||||
height: 220px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
p {
|
||||
width: 230px;
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
margin-top: auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 230px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.detail-button {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.detail-button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.whatsapp-button {
|
||||
background-color: #25d366;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.whatsapp-button:hover {
|
||||
background-color: #1ebe5d;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.dishes {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dish {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
53
src/components/main/ReasonsSection.vue
Normal file
@ -0,0 +1,53 @@
|
||||
<script setup>
|
||||
const steps = [
|
||||
{
|
||||
number: '1.',
|
||||
title: 'Konsultasi & Pemilihan Layanan',
|
||||
description: 'Pilih layanan yang sesuai dengan kebutuhan usaha Anda.'
|
||||
},
|
||||
{
|
||||
number: '2.',
|
||||
title: 'Upload & Verifikasi Dokumen',
|
||||
description: 'Kirim dokumen yang dibutuhkan, kami bantu cek kelengkapannya.'
|
||||
},
|
||||
{
|
||||
number: '3.',
|
||||
title: 'Proses oleh Tim Legal',
|
||||
description: 'Dokumen Anda diurus oleh notaris & konsultan hukum terpercaya.'
|
||||
},
|
||||
{
|
||||
number: '4.',
|
||||
title: 'Dokumen Selesai & Dikirim',
|
||||
description: 'Terima semua dokumen resmi dalam bentuk digital dan fisik.'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="reasons">
|
||||
<div class="container">
|
||||
<h2 class="headline">Bagaimana Kami Membantu Anda</h2>
|
||||
<div class="grid">
|
||||
<article v-for="(step, i) in steps" :key="i" class="card">
|
||||
<div class="number-badge">{{ step.number }}</div>
|
||||
<h3 class="card-title">{{ step.title }}</h3>
|
||||
<p class="card-desc">{{ step.description }}</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.reasons { padding: 80px 20px; background: #f9fafb; }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.headline { font-size: 36px; font-weight: 800; text-align: center; margin: 0 0 56px; color: #111827; }
|
||||
.grid { display: grid; gap: 24px; grid-template-columns: 1fr; }
|
||||
@media (min-width: 640px) { .grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (min-width: 1024px) { .grid { grid-template-columns: repeat(4, 1fr); } }
|
||||
.card { background: #fff; padding: 32px 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); text-align: left; }
|
||||
.number-badge { width: 48px; height: 48px; border-radius: 50%; border: 2px solid #e5e7eb; display: flex; align-items: center; justify-content: center; font-size: 18px; font-weight: 700; color: #6b7280; margin-bottom: 16px; }
|
||||
.card-title { font-size: 18px; font-weight: 700; margin: 0 0 12px; color: #111827; line-height: 1.4; }
|
||||
.card-desc { font-size: 14px; line-height: 1.6; color: #6b7280; margin: 0; }
|
||||
@media (min-width: 768px) { .headline { font-size: 40px; } }
|
||||
</style>
|
||||
208
src/components/main/Service.vue
Normal file
@ -0,0 +1,208 @@
|
||||
<template>
|
||||
<div class="service-card">
|
||||
<div class="diamond-wrapper">
|
||||
<div class="diamond-bg"></div>
|
||||
<img
|
||||
:src="image"
|
||||
:alt="title"
|
||||
class="service-image"
|
||||
/>
|
||||
<div class="icon-badge">
|
||||
<svg v-if="!primary" width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19 3H5C3.89543 3 3 3.89543 3 5V19C3 20.1046 3.89543 21 5 21H19C20.1046 21 21 20.1046 21 19V5C21 3.89543 20.1046 3 19 3Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9 9H15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M9 13H15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M9 17H13" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
<svg v-else width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 15C21 15.5304 20.7893 16.0391 20.4142 16.4142C20.0391 16.7893 19.5304 17 19 17H7L3 21V5C3 4.46957 3.21071 3.96086 3.58579 3.58579C3.96086 3.21071 4.46957 3 5 3H19C19.5304 3 20.0391 3.21071 20.4142 3.58579C20.7893 3.96086 21 4.46957 21 5V15Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<!-- Tags -->
|
||||
<div v-if="tags && tags.length > 0" class="tags">
|
||||
<div v-for="(tag, i) in tags" :key="i" class="tag">
|
||||
{{ tag }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="service-title">{{ title }}</h3>
|
||||
|
||||
<p class="service-desc">
|
||||
{{ description }}
|
||||
</p>
|
||||
|
||||
<button
|
||||
class="service-btn"
|
||||
:class="{ primary }"
|
||||
type="button"
|
||||
@click="handleClick"
|
||||
>
|
||||
{{ buttonText }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const { image, title, description, buttonText, primary, tags, routeName } = defineProps({
|
||||
image: { type: String, required: true },
|
||||
title: { type: String, required: true },
|
||||
description: { type: String, required: true },
|
||||
buttonText: { type: String, required: true },
|
||||
primary: { type: Boolean, default: false },
|
||||
tags: { type: Array, default: () => [] },
|
||||
routeName: { type: String, default: "" }
|
||||
});
|
||||
|
||||
const whatsAppUrl = 'https://wa.me/6281234567890';
|
||||
|
||||
const handleClick = () => {
|
||||
if (routeName) {
|
||||
router.push({ name: routeName });
|
||||
} else if (primary || buttonText.includes('Konsultasi')) {
|
||||
window.open(whatsAppUrl, '_blank');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.service-card {
|
||||
background: #f9fafb;
|
||||
padding: 32px 24px;
|
||||
text-align: center;
|
||||
transition: 0.2s ease-in-out;
|
||||
cursor: default;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.service-card:hover {
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Diamond wrapper */
|
||||
.diamond-wrapper {
|
||||
position: relative;
|
||||
width: 260px;
|
||||
height: 240px;
|
||||
margin-bottom: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.diamond-bg {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: linear-gradient(135deg, #FF6640 0%, #e85a30 100%);
|
||||
transform: rotate(45deg);
|
||||
z-index: 1;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.service-image {
|
||||
position: relative;
|
||||
width: 180px;
|
||||
height: 200px;
|
||||
object-fit: cover;
|
||||
object-position: center top;
|
||||
z-index: 2;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.icon-badge {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 20px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.15);
|
||||
z-index: 3;
|
||||
color: #FF6640;
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
.tags {
|
||||
position: absolute;
|
||||
bottom: -8px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
z-index: 3;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
max-width: 220px;
|
||||
}
|
||||
|
||||
.tag {
|
||||
background: rgba(75, 85, 99, 0.88);
|
||||
color: #fff;
|
||||
padding: 7px 14px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Title */
|
||||
.service-title {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 12px;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
/* Description */
|
||||
.service-desc {
|
||||
font-size: 14px;
|
||||
color: #6b7280;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 24px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Button */
|
||||
.service-btn {
|
||||
border: 2px solid #FF6640;
|
||||
padding: 12px 28px;
|
||||
color: #FF6640;
|
||||
font-weight: 600;
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.service-btn:hover {
|
||||
background: #FF6640;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Primary style */
|
||||
.service-btn.primary {
|
||||
background: #FF6640;
|
||||
color: white;
|
||||
border-color: #FF6640;
|
||||
}
|
||||
|
||||
.service-btn.primary:hover {
|
||||
background: #e85a30;
|
||||
border-color: #e85a30;
|
||||
}
|
||||
</style>
|
||||
121
src/components/main/ServiceSection.vue
Normal file
@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<section class="services-wrapper">
|
||||
<div class="container">
|
||||
<div class="eyebrow">SOLUSI LEGAL</div>
|
||||
<h2 class="headline">Semua Urusan Legal Anda,<br/>Kami Bantu Selesaikan</h2>
|
||||
<p class="description">
|
||||
Solnus membantu individu dan perusahaan mengurusberbagai kebutuhan hukum, dari pendirian badan usaha, pengurusan izin, hingga konsultasi legal. Kami menghadirkan kemudahan, transparansi, dan kepastian dalam setiap proses legal yang Anda butuhkan.
|
||||
</p>
|
||||
|
||||
<div class="services-container">
|
||||
<Service
|
||||
v-for="service in services"
|
||||
:key="service.id"
|
||||
:image="service.image"
|
||||
:title="service.title"
|
||||
:description="service.description"
|
||||
:button-text="service.buttonText"
|
||||
:primary="service.primary"
|
||||
:tags="service.tags"
|
||||
:route-name="service.routeName"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Service from "./Service.vue";
|
||||
|
||||
const services = [
|
||||
{
|
||||
id: "business-formation",
|
||||
image: 'https://images.unsplash.com/photo-1560250097-0b93528c311a?w=400&h=400&fit=crop',
|
||||
title: "Pendirian Badan Usaha",
|
||||
description: "Buat PT, CV, atau Yayasan secara online, dengan dokumen resmi Kemenkumham.",
|
||||
buttonText: "Lihat Detail Layanan",
|
||||
primary: false,
|
||||
tags: ['PT', 'CV', 'Yayasan'],
|
||||
routeName: "PackagesPendirian"
|
||||
},
|
||||
{
|
||||
id: "license-nib",
|
||||
image: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=400&h=400&fit=crop',
|
||||
title: "Perizinan & NIB",
|
||||
description: "Dapatkan Nomor Induk Berusaha (NIB) dan izin OSS dengan cepat & aman.",
|
||||
buttonText: "Lihat Detail Layanan",
|
||||
primary: false,
|
||||
tags: [],
|
||||
routeName: "PackagesKhusus"
|
||||
},
|
||||
{
|
||||
id: "legal-consultation",
|
||||
image: 'https://images.unsplash.com/photo-1519085360753-af0119f7cbe7?w=400&h=400&fit=crop',
|
||||
title: "Konsultasi Hukum",
|
||||
description: "Konsultasikan masalah hukum bisnis Anda dengan ahli berpengalaman.",
|
||||
buttonText: "Jadwalkan Konsultasi Gratis",
|
||||
primary: true,
|
||||
tags: ['Lebih baik PT atau CV ya?', 'Ini masih bisa daftar NIB?']
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.services-wrapper {
|
||||
padding: 80px 20px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #FF6640;
|
||||
letter-spacing: 1px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
color: #111827;
|
||||
margin: 0 0 20px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 15px;
|
||||
line-height: 1.7;
|
||||
color: #6b7280;
|
||||
text-align: center;
|
||||
max-width: 800px;
|
||||
margin: 0 auto 56px;
|
||||
}
|
||||
|
||||
.services-container {
|
||||
display: grid;
|
||||
gap: 32px;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.services-container {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.headline {
|
||||
font-size: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.headline {
|
||||
font-size: 28px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
171
src/components/main/ServicesMenu.vue
Normal file
@ -0,0 +1,171 @@
|
||||
<script setup>
|
||||
import { RouterLink } from "vue-router";
|
||||
|
||||
const services = [
|
||||
{
|
||||
id: "pendirian",
|
||||
title: "Paket Pendirian",
|
||||
icon: "🏢",
|
||||
image:
|
||||
"https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?w=400&h=300&fit=crop",
|
||||
routeName: "PackagesPendirian"
|
||||
},
|
||||
{
|
||||
id: "perubahan",
|
||||
title: "Paket Perubahan\n& Pembubaran",
|
||||
icon: "📄",
|
||||
image:
|
||||
"https://images.unsplash.com/photo-1450101499163-c8848c66ca85?w=400&h=300&fit=crop",
|
||||
routeName: "PackagesPerubahan"
|
||||
},
|
||||
{
|
||||
id: "property",
|
||||
title: "Paket Property",
|
||||
icon: "🏠",
|
||||
image:
|
||||
"https://images.unsplash.com/photo-1560518883-ce09059eeffa?w=400&h=300&fit=crop",
|
||||
routeName: "PackagesProperty"
|
||||
},
|
||||
{
|
||||
id: "khusus",
|
||||
title: "Paket Khusus",
|
||||
icon: "⚖️",
|
||||
image:
|
||||
"https://images.unsplash.com/photo-1589829545856-d10d557cf95f?w=400&h=300&fit=crop",
|
||||
routeName: "PackagesKhusus"
|
||||
},
|
||||
{
|
||||
id: "umum",
|
||||
title: "Paket Umum",
|
||||
icon: "🔨",
|
||||
image:
|
||||
"https://images.unsplash.com/photo-1505664194779-8beaceb93744?w=400&h=300&fit=crop",
|
||||
routeName: "PackagesUmum"
|
||||
}
|
||||
];
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="services-menu">
|
||||
<div class="overlay"></div>
|
||||
<div class="container">
|
||||
<h2 class="headline">Layanan Legal Solnus</h2>
|
||||
<div class="cards">
|
||||
<RouterLink
|
||||
v-for="service in services"
|
||||
:key="service.id"
|
||||
:to="{ name: service.routeName }"
|
||||
class="card"
|
||||
>
|
||||
<div class="card-icon">{{ service.icon }}</div>
|
||||
<h3 class="card-title">{{ service.title }}</h3>
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.services-menu {
|
||||
position: relative;
|
||||
padding: 80px 20px;
|
||||
background-image: url('@/assets/service_legal.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.headline {
|
||||
font-size: 36px;
|
||||
font-weight: 800;
|
||||
text-align: center;
|
||||
margin: 0 0 48px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.cards {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.cards {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.cards {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #fff;
|
||||
border-radius: 12px;
|
||||
padding: 32px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
text-decoration: none;
|
||||
transition: transform .2s, box-shadow .2s;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
font-size: 48px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f9fafb;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.headline {
|
||||
font-size: 42px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
92
src/components/main/Testimonial.vue
Normal file
@ -0,0 +1,92 @@
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
name: 'Imam Santosa',
|
||||
role: 'Owner Nona Craft Studio',
|
||||
text: 'Saya sempat ragu bikin PT karena takut ribet dan mahal. Tapi ternyata lewat Solnus, semua prosesnya transparan, cepat, dan saya bisa pantau dari HP. Dalam 7 hari, SK dan NIB saya sudah keluar. Sekarang bisnis saya bisa kerja sama dengan brand besar.',
|
||||
avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=200&h=200&fit=crop'
|
||||
}
|
||||
]
|
||||
|
||||
const current = ref(0)
|
||||
|
||||
function prev() {
|
||||
current.value = (current.value - 1 + testimonials.length) % testimonials.length
|
||||
}
|
||||
|
||||
function next() {
|
||||
current.value = (current.value + 1) % testimonials.length
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="testimonial">
|
||||
<div class="container">
|
||||
<div class="eyebrow">1500+ Pengusaha Telah Buktikan</div>
|
||||
<h2 class="headline">Sekarang Giliran Anda!</h2>
|
||||
|
||||
<div class="card">
|
||||
<div class="author">
|
||||
<img :src="testimonials[current].avatar" :alt="testimonials[current].name" class="avatar" />
|
||||
<div class="meta">
|
||||
<div class="name">{{ testimonials[current].name }}</div>
|
||||
<div class="role">{{ testimonials[current].role }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<blockquote class="quote">
|
||||
"{{ testimonials[current].text }}"
|
||||
</blockquote>
|
||||
|
||||
<div class="stats">
|
||||
<div class="stat">
|
||||
<div class="stat-value">100%</div>
|
||||
<div class="stat-label">Kepuasan pelanggan</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-value">4x</div>
|
||||
<div class="stat-label">Lebih cepat dari proses manual</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="nav">
|
||||
<button @click="prev" class="nav-btn" aria-label="Previous">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5 15L7.5 10L12.5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button @click="next" class="nav-btn" aria-label="Next">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.5 15L12.5 10L7.5 5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.testimonial { padding: 80px 20px; background: #fff; }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.eyebrow { font-size: 16px; font-weight: 600; color: #FF6640; text-align: center; margin: 0 0 12px; letter-spacing: .5px; }
|
||||
.headline { font-size: 40px; font-weight: 800; text-align: center; margin: 0 0 56px; color: #111827; line-height: 1.2; }
|
||||
.card { padding: 48px; background: #f9fafb; border-radius: 16px; position: relative; max-width: 1000px; margin: 0 auto; }
|
||||
.author { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; }
|
||||
.avatar { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; }
|
||||
.meta { display: flex; flex-direction: column; gap: 4px; }
|
||||
.name { font-weight: 700; font-size: 18px; color: #111827; }
|
||||
.role { font-size: 15px; color: #9ca3af; font-style: italic; }
|
||||
.quote { margin: 0 0 32px; font-size: 20px; line-height: 1.7; color: #374151; font-weight: 400; }
|
||||
.stats { display: flex; gap: 48px; margin-bottom: 0; }
|
||||
.stat { }
|
||||
.stat-value { font-size: 28px; font-weight: 800; color: #111827; margin-bottom: 4px; }
|
||||
.stat-label { font-size: 14px; color: #6b7280; }
|
||||
.nav { position: absolute; bottom: 48px; right: 48px; display: flex; gap: 12px; }
|
||||
.nav-btn { width: 44px; height: 44px; border-radius: 50%; border: 1px solid #e5e7eb; background: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all .2s; color: #6b7280; }
|
||||
.nav-btn:hover { background: #f3f4f6; border-color: #d1d5db; color: #111827; }
|
||||
@media (min-width: 768px) { .headline { font-size: 48px; } }
|
||||
@media (max-width: 768px) { .card { padding: 32px 24px; } .nav { position: static; margin-top: 24px; justify-content: center; } .stats { flex-direction: column; gap: 20px; } }
|
||||
</style>
|
||||
67
src/components/main/WhyChoose.vue
Normal file
@ -0,0 +1,67 @@
|
||||
<script setup>
|
||||
const features = [
|
||||
{
|
||||
icon: 'lightning',
|
||||
title: 'Proses Cepat & Efisien',
|
||||
description: 'Semua layanan dilakukan online dengan deadline jelas untuk efisiensi.'
|
||||
},
|
||||
{
|
||||
icon: 'lock',
|
||||
title: 'Aman & Terpercaya',
|
||||
description: 'Dokumen diverifikasi langsung oleh notaris dan instansi resmi.'
|
||||
},
|
||||
{
|
||||
icon: 'star',
|
||||
title: 'Tim Profesional',
|
||||
description: 'Didukung pengacara dan konsultan hukum berpengalaman.'
|
||||
},
|
||||
{
|
||||
icon: 'message',
|
||||
title: 'Proses Transparan',
|
||||
description: 'Anda bisa pantau status dokumen kapan pun.'
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="why-choose">
|
||||
<div class="container">
|
||||
<h2 class="headline">Kenapa Bisnis Memilih Solusi Kami</h2>
|
||||
<div class="grid">
|
||||
<article v-for="(feature, i) in features" :key="i" class="card">
|
||||
<div class="icon-wrapper">
|
||||
<svg v-if="feature.icon === 'lightning'" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13 2L3 14H12L11 22L21 10H12L13 2Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<svg v-else-if="feature.icon === 'lock'" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="3" y="11" width="18" height="11" rx="2" stroke="currentColor" stroke-width="2"/>
|
||||
<path d="M7 11V7C7 4.79086 8.79086 3 11 3H13C15.2091 3 17 4.79086 17 7V11" stroke="currentColor" stroke-width="2"/>
|
||||
</svg>
|
||||
<svg v-else-if="feature.icon === 'star'" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 2L15.09 8.26L22 9.27L17 14.14L18.18 21.02L12 17.77L5.82 21.02L7 14.14L2 9.27L8.91 8.26L12 2Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
<svg v-else-if="feature.icon === 'message'" width="32" height="32" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 11.5C21.0034 12.8199 20.6951 14.1219 20.1 15.3C19.3944 16.7118 18.3098 17.8992 16.9674 18.7293C15.6251 19.5594 14.0782 19.9994 12.5 20C11.1801 20.0035 9.87812 19.6951 8.7 19.1L3 21L4.9 15.3C4.30493 14.1219 3.99656 12.8199 4 11.5C4.00061 9.92179 4.44061 8.37488 5.27072 7.03258C6.10083 5.69028 7.28825 4.6056 8.7 3.90003C9.87812 3.30496 11.1801 2.99659 12.5 3.00003H13C15.0843 3.11502 17.053 3.99479 18.5291 5.47089C20.0052 6.94699 20.885 8.91568 21 11V11.5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="card-title">{{ feature.title }}</h3>
|
||||
<p class="card-desc">{{ feature.description }}</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.why-choose { padding: 80px 20px; background: #111827; }
|
||||
.container { max-width: 1200px; margin: 0 auto; }
|
||||
.headline { font-size: 36px; font-weight: 800; text-align: center; margin: 0 0 56px; color: #fff; line-height: 1.2; }
|
||||
.grid { display: grid; gap: 32px; grid-template-columns: 1fr; }
|
||||
@media (min-width: 640px) { .grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (min-width: 1024px) { .grid { grid-template-columns: repeat(4, 1fr); } }
|
||||
.card { text-align: center; }
|
||||
.icon-wrapper { width: 64px; height: 64px; margin: 0 auto 20px; display: flex; align-items: center; justify-content: center; border-radius: 50%; border: 2px solid rgba(255,255,255,0.2); color: #fff; }
|
||||
.card-title { font-size: 18px; font-weight: 700; margin: 0 0 12px; color: #fff; }
|
||||
.card-desc { font-size: 14px; line-height: 1.6; color: #9ca3af; margin: 0; }
|
||||
@media (min-width: 768px) { .headline { font-size: 40px; } }
|
||||
</style>
|
||||
260
src/components/packages/PackageCard.vue
Normal file
@ -0,0 +1,260 @@
|
||||
<script setup>
|
||||
import addOnIcon from "@/assets/add-on.svg";
|
||||
import checkIcon from "@/assets/check-circle.svg";
|
||||
import xCircleIcon from "@/assets/x-circle.svg";
|
||||
|
||||
const emit = defineEmits(["toggle"]);
|
||||
|
||||
const props = defineProps({
|
||||
title: { type: String, required: true },
|
||||
price: { type: String, required: true },
|
||||
subtitle: { type: String, default: "" },
|
||||
image: { type: String, default: "" },
|
||||
features: { type: Array, default: () => [] },
|
||||
ctaText: { type: String, default: "Konsultasi Gratis" },
|
||||
originalPrice: { type: String, default: "" },
|
||||
expanded: { type: Boolean, default: false },
|
||||
group: { type: String, default: "" }
|
||||
});
|
||||
|
||||
const isPriceLine = (item) =>
|
||||
typeof item === "object" && item.status === "price-line";
|
||||
|
||||
const priceLines = (features) =>
|
||||
features.filter((item) => isPriceLine(item));
|
||||
|
||||
const isPriceTier = (item) =>
|
||||
typeof item === "object" && item.status === "price-tier";
|
||||
|
||||
const priceTiers = (features) =>
|
||||
features.filter((item) => isPriceTier(item));
|
||||
|
||||
const regularFeatures = (features) =>
|
||||
features.filter(
|
||||
(item) => !isPriceLine(item) && !isPriceTier(item)
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article class="card">
|
||||
<div class="media" v-if="image">
|
||||
<img :src="image" :alt="title" class="image-package"/>
|
||||
<template v-if="group !== 'web'">
|
||||
<div class="overlay"></div>
|
||||
<div class="media-text">
|
||||
<h3>{{ title }}</h3>
|
||||
<p>{{ subtitle }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="body">
|
||||
<div v-if="originalPrice" class="original-price">{{ originalPrice }}</div>
|
||||
<div class="price">{{ price }}</div>
|
||||
<button class="toggle-details" type="button" @click="emit('toggle')">
|
||||
<span>{{ expanded ? 'Sembunyikan detail' : 'Lihat selengkapnya' }}</span>
|
||||
<svg :class="['toggle-icon', { expanded }]" width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6 9L12 15L18 9" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="divider"></div>
|
||||
<transition name="features">
|
||||
<div v-if="expanded">
|
||||
<!-- Khusus paket jasa perpajakan: garis harga + bullet -->
|
||||
<template v-if="group === 'tax'">
|
||||
<!-- Tiers (bulanan/tahunan) -->
|
||||
<div v-if="priceTiers(features).length" class="price-tiers">
|
||||
<div
|
||||
v-for="(t, i) in priceTiers(features)"
|
||||
:key="'tier-' + i"
|
||||
class="price-tier"
|
||||
>
|
||||
<div class="price-tier-value">{{ t.price }}</div>
|
||||
<div class="price-tier-desc">{{ t.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul v-if="priceLines(features).length" class="price-lines">
|
||||
<li
|
||||
v-for="(f, i) in priceLines(features)"
|
||||
:key="'price-' + i"
|
||||
class="price-line"
|
||||
>
|
||||
<span class="price-line-label">
|
||||
{{ (typeof f === 'object' ? f.label : f).split('—')[0].trim() }}
|
||||
</span>
|
||||
<span class="price-line-value">
|
||||
{{ (typeof f === 'object' ? f.label : f).split('—')[1]?.trim() }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul
|
||||
v-if="regularFeatures(features).length"
|
||||
class="features"
|
||||
>
|
||||
<li
|
||||
v-for="(f, i) in regularFeatures(features)"
|
||||
:key="'feat-' + i"
|
||||
:class="[
|
||||
'feature-item',
|
||||
typeof f === 'object' && f.status ? f.status : 'include'
|
||||
]"
|
||||
>
|
||||
<!-- Icon include / addon -->
|
||||
<img
|
||||
v-if="typeof f === 'object' && f.status === 'addon'"
|
||||
class="icon"
|
||||
:src="addOnIcon"
|
||||
alt="Add-on"
|
||||
/>
|
||||
<img
|
||||
v-else-if="!(typeof f === 'object' && f.status === 'exclude')"
|
||||
class="icon"
|
||||
:src="checkIcon"
|
||||
alt="Termasuk"
|
||||
/>
|
||||
<!-- Icon exclude -->
|
||||
<img
|
||||
v-else
|
||||
class="icon negative-icon"
|
||||
:src="xCircleIcon"
|
||||
alt="Tidak termasuk"
|
||||
/>
|
||||
<span>{{ typeof f === 'string' ? f : f.label }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<!-- Paket lain: bullet standar -->
|
||||
<ul
|
||||
v-else
|
||||
class="features"
|
||||
>
|
||||
<li
|
||||
v-for="(f, i) in features"
|
||||
:key="i"
|
||||
:class="[
|
||||
'feature-item',
|
||||
typeof f === 'object' && f.status ? f.status : 'include'
|
||||
]"
|
||||
>
|
||||
<!-- Icon include / addon -->
|
||||
<img
|
||||
v-if="typeof f === 'object' && f.status === 'addon'"
|
||||
class="icon"
|
||||
:src="addOnIcon"
|
||||
alt="Add-on"
|
||||
/>
|
||||
<img
|
||||
v-else-if="!(typeof f === 'object' && f.status === 'exclude')"
|
||||
class="icon"
|
||||
:src="checkIcon"
|
||||
alt="Termasuk"
|
||||
/>
|
||||
<!-- Icon exclude -->
|
||||
<img
|
||||
v-else
|
||||
class="icon negative-icon"
|
||||
:src="xCircleIcon"
|
||||
alt="Tidak termasuk"
|
||||
/>
|
||||
<span>{{ typeof f === 'string' ? f : f.label }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</transition>
|
||||
<button class="cta" >
|
||||
<a href="https://wa.me/6281234567890" target="_blank" style="display: flex; align-items: center; color: white; text-decoration: none;">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="margin-right: 6px;">
|
||||
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413Z" fill="currentColor"/>
|
||||
</svg>
|
||||
{{ ctaText }}
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.card { border: 1px solid #e5e7eb; border-radius: 12px; overflow: hidden; background: #fff; display: flex; flex-direction: column; box-shadow: 0 1px 3px rgba(0,0,0,.08); transition: box-shadow .2s; }
|
||||
.card:hover { box-shadow: 0 4px 12px rgba(0,0,0,.12); }
|
||||
.media { position: relative; height: 238px; overflow: hidden; }
|
||||
.media img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
||||
.overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.65) 100%);
|
||||
}
|
||||
.media-text {
|
||||
position: absolute;
|
||||
bottom: 18px;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
}
|
||||
.media-text h3 { margin: 0; font-size: 20px; font-weight: 700; }
|
||||
.media-text p { margin: 4px 0 0; opacity: 0.95; font-size: 13px; }
|
||||
.body { padding: 20px; display: flex; flex-direction: column; gap: 16px; flex: 1; }
|
||||
.price { font-weight: 800; color: #EE3000; font-size: 24px; }
|
||||
.original-price { font-size: 13px; color: #9ca3af; text-decoration: line-through; margin-bottom: 4px; }
|
||||
.features { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; flex: 1; }
|
||||
.features .feature-item { display: flex; align-items: flex-start; gap: 10px; font-size: 14px; line-height: 1.5; color: #374151; }
|
||||
.features .feature-item.exclude { color: #ef4444; }
|
||||
.features .feature-item.addon { color: #494949; }
|
||||
.icon { flex-shrink: 0; margin-top: 2px; }
|
||||
.price-tiers {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.price-tier {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #374151;
|
||||
}
|
||||
.price-tier-value {
|
||||
color: #EE3000;
|
||||
font-weight: 800;
|
||||
}
|
||||
.price-tier-desc {
|
||||
color: #374151;
|
||||
}
|
||||
.price-lines {
|
||||
list-style: none;
|
||||
margin: 0 0 10px;
|
||||
padding: 0;
|
||||
}
|
||||
.price-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: #111827;
|
||||
}
|
||||
.price-line-label {
|
||||
flex: 1;
|
||||
}
|
||||
.price-line-value {
|
||||
white-space: nowrap;
|
||||
color: #EE3000;
|
||||
font-weight: 700;
|
||||
}
|
||||
.toggle-details { margin-top: 4px; padding-top: 8px; border: none; background: transparent; display: flex; align-items: center; justify-content: space-between; width: 100%; font-size: 13px; color: #494949 !important; cursor: pointer; }
|
||||
.toggle-details:hover { color: #111827; }
|
||||
.toggle-icon { transition: transform .2s; }
|
||||
.toggle-icon.expanded { transform: rotate(180deg); }
|
||||
.toggle-details:hover .toggle-icon { transform: translateY(1px); }
|
||||
.toggle-details:hover .toggle-icon.expanded { transform: translateY(1px) rotate(180deg); }
|
||||
.features-enter-active, .features-leave-active { transition: opacity .2s ease, transform .2s ease; }
|
||||
.features-enter-from, .features-leave-to { opacity: 0; transform: translateY(-4px); }
|
||||
.cta { width: 100%; padding: 12px 16px; background: #111827; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 14px; display: flex; align-items: center; justify-content: center; transition: background .2s; }
|
||||
.cta:hover { background: #000; }
|
||||
.divider { height: 1px; background: #e5e7eb; margin: 0; }
|
||||
.image-package{
|
||||
height: 238px
|
||||
}
|
||||
</style>
|
||||
54
src/components/packages/PackagesGrid.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import PackageCard from './PackageCard.vue'
|
||||
|
||||
const props = defineProps({
|
||||
items: { type: Array, default: () => [] },
|
||||
columnsLg: { type: Number, default: 3 }
|
||||
})
|
||||
|
||||
const expandedIndices = ref([])
|
||||
|
||||
const handleToggle = (index) => {
|
||||
if (expandedIndices.value.includes(index)) {
|
||||
expandedIndices.value = expandedIndices.value.filter(i => i !== index)
|
||||
} else {
|
||||
expandedIndices.value = [...expandedIndices.value, index]
|
||||
}
|
||||
}
|
||||
|
||||
const columnsClass = computed(() => {
|
||||
return props.columnsLg === 4 ? 'cols-4-lg' : null
|
||||
})
|
||||
|
||||
const isExpanded = (index) => expandedIndices.value.includes(index)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid" :class="columnsClass">
|
||||
<PackageCard
|
||||
v-for="(p, i) in items"
|
||||
:key="i"
|
||||
:title="p.title"
|
||||
:subtitle="p.subtitle"
|
||||
:price="p.price"
|
||||
:image="p.image"
|
||||
:features="p.features"
|
||||
:cta-text="p.ctaText"
|
||||
:original-price="p.originalPrice"
|
||||
:group="p.group"
|
||||
:expanded="isExpanded(i)"
|
||||
@toggle="handleToggle(i)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: 16px; align-items: flex-start; }
|
||||
@media (min-width: 0px) { .grid { grid-template-columns: 1fr; } }
|
||||
@media (min-width: 640px) { .grid { grid-template-columns: repeat(2, 1fr); } }
|
||||
@media (min-width: 1024px) {
|
||||
.grid { grid-template-columns: repeat(3, 1fr); }
|
||||
.grid.cols-4-lg { grid-template-columns: repeat(4, 1fr); }
|
||||
}
|
||||
</style>
|
||||
72
src/components/packages/PackagesSection.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<script setup>
|
||||
import { TABS as tabs, DATA_BY_TAB as dataByTab } from './data.js'
|
||||
import { computed } from 'vue'
|
||||
import PackagesGrid from './PackagesGrid.vue'
|
||||
|
||||
const props = defineProps({
|
||||
initialCategory: { type: String, default: null }
|
||||
})
|
||||
|
||||
// If no category specified, show all packages
|
||||
const currentCategory = computed(() => props.initialCategory || null)
|
||||
|
||||
const isLainnya = computed(() => currentCategory.value === 'lainnya')
|
||||
|
||||
const currentData = computed(() => {
|
||||
if (!currentCategory.value) {
|
||||
// Show all packages from all categories
|
||||
return Object.values(dataByTab).flat()
|
||||
}
|
||||
if (isLainnya.value) {
|
||||
// Not used directly in template for "lainnya"
|
||||
return dataByTab.lainnya || []
|
||||
}
|
||||
return dataByTab[currentCategory.value] || []
|
||||
})
|
||||
|
||||
const taxPackages = computed(() => {
|
||||
if (!isLainnya.value) return []
|
||||
return (dataByTab.lainnya || []).filter(p => p.group === 'tax')
|
||||
})
|
||||
|
||||
const websitePackages = computed(() => {
|
||||
if (!isLainnya.value) return []
|
||||
return (dataByTab.lainnya || []).filter(p => p.group === 'web')
|
||||
})
|
||||
|
||||
const headline = computed(() => {
|
||||
if (!currentCategory.value) {
|
||||
return 'Semua Paket Layanan'
|
||||
}
|
||||
const tab = tabs.find(t => t.key === currentCategory.value)
|
||||
return tab ? tab.label : 'Paket Layanan'
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="packages">
|
||||
<div class="container">
|
||||
<template v-if="!isLainnya">
|
||||
<h2 class="headline">{{ headline }}</h2>
|
||||
<PackagesGrid :items="currentData" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<h2 class="headline">Paket Jasa Perpajakan</h2>
|
||||
<PackagesGrid :items="taxPackages" />
|
||||
|
||||
<h2 class="headline headline-secondary">
|
||||
Paket Pembuatan Website
|
||||
</h2>
|
||||
<PackagesGrid :items="websitePackages" :columns-lg="4" />
|
||||
</template>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.packages { padding: 80px 0; background: #fff; margin-top: 60px; }
|
||||
.container { max-width: 1200px; margin: 0 auto; padding: 0 20px; }
|
||||
.headline { font-size: 32px; font-weight: 800; text-align: center; margin: 0 0 40px; color: #111827; }
|
||||
.headline-secondary { margin-top: 72px; }
|
||||
@media (min-width: 768px) { .headline { font-size: 40px; margin-bottom: 48px; } }
|
||||
</style>
|
||||
792
src/components/packages/data.js
Normal file
@ -0,0 +1,792 @@
|
||||
import yayasanImg from "@/assets/service_legal.jpg";
|
||||
import propertyHeroImg from "@/assets/business-hero.png";
|
||||
import certificateHeroImg from "@/assets/hero.png";
|
||||
import electronicCertImg from "@/assets/background_hero.png";
|
||||
import packageBronzeImg from "@/assets/package-bronze.png";
|
||||
import packageSilverImg from "@/assets/package-silver.png";
|
||||
import packageGoldImg from "@/assets/package-gold.png";
|
||||
import packagePlatinumImg from "@/assets/package-platinum.png";
|
||||
|
||||
export const TABS = [
|
||||
{ key: 'pendirian', label: 'Paket Pendirian' },
|
||||
{ key: 'perubahan', label: 'Paket Perubahan & Pembubaran' },
|
||||
{ key: 'property', label: 'Paket Property' },
|
||||
{ key: 'khusus', label: 'Paket Khusus' },
|
||||
{ key: 'umum', label: 'Paket Umum' },
|
||||
{ key: 'lainnya', label: 'Paket Lainnya' }
|
||||
]
|
||||
|
||||
const basePendirianFeatures = [
|
||||
{ label: 'Akta Pendirian', status: 'include' },
|
||||
{ label: 'SK Pendirian AHU (Kemenkum)', status: 'include' },
|
||||
{ label: 'NIB', status: 'include' },
|
||||
{ label: 'Akun OSS', status: 'include' },
|
||||
{ label: 'K3L', status: 'include' },
|
||||
{ label: 'SPPL', status: 'include' },
|
||||
{ label: 'Pernyataan Mandiri', status: 'include' },
|
||||
{ label: 'Sertifikat Standar (untuk KBLI tertentu)', status: 'include' },
|
||||
{ label: 'Hasil Penapisan Dokumen Amdalnet (untuk KBLI tertentu)', status: 'include' },
|
||||
{ label: 'NPWP', status: 'include' },
|
||||
{ label: 'Akun Coretax', status: 'include' },
|
||||
{ label: 'SKT Pajak', status: 'include' },
|
||||
{ label: 'Surat Penerbitan Akun Pajak', status: 'include' },
|
||||
{ label: 'Bukti Penerimaan Surat Pendaftaran Wajib Pajak', status: 'include' },
|
||||
{ label: 'Email Badan', status: 'include' },
|
||||
{ label: 'Stempel/Cap Badan', status: 'include' },
|
||||
{ label: 'Free Pengecekan Nama', status: 'include' },
|
||||
{ label: 'Free Konsultasi', status: 'include' },
|
||||
// Fitur khusus koperasi (default tidak termasuk)
|
||||
{ label: 'Free Rekomendasi Pembukaan Rekening Badan', status: 'exclude' },
|
||||
{ label: 'Sertifikat NIK', status: 'exclude' },
|
||||
{ label: 'Nomor Induk Koperasi (NIK)', status: 'exclude' },
|
||||
{ label: 'Contoh RAT Koperasi', status: 'exclude' },
|
||||
{ label: 'Template Laporan Pengawas', status: 'exclude' },
|
||||
{ label: 'Template Laporan Pengurus', status: 'exclude' }
|
||||
]
|
||||
|
||||
const basePerubahanFeatures = [
|
||||
{ label: 'Akta Perubahan', status: 'include' },
|
||||
{ label: 'SK Perubahan/SP Perubahan AHU (Kemenkum RI)', status: 'include' },
|
||||
{ label: 'Softcopy File Dokumen (Pdf)', status: 'include' },
|
||||
{ label: 'Free Konsultasi', status: 'include' }
|
||||
]
|
||||
|
||||
const img = (q) => `https://images.unsplash.com/${q}&auto=format&fit=crop&w=1200&q=60`
|
||||
|
||||
export const DATA_BY_TAB = {
|
||||
pendirian: [
|
||||
{
|
||||
title: 'Pendirian PT',
|
||||
subtitle: 'Mulai Langkah Pertama Bisnis Resmi Anda',
|
||||
originalPrice: 'Rp 5,5 Juta',
|
||||
price: 'Rp 3,850 K',
|
||||
image: img('photo-1520975916090-3105956dac38?ixlib=rb-4.0.3'),
|
||||
features: basePendirianFeatures
|
||||
},
|
||||
{
|
||||
title: 'Paket Level Up',
|
||||
subtitle: 'Saatnya Naik Kelas & Siap Dapat Klien Besar',
|
||||
originalPrice: 'Rp 5,5 Juta',
|
||||
price: 'Rp 3,200 K',
|
||||
image: img('photo-1517245386807-bb43f82c33c4?ixlib=rb-4.0.3'),
|
||||
features: basePendirianFeatures
|
||||
},
|
||||
{
|
||||
title: 'Pendirian Yayasan',
|
||||
subtitle: 'Yayasan Resmi, Siap Operasional Penuh',
|
||||
originalPrice: 'Rp 5,5 Juta',
|
||||
price: 'Rp 3,800 K',
|
||||
image: yayasanImg,
|
||||
features: basePendirianFeatures
|
||||
},
|
||||
{
|
||||
title: 'Pendirian Firma',
|
||||
subtitle: 'Mulai Langkah Pertama Bisnis Resmi Anda',
|
||||
originalPrice: 'Rp 5,5 Juta',
|
||||
price: 'Rp 3,500 K',
|
||||
image: img('photo-1525182008055-f88b95ff7980?ixlib=rb-4.0.3'),
|
||||
features: basePendirianFeatures
|
||||
},
|
||||
{
|
||||
title: 'Pendirian Perkumpulan',
|
||||
subtitle: 'Mulai Langkah Pertama Bisnis Resmi Anda',
|
||||
originalPrice: 'Rp 7,5 Juta',
|
||||
price: 'Rp 5,000 K',
|
||||
image: img('photo-1521737604893-d14cc237f11d?ixlib=rb-4.0.3'),
|
||||
features: basePendirianFeatures
|
||||
},
|
||||
{
|
||||
title: 'Pendirian Persekutuan Perdata',
|
||||
subtitle: 'Mulai Langkah Pertama Bisnis Resmi Anda',
|
||||
originalPrice: 'Rp 5,5 Juta',
|
||||
price: 'Rp 3,500 K',
|
||||
image: img('photo-1538688423619-a81d3f23454b?ixlib=rb-4.0.3'),
|
||||
features: basePendirianFeatures
|
||||
},
|
||||
{
|
||||
title: 'Pendirian Koperasi',
|
||||
subtitle: 'Mulai Langkah Pertama Bisnis Resmi Anda',
|
||||
originalPrice: 'Rp 10,25 Juta',
|
||||
price: 'Rp 8,500 K',
|
||||
image: img('photo-1520607162513-77705c0f0d4a?ixlib=rb-4.0.3'),
|
||||
features: [
|
||||
// Semua fitur pendirian + seluruh benefit koperasi sebagai checklist
|
||||
...basePendirianFeatures.map(f => ({ ...f, status: 'include' })),
|
||||
{ label: 'Konfirmasi Kesesuaian Kegiatan Pemanfaatan Ruang', status: 'include' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Pendirian PT Perseorangan',
|
||||
subtitle: 'Mulai Langkah Pertama Bisnis Resmi Anda',
|
||||
originalPrice: 'Rp 2,5 Juta',
|
||||
price: 'Rp 1,200 K',
|
||||
image: img('photo-1519340241574-2cec6aef0c01?ixlib=rb-4.0.3'),
|
||||
features: [
|
||||
{ label: 'Sertifikat Pendaftaran Pendirian Perseorangan (Kemenkum)', status: 'include' },
|
||||
{ label: 'Pernyataan Pendirian Kemenkum', status: 'include' },
|
||||
{ label: 'NIB', status: 'include' },
|
||||
{ label: 'Akun OSS', status: 'include' },
|
||||
{ label: 'Konfirmasi Kesesuaian Kegiatan Pemanfaatan Ruang', status: 'include' },
|
||||
{ label: 'SPPL', status: 'include' },
|
||||
{ label: 'Sertifikat Standar (untuk KBLI tertentu)', status: 'include' },
|
||||
{ label: 'Hasil Penapisan Dokumen Amdalnet (untuk KBLI tertentu)', status: 'include' },
|
||||
{ label: 'NPWP', status: 'include' },
|
||||
{ label: 'Akun Coretax', status: 'include' },
|
||||
{ label: 'SKT Pajak', status: 'include' },
|
||||
{ label: 'Surat Penerbitan Akun Pajak', status: 'include' },
|
||||
{ label: 'Bukti Penerimaan Surat Pendaftaran Wajib Pajak', status: 'include' },
|
||||
{ label: 'Email Badan', status: 'include' },
|
||||
{ label: 'Stempel/Cap Badan', status: 'include' },
|
||||
{ label: 'Free Pengecekan Nama', status: 'include' },
|
||||
{ label: 'Free Konsultasi', status: 'include' },
|
||||
{ label: 'Add on Akta Pendirian Rp 2,000,000', status: 'addon' },
|
||||
{ label: 'Free Rekomendasi Pembukaan Rekening Badan', status: 'exclude' },
|
||||
{ label: 'Nomor Induk Koperasi (NIK)', status: 'exclude' },
|
||||
{ label: 'Contoh RAT Koperasi', status: 'exclude' },
|
||||
{ label: 'Template Laporan Pengawas', status: 'exclude' },
|
||||
{ label: 'Template Laporan Pengurus', status: 'exclude' },
|
||||
{ label: 'Akta Pendirian', status: 'exclude' },
|
||||
{ label: 'SK Pendirian AHU (Kemenkum)', status: 'exclude' }
|
||||
]
|
||||
}
|
||||
],
|
||||
perubahan: [
|
||||
{
|
||||
title: 'Perubahan PT',
|
||||
subtitle: 'Start from Rp 5,5 Juta',
|
||||
originalPrice: 'Start from Rp 5,5 Juta',
|
||||
price: 'Rp 3,550 K',
|
||||
image: img('photo-1520975916090-3105956dac38?ixlib=rb-4.0.3'),
|
||||
features: basePerubahanFeatures
|
||||
},
|
||||
{
|
||||
title: 'Perubahan CV',
|
||||
subtitle: 'Start from Rp 5,5 Juta',
|
||||
originalPrice: 'Start from Rp 5,5 Juta',
|
||||
price: 'Rp 3,250 K',
|
||||
image: img('photo-1517245386807-bb43f82c33c4?ixlib=rb-4.0.3'),
|
||||
features: basePerubahanFeatures
|
||||
},
|
||||
{
|
||||
title: 'Perubahan Yayasan',
|
||||
subtitle: 'Start from Rp 5,5 Juta',
|
||||
originalPrice: 'Start from Rp 5,5 Juta',
|
||||
price: 'Rp 3,500 K',
|
||||
image: yayasanImg,
|
||||
features: basePerubahanFeatures
|
||||
},
|
||||
{
|
||||
title: 'Perubahan Firma',
|
||||
subtitle: 'Start from Rp 5,5 Juta',
|
||||
originalPrice: 'Start from Rp 5,5 Juta',
|
||||
price: 'Rp 3,500 K',
|
||||
image: img('photo-1525182008055-f88b95ff7980?ixlib=rb-4.0.3'),
|
||||
features: basePerubahanFeatures
|
||||
},
|
||||
{
|
||||
title: 'Perubahan Perkumpulan',
|
||||
subtitle: 'Start from Rp 5,5 Juta',
|
||||
originalPrice: 'Start from Rp 5,5 Juta',
|
||||
price: 'Rp 4,850 K',
|
||||
image: img('photo-1521737604893-d14cc237f11d?ixlib=rb-4.0.3'),
|
||||
features: basePerubahanFeatures
|
||||
},
|
||||
{
|
||||
title: 'Perubahan Persekutuan Perdata',
|
||||
subtitle: 'Start from Rp 5,5 Juta',
|
||||
originalPrice: 'Start from Rp 5,5 Juta',
|
||||
price: 'Rp 3,100 K',
|
||||
image: img('photo-1538688423619-a81d3f23454b?ixlib=rb-4.0.3'),
|
||||
features: basePerubahanFeatures
|
||||
},
|
||||
{
|
||||
title: 'Perubahan Koperasi',
|
||||
subtitle: 'Start from Rp 10,5 Juta',
|
||||
originalPrice: 'Start from Rp 10,5 Juta',
|
||||
price: 'Rp 3,100 K',
|
||||
image: img('photo-1520607162513-77705c0f0d4a?ixlib=rb-4.0.3'),
|
||||
features: basePerubahanFeatures
|
||||
},
|
||||
{
|
||||
title: 'Perubahan PT Perseorangan',
|
||||
subtitle: 'Start from Rp 3,5 Juta',
|
||||
originalPrice: 'Start from Rp 3,5 Juta',
|
||||
price: 'Rp 1,200 K',
|
||||
image: img('photo-1519340241574-2cec6aef0c01?ixlib=rb-4.0.3'),
|
||||
features: [
|
||||
...basePerubahanFeatures,
|
||||
{ label: 'Add on Akta Perubahan Rp 2,000,000', status: 'addon' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Pembubaran Badan Hukum',
|
||||
subtitle: 'Start from Rp 15,5 Juta',
|
||||
originalPrice: 'Start from Rp 15,5 Juta',
|
||||
price: 'Rp 9,800 K',
|
||||
image: img('photo-1520607162513-77705c0f0d4a?ixlib=rb-4.0.3'),
|
||||
features: [
|
||||
{ label: 'Akta Perubahan', status: 'include' },
|
||||
{ label: 'Pengumuman Koran', status: 'include' },
|
||||
{ label: 'BNRI', status: 'include' },
|
||||
{ label: 'SK Pembubaran AHU (Kemenkum RI)', status: 'include' },
|
||||
{ label: 'Softcopy File Dokumen (Pdf)', status: 'include' },
|
||||
{ label: 'Free Konsultasi', status: 'include' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Perubahan Badan Usaha',
|
||||
subtitle: 'Start from Rp 10,5 Juta',
|
||||
originalPrice: 'Start from Rp 10,5 Juta',
|
||||
price: 'Rp 8,500 K',
|
||||
image: img('photo-1520607162513-77705c0f0d4a?ixlib=rb-4.0.3'),
|
||||
features: [
|
||||
{ label: 'Akta Perubahan', status: 'include' },
|
||||
{ label: 'Pengumuman Koran', status: 'include' },
|
||||
{ label: 'SK Pembubaran AHU (Kemenkum RI)', status: 'include' },
|
||||
{ label: 'Softcopy File Dokumen (Pdf)', status: 'include' },
|
||||
{ label: 'Free Konsultasi', status: 'include' }
|
||||
]
|
||||
}
|
||||
],
|
||||
property: [
|
||||
{
|
||||
title: "Jasa Agen Property",
|
||||
subtitle: "Start from Rp 7,5 Juta",
|
||||
originalPrice: "Start from Rp 7,5 Juta",
|
||||
price: "Rp 5,500 K",
|
||||
image: img("photo-1560518883-ce09059eeffa?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Pemasangan Iklan (Spanduk & Media Sosial)", status: "include" },
|
||||
{ label: "Pengecekan Sertifikat oleh BPN", status: "include" },
|
||||
{ label: "Pengurusan Jual Beli (Akta Jual Beli)", status: "include" },
|
||||
{ label: "Pengurusan Pajak Jual Beli", status: "include" },
|
||||
{ label: "Pengurusan Balik Nama Sertifikat Tanah", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Penyewaan Property",
|
||||
subtitle: "Start from Rp 5,5 Juta",
|
||||
originalPrice: "Start from Rp 5,5 Juta",
|
||||
price: "Rp 3,500 K",
|
||||
image: img("photo-1560520653-9e0e4c89eb11?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Pemasangan Iklan (Spanduk & Media Sosial)", status: "include" },
|
||||
{ label: "Pengecekan Sertifikat oleh BPN", status: "include" },
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" },
|
||||
{ label: "Pengurusan Pajak Jual Beli", status: "exclude" },
|
||||
{ label: "Pengurusan Balik Nama Sertifikat Tanah", status: "exclude" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Balik Nama Sertifikat Tanah",
|
||||
subtitle: "Berdasarkan jual-beli, waris, hibah wasiat",
|
||||
originalPrice: "Start from Rp 6,5 Juta",
|
||||
price: "Rp 4,800 K",
|
||||
image: img("photo-1568602471122-7832951cc4c5?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Pengecekan Sertifikat Tanah oleh BPN", status: "include" },
|
||||
{ label: "Akta Otentik (Jual Beli/Hibah/Waris)", status: "include" },
|
||||
{ label: "Pengurusan Pajak Jual Beli", status: "include" },
|
||||
{ label: "Pengurusan Balik Nama Sertifikat Tanah", status: "include" },
|
||||
{ label: "Sertifikat Tanah (Berdasarkan jual-beli/waris/hibah wasiat)", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pemecahan, Pemisahan & Penggabungan Sertifikat Tanah",
|
||||
subtitle: "Start from Rp 6 Juta",
|
||||
originalPrice: "Start from Rp 6 Juta",
|
||||
price: "Rp 4,500 K",
|
||||
image: propertyHeroImg,
|
||||
features: [
|
||||
{ label: "Pengecekan Sertifikat Tanah di BPN", status: "include" },
|
||||
{ label: "Pengurusan Tanah oleh BPN", status: "include" },
|
||||
{ label: "Sertifikat Tanah (Hasil Pecahan/Pemisahan/Penggabungan)", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Perpanjangan Sertifikat Tanah",
|
||||
subtitle: "atau pembaruan (HGB, HGU, Hak Pakai)",
|
||||
originalPrice: "Start from Rp 6 Juta",
|
||||
price: "Rp 4,300 K",
|
||||
image: img("photo-1589923188900-85dae523342b?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Pengecekan Sertifikat Tanah di BPN", status: "include" },
|
||||
{ label: "Pengurusan Tanah oleh BPN (Jika perlu)", status: "include" },
|
||||
{ label: "Sertifikat Tanah (Hasil Perpanjangan)", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Peningkatan & Penurunan Status Hak Atas Tanah",
|
||||
subtitle: "Start from Rp 5,5 Juta",
|
||||
originalPrice: "Start from Rp 5,5 Juta",
|
||||
price: "Rp 4,800 K",
|
||||
image: img("photo-1500382017468-9049fed747ef?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Pengecekan Sertifikat Tanah di BPN", status: "include" },
|
||||
{ label: "Pengurusan Sertifikat Tanah oleh BPN (Jika perlu)", status: "include" },
|
||||
{ label: "Sertifikat Tanah (Hasil Peningkatan & Penurunan)", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pengurusan Sertifikat Baru",
|
||||
subtitle: "Start from Rp 4,5 Juta",
|
||||
originalPrice: "Start from Rp 4,5 Juta",
|
||||
price: "Rp 3,800 K",
|
||||
image: certificateHeroImg,
|
||||
features: [
|
||||
{ label: "Pengukuran Tanah oleh BPN", status: "include" },
|
||||
{ label: "Sertifikat Tanah", status: "include" },
|
||||
{ label: "Pengurusan Pajak PBB", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pengurusan Sertifikat Elektronik",
|
||||
subtitle: "dari sertifikat analog/model lama",
|
||||
originalPrice: "Start from Rp 4,5 Juta",
|
||||
price: "Rp 2,500 K",
|
||||
image: electronicCertImg,
|
||||
features: [
|
||||
{ label: "Sertifikat Tanah", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Roya Sertifikat Tanah",
|
||||
subtitle: "Start from Rp 3,5 Juta",
|
||||
originalPrice: "Start from Rp 3,5 Juta",
|
||||
price: "Rp 1,800 K",
|
||||
image: img("photo-1531297484001-80022131f5a1?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Bukti Roya", status: "include" },
|
||||
{ label: "Sertifikat Tanah (setelah Roya)", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pengecekan Sertifikat Tanah",
|
||||
subtitle: "Start from Rp 2,5 Juta",
|
||||
originalPrice: "Start from Rp 2,5 Juta",
|
||||
price: "Rp 1,000 K",
|
||||
image: img("photo-1518733057094-95b53143d2a7?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Pengecekan Sertifikat Tanah oleh BPN", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
}
|
||||
],
|
||||
khusus: [
|
||||
{
|
||||
title: "Jasa Pembuatan Nomor Induk Berusaha (NIB)",
|
||||
subtitle: "Start from Rp 1,5 Juta",
|
||||
originalPrice: "Start from Rp 1,5 Juta",
|
||||
price: "Rp 1,000 K",
|
||||
image: certificateHeroImg,
|
||||
features: [
|
||||
{ label: "Nomor Induk Berusaha (NIB)", status: "include" },
|
||||
{ label: "Akun OSS", status: "include" },
|
||||
{ label: "Konfirmasi Kesesuaian Kegiatan Pemanfaatan Ruang", status: "include" },
|
||||
{ label: "SPPL", status: "include" },
|
||||
{ label: "Hasil Penapisan Dokumen Amdalnet (untuk KBLI tertentu)", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Nomor Pokok Wajib Pajak (NPWP)",
|
||||
subtitle: "Start from Rp 2,5 Juta",
|
||||
originalPrice: "Start from Rp 2,5 Juta",
|
||||
price: "Rp 600 K",
|
||||
image: propertyHeroImg,
|
||||
features: [
|
||||
{ label: "NPWP", status: "include" },
|
||||
{ label: "Akun Coretax", status: "include" },
|
||||
{ label: "SKT Pajak", status: "include" },
|
||||
{ label: "Surat Penerbitan Akun Pajak", status: "include" },
|
||||
{ label: "Bukti Penerimaan Surat Pendaftaran Wajib Pajak", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" },
|
||||
{ label: "Nomor Induk Berusaha (NIB)", status: "exclude" },
|
||||
{ label: "Akun OSS", status: "exclude" },
|
||||
{ label: "SPPL", status: "exclude" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Sertifikat Koperasi (Nomor Induk Koperasi)",
|
||||
subtitle: "Start from Rp 12,5 Juta",
|
||||
originalPrice: "Start from Rp 12,5 Juta",
|
||||
price: "Rp 9,850 K",
|
||||
image: yayasanImg,
|
||||
features: [
|
||||
{ label: "Sertifikat Koperasi", status: "include" },
|
||||
{ label: "Nomor Induk Koperasi (NIK)", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah di legalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" },
|
||||
{ label: "Nomor Induk Berusaha (NIB)", status: "exclude" },
|
||||
{ label: "Akun OSS", status: "exclude" },
|
||||
{ label: "NPWP", status: "exclude" },
|
||||
{ label: "SKT Pajak", status: "exclude" },
|
||||
{ label: "Akun Coretax", status: "exclude" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pendaftaran Hak Merek, Hak Paten, dan Hak Cipta",
|
||||
subtitle: "Start from Rp 6 Juta",
|
||||
originalPrice: "Start from Rp 6 Juta",
|
||||
price: "Rp 4,500 K",
|
||||
image: img("photo-1473496169904-658ba7c44d8a?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Sertifikat pendaftaran dari DJKI Kemenkum RI", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah di legalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Izin Amdal",
|
||||
subtitle: "Start from Rp 5 Juta",
|
||||
originalPrice: "Start from Rp 5 Juta",
|
||||
price: "Rp 3,500 K",
|
||||
image: electronicCertImg,
|
||||
features: [
|
||||
{ label: "Fotocopy Dokumen Akta yang telah di legalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan PKKPR",
|
||||
subtitle: "Start from Rp 5,5 Juta",
|
||||
originalPrice: "Start from Rp 5,5 Juta",
|
||||
price: "Rp 3,800 K",
|
||||
image: img("photo-1520607162513-77705c0f0d4a?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Fotocopy Dokumen Akta yang telah di legalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Logo, Stempel, Kop Surat, dll.",
|
||||
subtitle: "Start from Rp 5 Juta",
|
||||
originalPrice: "Start from Rp 5 Juta",
|
||||
price: "Rp 550 K",
|
||||
image: img("photo-1515378791036-0648a3ef77b2?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Logo", status: "include" },
|
||||
{ label: "Stempel / Cap", status: "include" },
|
||||
{ label: "Kop Surat", status: "include" },
|
||||
{ label: "Company Profile", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pengurusan Legalitas Kapal",
|
||||
subtitle: "Start from Rp 15 Juta",
|
||||
originalPrice: "Start from Rp 15 Juta",
|
||||
price: "Rp 9,850 K",
|
||||
image: img("photo-1505839673365-e3971f8d9184?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris (Jual Beli, Hibah, Waris, Hibah Wasiat)", status: "include" },
|
||||
{ label: "Dokumen Status Kapal dari Direktorat Jenderal Perhubungan Laut di Kementerian Perhubungan RI", status: "include" },
|
||||
{ label: "Proses Balik Nama Kepemilikan Kapal (Grosse Kapal)", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah di legalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pemasangan Jaminan Hipotek Kapal",
|
||||
subtitle: "Start from Rp 15 Juta",
|
||||
originalPrice: "Start from Rp 15 Juta",
|
||||
price: "Rp 9,850 K",
|
||||
image: img("photo-1504711434969-e33886168f5c?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris (Jual Beli, Hibah, Waris, Hibah Wasiat)", status: "include" },
|
||||
{ label: "Dokumen Status Kapal dari Direktorat Jenderal Perhubungan Laut di Kementerian Perhubungan RI", status: "include" },
|
||||
{ label: "Proses Balik Nama Kepemilikan Kapal (Grosse Kapal)", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah di legalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
}
|
||||
],
|
||||
umum: [
|
||||
{
|
||||
title: "Jasa Pembuatan Wasiat",
|
||||
subtitle: "Start from Rp 5,5 Juta",
|
||||
originalPrice: "Start from Rp 5,5 Juta",
|
||||
price: "Rp 4,850 K",
|
||||
image: img("photo-1517248135467-4c7edcad34c4?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Pendaftaran Wasiat di Balai Harta Peninggalan (BHP)", status: "include" },
|
||||
{ label: "Pengecekan Wasiat (Dokumen Pengecekan Wasiat dari AHU Kemenkum RI)", status: "include" },
|
||||
{ label: "Fotocopy Dokumen yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Surat Keterangan Waris & Pernyataan Ahli Waris",
|
||||
subtitle: "Start from Rp 7,5 Juta",
|
||||
originalPrice: "Start from Rp 7,5 Juta",
|
||||
price: "Rp 5,550 K",
|
||||
image: img("photo-1517248135467-4c7edcad34c4?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris (Pernyataan Ahli Waris)", status: "include" },
|
||||
{ label: "Surat Keterangan Waris (SKW)", status: "include" },
|
||||
{ label: "Pengecekan Wasiat (Dokumen Pengecekan Wasiat dari AHU Kemenkum RI)", status: "include" },
|
||||
{ label: "Fotocopy Dokumen yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Perjanjian Kawin",
|
||||
subtitle: "Start from Rp 5,5 Juta",
|
||||
originalPrice: "Start from Rp 5,5 Juta",
|
||||
price: "Rp 3,850 K",
|
||||
image: img("photo-1521791136064-7986c2920216?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Perjanjian Kerjasama",
|
||||
subtitle: "Start from Rp 4 Juta",
|
||||
originalPrice: "Start from Rp 4 Juta",
|
||||
price: "Rp 2,850 K",
|
||||
image: img("photo-1520607162513-77705c0f0d4a?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Pemberian Kuasa",
|
||||
subtitle: "Start from Rp 3,5 Juta",
|
||||
originalPrice: "Start from Rp 3,5 Juta",
|
||||
price: "Rp 1,550 K",
|
||||
image: img("photo-1554224154-22dec7ec8818?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Perjanjian Hutang Piutang",
|
||||
subtitle: "Start from Rp 5,5 Juta",
|
||||
originalPrice: "Start from Rp 5,5 Juta",
|
||||
price: "Rp 3,550 K",
|
||||
image: propertyHeroImg,
|
||||
features: [
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Legalitas & Waarmerking Dokumen",
|
||||
subtitle: "Start from Rp 5 Juta",
|
||||
originalPrice: "Start from Rp 5 Juta",
|
||||
price: "Rp 650 K",
|
||||
image: img("photo-1555374018-13a8994ab246?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Dokumen yang telah dilegalisasi atau diwaarmerking oleh notaris", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Legalisir Dokumen",
|
||||
subtitle: "Start from Rp 5 Juta",
|
||||
originalPrice: "Start from Rp 5 Juta",
|
||||
price: "Rp 50 K",
|
||||
image: img("photo-1554224155-6726b3ff858f?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Dokumen yang telah dilegalisasi oleh notaris", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pengecekan Wasiat",
|
||||
subtitle: "Start from Rp 3,5 Juta",
|
||||
originalPrice: "Start from Rp 3,5 Juta",
|
||||
price: "Rp 1,250 K",
|
||||
image: img("photo-1517248135467-4c7edcad34c4?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Dokumen Pengecekan Wasiat dari AHU Kemenkum RI", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Perjanjian Umum atau Khusus",
|
||||
subtitle: "Start from Rp 4 Juta",
|
||||
originalPrice: "Start from Rp 4 Juta",
|
||||
price: "Rp 2,850 K",
|
||||
image: img("photo-1521791136064-7986c2920216?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Jasa Pembuatan Akta Notaris",
|
||||
subtitle: "Start from Rp 4 Juta",
|
||||
originalPrice: "Start from Rp 4 Juta",
|
||||
price: "Rp 2,550 K",
|
||||
image: img("photo-1519671482749-fd09be7ccebf?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Akta Notaris", status: "include" },
|
||||
{ label: "Fotocopy Dokumen Akta yang telah dilegalisir notaris", status: "include" },
|
||||
{ label: "Softcopy File Dokumen (Pdf)", status: "include" }
|
||||
]
|
||||
}
|
||||
],
|
||||
lainnya: [
|
||||
{
|
||||
title: "Layanan Pelaporan Pajak Perusahaan Bulanan",
|
||||
group: "tax",
|
||||
subtitle: "Start from Rp 3,5 Juta",
|
||||
originalPrice: "Start from Rp 3,5 Juta",
|
||||
price: "Rp 750 K",
|
||||
image: img("photo-1517248135467-4c7edcad34c4?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ price: "Rp 750 K /bulan", description: "Perusahaan baru dibentuk dengan omset nihil", status: "price-tier" },
|
||||
{ price: "Rp 1,500 K /bulan", description: "Perusahaan non-PKP atau omset minimal Rp 4,8 M", status: "price-tier" },
|
||||
{ price: "Rp 1,500 K /bulan", description: "Perusahaan PKP atau omset maksimal Rp 4,8 M s.d. Rp 10 M", status: "price-tier" },
|
||||
{ label: "Tax Planning", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh 21/26", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh 23", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh UMKM", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh 4 Ayat 2", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Layanan Pelaporan Pajak Perusahaan Tahunan",
|
||||
group: "tax",
|
||||
subtitle: "Start from Rp 4,5 Juta",
|
||||
originalPrice: "Start from Rp 4,5 Juta",
|
||||
price: "Rp 1,500 K",
|
||||
image: img("photo-1517248135467-4c7edcad34c4?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ price: "Rp 1,500 K /bulan", description: "Pelaporan SPT Tahunan Nihil", status: "price-tier" },
|
||||
{ price: "Rp 3,500 K /bulan", description: "Pelaporan SPT Tahunan ada transaksi", status: "price-tier" },
|
||||
{ label: "Tax Planning", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh 21/26", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh 23", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh UMKM", status: "include" },
|
||||
{ label: "Perhitungan & pelaporan PPh 4 Ayat 2", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Layanan Pembukuan Pajak Perusahaan",
|
||||
group: "tax",
|
||||
subtitle: "Start from Rp 20 Juta",
|
||||
originalPrice: "Start from Rp 20 Juta",
|
||||
price: "Rp 2,000 K",
|
||||
image: img("photo-1521791136064-7986c2920216?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "Pembukuan bulanan — Rp 2,000 K", status: "price-line" },
|
||||
{ label: "Pembukuan 3 bulanan — Rp 5,000 K", status: "price-line" },
|
||||
{ label: "Pembukuan 12 bulanan — Rp 18,000 K", status: "price-line" },
|
||||
{ label: "Pembukuan pajak rutin perusahaan", status: "include" },
|
||||
{ label: "Highlight laporan keuangan", status: "include" },
|
||||
{ label: "Laporan laba/rugi", status: "include" },
|
||||
{ label: "Laporan neraca", status: "include" },
|
||||
{ label: "Laporan arus kas", status: "include" },
|
||||
{ label: "Laporan buku besar", status: "include" },
|
||||
{ label: "Trend laba/rugi", status: "include" },
|
||||
{ label: "Perbandingan rasio biaya", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Layanan Perpajakan Umum",
|
||||
group: "tax",
|
||||
subtitle: "Start from Rp 20 Juta",
|
||||
originalPrice: "Start from Rp 20 Juta",
|
||||
price: "Rp 2,000 K",
|
||||
image: img("photo-1517248135467-4c7edcad34c4?ixlib=rb-4.0.3"),
|
||||
features: [
|
||||
{ label: "NPWP & Coretax Badan — Rp 600 K", status: "price-line" },
|
||||
{ label: "NPWP & Coretax Pribadi — Rp 250 K", status: "price-line" },
|
||||
{ label: "Pengurusan PKP — Rp 3,500 K", status: "price-line" },
|
||||
{ label: "Surat Keterangan Fiskal — Rp 300 K", status: "price-line" },
|
||||
{ label: "Surat Keterangan Bebas — Rp 950 K", status: "price-line" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Paket Bronze",
|
||||
group: "web",
|
||||
subtitle: "Start from Rp 3,5 Juta",
|
||||
originalPrice: "Start from Rp 3,5 Juta",
|
||||
price: "Rp 2,000 K",
|
||||
image: packageBronzeImg,
|
||||
features: [
|
||||
{ label: "Domain .com/.id setahun", status: "include" },
|
||||
{ label: "Gratis hosting vercel", status: "include" },
|
||||
{ label: "20 pilihan template", status: "include" },
|
||||
{ label: "1 halaman website", status: "include" },
|
||||
{ label: "Tanpa admin panel", status: "include" },
|
||||
{ label: "Tanpa database", status: "include" },
|
||||
{ label: "Tanpa email custom", status: "include" },
|
||||
{ label: "1 kali perubahan konten", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Paket Silver",
|
||||
group: "web",
|
||||
subtitle: "Start from Rp 5 Juta",
|
||||
originalPrice: "Start from Rp 5 Juta",
|
||||
price: "Rp 4,000 K",
|
||||
image: packageSilverImg,
|
||||
features: [
|
||||
{ label: "Domain .com/.id setahun", status: "include" },
|
||||
{ label: "Gratis hosting vercel", status: "include" },
|
||||
{ label: "Bisa request design", status: "include" },
|
||||
{ label: "1 halaman website", status: "include" },
|
||||
{ label: "Tanpa admin panel", status: "include" },
|
||||
{ label: "Tanpa database", status: "include" },
|
||||
{ label: "Dengan 2 email custom", status: "include" },
|
||||
{ label: "3 kali perubahan konten", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Paket Gold",
|
||||
group: "web",
|
||||
subtitle: "Start from Rp 12 Juta",
|
||||
originalPrice: "Start from Rp 12 Juta",
|
||||
price: "Rp 9,000 K",
|
||||
image: packageGoldImg,
|
||||
features: [
|
||||
{ label: "Domain .com/.id setahun", status: "include" },
|
||||
{ label: "Free Virtual personal server setahun", status: "include" },
|
||||
{ label: "Bisa request design", status: "include" },
|
||||
{ label: "1–5 halaman website", status: "include" },
|
||||
{ label: "Dengan admin panel", status: "include" },
|
||||
{ label: "Dengan database 5–20 GB", status: "include" },
|
||||
{ label: "Dengan 10 email custom", status: "include" },
|
||||
{ label: "Akses login admin panel", status: "include" },
|
||||
{ label: "Konten dapat di-update via admin panel", status: "include" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Paket Platinum",
|
||||
group: "web",
|
||||
subtitle: "Start from Rp 18 Juta",
|
||||
originalPrice: "Start from Rp 18 Juta",
|
||||
price: "Rp 14,000 K",
|
||||
image: packagePlatinumImg,
|
||||
features: [
|
||||
{ label: "Domain .com/.id setahun", status: "include" },
|
||||
{ label: "Free Virtual personal server setahun", status: "include" },
|
||||
{ label: "Bisa request design", status: "include" },
|
||||
{ label: "Bebas halaman website", status: "include" },
|
||||
{ label: "Dengan admin panel", status: "include" },
|
||||
{ label: "Database up to 50 GB", status: "include" },
|
||||
{ label: "Dengan 25 email custom", status: "include" },
|
||||
{ label: "Akses login admin panel", status: "include" },
|
||||
{ label: "Konten dapat di-update via admin panel", status: "include" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
72
src/components/ui/Tabs.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
tabs: { type: Array, required: true },
|
||||
modelValue: { type: String, default: '' },
|
||||
ariaLabel: { type: String, default: 'Sections' }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'change'])
|
||||
|
||||
const internal = ref(props.modelValue || (props.tabs[0] && props.tabs[0].key) || '')
|
||||
|
||||
watch(() => props.modelValue, (v) => {
|
||||
if (v && v !== internal.value) internal.value = v
|
||||
})
|
||||
|
||||
watch(internal, (v) => {
|
||||
emit('update:modelValue', v)
|
||||
emit('change', v)
|
||||
})
|
||||
|
||||
const activeIndex = computed(() => props.tabs.findIndex(t => t.key === internal.value))
|
||||
|
||||
function selectByIndex(idx) {
|
||||
if (idx < 0 || idx >= props.tabs.length) return
|
||||
internal.value = props.tabs[idx].key
|
||||
}
|
||||
|
||||
function onKeydown(e) {
|
||||
if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) return
|
||||
e.preventDefault()
|
||||
if (e.key === 'ArrowLeft') selectByIndex((activeIndex.value - 1 + props.tabs.length) % props.tabs.length)
|
||||
if (e.key === 'ArrowRight') selectByIndex((activeIndex.value + 1) % props.tabs.length)
|
||||
if (e.key === 'Home') selectByIndex(0)
|
||||
if (e.key === 'End') selectByIndex(props.tabs.length - 1)
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tabs">
|
||||
<div class="tablist" role="tablist" :aria-label="ariaLabel" @keydown="onKeydown">
|
||||
<button
|
||||
v-for="(t, i) in tabs"
|
||||
:key="t.key"
|
||||
class="tab"
|
||||
:class="{ active: t.key === internal }"
|
||||
role="tab"
|
||||
:id="`tab-${t.key}`"
|
||||
:aria-selected="t.key === internal"
|
||||
:tabindex="t.key === internal ? 0 : -1"
|
||||
@click="internal = t.key"
|
||||
>
|
||||
{{ t.label }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="tabpanel">
|
||||
<slot :active="internal"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.tabs { width: 100%; }
|
||||
.tablist { display: flex; justify-content: center; gap: 32px; border-bottom: 1px solid #e5e7eb; overflow-x: auto; }
|
||||
.tab { appearance: none; background: transparent; border: none; padding: 14px 4px; cursor: pointer; color: #6b7280; font-weight: 600; font-size: 14px; letter-spacing: .25px; white-space: nowrap; border-bottom: 3px solid transparent; margin-bottom: -1px; transition: color .18s, border-color .18s; }
|
||||
.tab.active { color: #111827; border-bottom-color: #FF6640; }
|
||||
.tab:hover { color: #111827; }
|
||||
.tabpanel { padding-top: 24px; }
|
||||
</style>
|
||||
7
src/main.js
Normal file
@ -0,0 +1,7 @@
|
||||
import './assets/main.css'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
createApp(App).use(router).mount('#app')
|
||||
27
src/pages/Home.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<script setup>
|
||||
import Hero from "@/components/main/Hero.vue";
|
||||
import ServicesMenu from "@/components/main/ServicesMenu.vue";
|
||||
import ServicesSection from "@/components/main/ServiceSection.vue";
|
||||
import WhyChoose from "@/components/main/WhyChoose.vue";
|
||||
import CallToAction from "@/components/main/CallToAction.vue";
|
||||
import ReasonsSection from "@/components/main/ReasonsSection.vue";
|
||||
import Testimonial from "@/components/main/Testimonial.vue";
|
||||
import FaqSection from "@/components/main/FaqSection.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<Hero />
|
||||
<ServicesMenu id="solusi" />
|
||||
<!-- FIX: use section, not single card -->
|
||||
<ServicesSection />
|
||||
<WhyChoose />
|
||||
<CallToAction id="konsultasi" />
|
||||
<ReasonsSection />
|
||||
<Testimonial />
|
||||
<FaqSection />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
17
src/pages/Packages.vue
Normal file
@ -0,0 +1,17 @@
|
||||
<script setup>
|
||||
import PackagesSection from "../components/packages/PackagesSection.vue";
|
||||
import { useRoute } from 'vue-router';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const route = useRoute();
|
||||
const category = computed(() => route.meta.category || null);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main>
|
||||
<PackagesSection id="paket" :initialCategory="category" />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
71
src/router/index.js
Normal file
@ -0,0 +1,71 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import Home from '@/pages/Home.vue'
|
||||
import Packages from '@/pages/Packages.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'Home',
|
||||
component: Home
|
||||
},
|
||||
{
|
||||
path: '/packages',
|
||||
name: 'Packages',
|
||||
component: Packages
|
||||
},
|
||||
{
|
||||
path: '/packages/pendirian',
|
||||
name: 'PackagesPendirian',
|
||||
component: Packages,
|
||||
meta: { category: 'pendirian' }
|
||||
},
|
||||
{
|
||||
path: '/packages/perubahan',
|
||||
name: 'PackagesPerubahan',
|
||||
component: Packages,
|
||||
meta: { category: 'perubahan' }
|
||||
},
|
||||
{
|
||||
path: '/packages/property',
|
||||
name: 'PackagesProperty',
|
||||
component: Packages,
|
||||
meta: { category: 'property' }
|
||||
},
|
||||
{
|
||||
path: '/packages/khusus',
|
||||
name: 'PackagesKhusus',
|
||||
component: Packages,
|
||||
meta: { category: 'khusus' }
|
||||
},
|
||||
{
|
||||
path: '/packages/umum',
|
||||
name: 'PackagesUmum',
|
||||
component: Packages,
|
||||
meta: { category: 'umum' }
|
||||
},
|
||||
{
|
||||
path: '/packages/lainnya',
|
||||
name: 'PackagesLainnya',
|
||||
component: Packages,
|
||||
meta: { category: 'lainnya' }
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
scrollBehavior(to, from, savedPosition) {
|
||||
if (to.hash) {
|
||||
return {
|
||||
el: to.hash,
|
||||
behavior: 'smooth'
|
||||
}
|
||||
} else if (savedPosition) {
|
||||
return savedPosition
|
||||
} else {
|
||||
return { top: 0 }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default router
|
||||
18
vite.config.js
Normal file
@ -0,0 +1,18 @@
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
vueDevTools(),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
},
|
||||
},
|
||||
})
|
||||