Migrate frontend to Vuetify/Vuexy + add real WHMCS product data

- Migrate all frontend from plain JS/Tailwind to TypeScript/Vuetify 3 (Vuexy design system)
- Replace placeholder plans with 25 real products scraped from WHMCS:
  9 VPS plans ($4.20-$30/mo), 8 dedicated servers ($44.39-$107.99/mo),
  4 web hosting plans ($2.39-$15.99/mo), 4 MySQL hosting plans ($6-$30/mo)
- Fix Pricing page: correct field mapping (service_type, price), display
  feature values instead of keys, proper price formatting
- Update all marketing pages (Home, Products, VPS, Dedicated, Web Hosting)
  with real specs, pricing, and features from production WHMCS
- Add 38 Vuexy @core SCSS override files for component styling
- Create 4 layouts (Account, Admin, Auth, Marketing) with Vuetify
- Add AppTextField/AppSelect/AppTextarea wrapper components
- Purple primary theme (#7367F0), dark mode default
- 52 tests passing, build clean

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Dev
2026-02-09 10:16:41 -05:00
parent 0fe4e4ab42
commit ec8f0272ec
141 changed files with 9592 additions and 2440 deletions

View File

@@ -0,0 +1,108 @@
<script lang="ts" setup>
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
const values = [
{ icon: 'tabler-heart', title: 'Customer First', description: 'Every decision we make starts with what\'s best for our customers.', color: 'error' },
{ icon: 'tabler-shield-check', title: 'Reliability', description: 'We engineer our infrastructure for maximum uptime and performance.', color: 'success' },
{ icon: 'tabler-eye', title: 'Transparency', description: 'No hidden fees, no surprise charges. What you see is what you pay.', color: 'primary' },
{ icon: 'tabler-rocket', title: 'Innovation', description: 'We continuously invest in the latest hardware and software technologies.', color: 'warning' },
]
const milestones = [
{ year: '2024', event: 'EZSCALE founded with a mission to simplify cloud hosting.' },
{ year: '2024', event: 'Launched VPS and Dedicated Server product lines.' },
{ year: '2025', event: 'Expanded to 50+ data center locations worldwide.' },
{ year: '2025', event: 'Surpassed 10,000 active customers.' },
]
</script>
<template>
<div>
<!-- Hero -->
<VContainer class="py-16">
<VRow align="center">
<VCol cols="12" md="8" class="mx-auto text-center">
<h1 class="text-h2 font-weight-bold mb-4">About EZSCALE</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular">
We're on a mission to make cloud hosting simple, affordable, and accessible to everyone.
From individual developers to growing businesses, EZSCALE provides the infrastructure you need to succeed.
</p>
</VCol>
</VRow>
</VContainer>
<!-- Values -->
<div class="bg-surface-variant py-16">
<VContainer>
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Our Values</h2>
</div>
<VRow>
<VCol v-for="value in values" :key="value.title" cols="12" sm="6" md="3">
<VCard variant="flat" class="text-center pa-6 h-100 bg-transparent">
<VAvatar :color="value.color" variant="tonal" size="64" class="mb-4">
<VIcon :icon="value.icon" size="32" />
</VAvatar>
<h3 class="text-h6 font-weight-bold mb-2">{{ value.title }}</h3>
<p class="text-body-2 text-medium-emphasis mb-0">{{ value.description }}</p>
</VCard>
</VCol>
</VRow>
</VContainer>
</div>
<!-- Timeline -->
<VContainer class="py-16">
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Our Journey</h2>
</div>
<VRow justify="center">
<VCol cols="12" md="8">
<VTimeline side="end" density="compact">
<VTimelineItem
v-for="(milestone, index) in milestones"
:key="index"
dot-color="primary"
size="small"
>
<VCard variant="outlined">
<VCardText>
<div class="text-caption text-primary font-weight-bold mb-1">{{ milestone.year }}</div>
<div class="text-body-1">{{ milestone.event }}</div>
</VCardText>
</VCard>
</VTimelineItem>
</VTimeline>
</VCol>
</VRow>
</VContainer>
<!-- Stats -->
<div class="bg-surface-variant py-16">
<VContainer>
<VRow>
<VCol cols="6" md="3" class="text-center">
<div class="text-h3 font-weight-bold text-primary">10K+</div>
<div class="text-body-1 text-medium-emphasis mt-1">Customers</div>
</VCol>
<VCol cols="6" md="3" class="text-center">
<div class="text-h3 font-weight-bold text-primary">99.99%</div>
<div class="text-body-1 text-medium-emphasis mt-1">Uptime</div>
</VCol>
<VCol cols="6" md="3" class="text-center">
<div class="text-h3 font-weight-bold text-primary">50+</div>
<div class="text-body-1 text-medium-emphasis mt-1">Locations</div>
</VCol>
<VCol cols="6" md="3" class="text-center">
<div class="text-h3 font-weight-bold text-primary">24/7</div>
<div class="text-body-1 text-medium-emphasis mt-1">Support</div>
</VCol>
</VRow>
</VContainer>
</div>
</div>
</template>

View File

@@ -0,0 +1,153 @@
<script lang="ts" setup>
import { useForm } from '@inertiajs/vue3'
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
import AppTextField from '@/Components/app-form-elements/AppTextField.vue'
import AppSelect from '@/Components/app-form-elements/AppSelect.vue'
import AppTextarea from '@/Components/app-form-elements/AppTextarea.vue'
defineOptions({ layout: MarketingLayout })
const form = useForm({
name: '',
email: '',
subject: '',
message: '',
})
const subjects = [
'General Inquiry',
'Sales',
'Technical Support',
'Billing',
'Partnership',
'Other',
]
function submit(): void {
form.post('/contact', {
preserveScroll: true,
onSuccess: () => form.reset(),
})
}
const contactInfo = [
{ icon: 'tabler-mail', title: 'Email', detail: 'support@ezscale.cloud', href: 'mailto:support@ezscale.cloud' },
{ icon: 'tabler-clock', title: 'Support Hours', detail: '24/7/365', href: null },
{ icon: 'tabler-message-circle', title: 'Live Chat', detail: 'Available on dashboard', href: null },
]
</script>
<template>
<div>
<VContainer class="py-16">
<div class="text-center mb-12">
<h1 class="text-h2 font-weight-bold mb-3">Contact Us</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular">
Have a question? We'd love to hear from you.
</p>
</div>
<VRow>
<!-- Contact Form -->
<VCol cols="12" md="7">
<VCard variant="outlined">
<VCardText class="pa-6">
<h2 class="text-h5 font-weight-bold mb-6">Send us a message</h2>
<form @submit.prevent="submit">
<VRow>
<VCol cols="12" sm="6">
<AppTextField
v-model="form.name"
label="Name"
placeholder="John Doe"
:error-messages="form.errors.name"
required
/>
</VCol>
<VCol cols="12" sm="6">
<AppTextField
v-model="form.email"
label="Email"
type="email"
placeholder="john@example.com"
:error-messages="form.errors.email"
required
/>
</VCol>
<VCol cols="12">
<AppSelect
v-model="form.subject"
:items="subjects"
label="Subject"
:error-messages="form.errors.subject"
required
/>
</VCol>
<VCol cols="12">
<AppTextarea
v-model="form.message"
label="Message"
rows="5"
placeholder="How can we help you?"
:error-messages="form.errors.message"
required
/>
</VCol>
<VCol cols="12">
<VBtn
type="submit"
color="primary"
size="large"
:loading="form.processing"
:disabled="form.processing"
>
Send Message
<VIcon icon="tabler-send" end />
</VBtn>
</VCol>
</VRow>
</form>
</VCardText>
</VCard>
</VCol>
<!-- Contact Info -->
<VCol cols="12" md="5">
<div class="d-flex flex-column ga-4">
<VCard v-for="info in contactInfo" :key="info.title" variant="outlined">
<VCardText class="d-flex align-center ga-4">
<VAvatar color="primary" variant="tonal" size="48">
<VIcon :icon="info.icon" size="24" />
</VAvatar>
<div>
<div class="text-subtitle-2 text-medium-emphasis">{{ info.title }}</div>
<a
v-if="info.href"
:href="info.href"
class="text-body-1 font-weight-medium text-decoration-none text-primary"
>
{{ info.detail }}
</a>
<div v-else class="text-body-1 font-weight-medium">{{ info.detail }}</div>
</div>
</VCardText>
</VCard>
<VCard variant="outlined" color="primary">
<VCardText class="pa-6">
<h3 class="text-h6 font-weight-bold mb-2">Need immediate help?</h3>
<p class="text-body-2 mb-3">
Our support team is available 24/7 through your account dashboard.
</p>
<VBtn variant="outlined" size="small">
Visit Knowledge Base
</VBtn>
</VCardText>
</VCard>
</div>
</VCol>
</VRow>
</VContainer>
</div>
</template>

View File

@@ -0,0 +1,304 @@
<script lang="ts" setup>
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
interface PageProps {
domains: { marketing: string; account: string; admin: string }
}
const page = usePage()
const props = computed(() => page.props as unknown as PageProps)
const accountUrl = computed(() => `https://${props.value.domains?.account}`)
interface ServerConfig {
model: string
formFactor: string
cpu: string
coresThreads: string
clockSpeed: string
ram: string
bays: string
price: string
inStock: boolean
}
const features = [
{ icon: 'tabler-cpu', title: 'Dedicated Hardware', description: 'No shared resources — all CPU, RAM, and storage are exclusively yours.' },
{ icon: 'tabler-dashboard', title: 'SynergyCP Access', description: 'Full server management with SynergyCP panel including IPMI, rDNS, and OS reload.' },
{ icon: 'tabler-network', title: '1Gbps Network', description: '1 Gbps port with 10 TB bandwidth included on every server.' },
{ icon: 'tabler-lock', title: 'RAID Support', description: 'Enterprise RAID controllers available for data redundancy and performance.' },
{ icon: 'tabler-clock', title: 'Same-Day Setup', description: 'Most in-stock servers deployed same-day, subject to availability.' },
{ icon: 'tabler-headset', title: '24/7 Support', description: 'Expert engineers available around the clock for hardware and network issues.' },
]
const servers: ServerConfig[] = [
{
model: 'Dell R330 LFF',
formFactor: '4-Bay',
cpu: '1x Intel Xeon E3-1220 v5',
coresThreads: '4C/4T',
clockSpeed: '3.0/3.5 GHz',
ram: '16 GB',
bays: '4x 3.5"',
price: '$44.39',
inStock: true,
},
{
model: 'Dell R420 LFF',
formFactor: '4-Bay',
cpu: '2x Intel Xeon E5-2430v2',
coresThreads: '12C/24T',
clockSpeed: '2.5/3.0 GHz',
ram: '32 GB',
bays: '4x 3.5"',
price: '$58.79',
inStock: false,
},
{
model: 'Dell R620 SFF',
formFactor: '10-Bay',
cpu: '2x Intel Xeon E5-2667v2',
coresThreads: '16C/32T',
clockSpeed: '3.3/4.0 GHz',
ram: '32 GB',
bays: '10x 2.5"',
price: '$61.19',
inStock: false,
},
{
model: 'Dell R620 SFF',
formFactor: '8-Bay',
cpu: '2x Intel Xeon E5-2667v2',
coresThreads: '16C/32T',
clockSpeed: '3.3/4.0 GHz',
ram: '32 GB',
bays: '8x 2.5"',
price: '$61.19',
inStock: false,
},
{
model: 'Dell R520 LFF',
formFactor: '8-Bay',
cpu: '2x Intel Xeon E5-2420v2',
coresThreads: '12C/24T',
clockSpeed: '2.2/2.7 GHz',
ram: '32 GB',
bays: '8x 3.5"',
price: '$64.79',
inStock: true,
},
{
model: 'Dell R430 LFF',
formFactor: '4-Bay',
cpu: '2x Intel Xeon E5-2667v4',
coresThreads: '16C/32T',
clockSpeed: '3.2/3.6 GHz',
ram: '32 GB',
bays: '4x 3.5"',
price: '$87.59',
inStock: true,
},
{
model: 'Dell R630 SFF',
formFactor: '8-Bay',
cpu: '2x Intel Xeon E5-2697A v4',
coresThreads: '32C/64T',
clockSpeed: '2.6/3.6 GHz',
ram: '32 GB',
bays: '8x 2.5"',
price: '$93.59',
inStock: true,
},
{
model: 'Dell R730 LFF',
formFactor: '8-Bay',
cpu: '2x Intel Xeon E5-2680v4',
coresThreads: '28C/56T',
clockSpeed: '2.4/3.3 GHz',
ram: '32 GB',
bays: '8x 3.5"',
price: '$107.99',
inStock: true,
},
]
const included = [
{ icon: 'tabler-world', label: '10 TB Bandwidth' },
{ icon: 'tabler-network', label: '1 Gbps Port' },
{ icon: 'tabler-map-pin', label: 'Atlanta, GA Datacenter' },
{ icon: 'tabler-address-book', label: '1 IPv4 Address' },
{ icon: 'tabler-hexagons', label: '1x /64 IPv6 Subnet' },
{ icon: 'tabler-dashboard', label: 'SynergyCP Panel' },
]
</script>
<template>
<div>
<!-- Hero -->
<div class="py-16" style="background: linear-gradient(135deg, rgb(var(--v-theme-success), 0.1), rgb(var(--v-theme-surface)));">
<VContainer class="text-center">
<VChip color="success" variant="tonal" class="mb-4">Dedicated Servers</VChip>
<h1 class="text-h2 font-weight-bold mb-3">Bare Metal Power</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular mb-8 mx-auto" style="max-width: 600px;">
Enterprise-grade Dell PowerEdge servers with full root access, SynergyCP management, and same-day deployment from our Atlanta datacenter.
</p>
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="success" size="x-large" rounded="lg">
Configure Server
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
</VContainer>
</div>
<!-- Features -->
<VContainer class="py-16">
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Enterprise Hardware</h2>
<p class="text-body-1 text-medium-emphasis">Every dedicated server comes with these features included.</p>
</div>
<VRow>
<VCol v-for="feature in features" :key="feature.title" cols="12" sm="6" md="4">
<div class="d-flex ga-3 mb-4">
<VAvatar color="success" variant="tonal" size="44">
<VIcon :icon="feature.icon" size="22" />
</VAvatar>
<div>
<h3 class="text-subtitle-1 font-weight-bold">{{ feature.title }}</h3>
<p class="text-body-2 text-medium-emphasis mb-0">{{ feature.description }}</p>
</div>
</div>
</VCol>
</VRow>
</VContainer>
<!-- Server Configurations -->
<div class="bg-surface-variant py-16">
<VContainer>
<div class="text-center mb-8">
<h2 class="text-h3 font-weight-bold mb-3">Server Configurations</h2>
<p class="text-body-1 text-medium-emphasis">Real Dell PowerEdge servers. Storage sold separately -- configure your drives at checkout.</p>
</div>
<VRow>
<VCol v-for="(server, index) in servers" :key="index" cols="12" sm="6" lg="3">
<VCard
variant="outlined"
class="h-100"
:class="{ 'server-card-unavailable': !server.inStock }"
:style="server.inStock ? {} : { opacity: 0.7 }"
>
<VCardText class="pa-5">
<!-- Header with model and stock status -->
<div class="d-flex align-center justify-space-between mb-1">
<h3 class="text-subtitle-1 font-weight-bold">{{ server.model }}</h3>
<VChip
:color="server.inStock ? 'success' : 'error'"
size="small"
variant="tonal"
>
{{ server.inStock ? 'In Stock' : 'Sold Out' }}
</VChip>
</div>
<p class="text-caption text-medium-emphasis mb-3">{{ server.formFactor }}</p>
<!-- Price -->
<div class="mb-4">
<span class="text-h4 font-weight-bold" :class="server.inStock ? 'text-success' : 'text-medium-emphasis'">{{ server.price }}</span>
<span class="text-body-2 text-medium-emphasis">/mo</span>
</div>
<VDivider class="mb-4" />
<!-- Specs -->
<div class="mb-4">
<div class="d-flex align-center ga-2 py-1">
<VIcon icon="tabler-cpu" size="16" color="medium-emphasis" />
<span class="text-body-2">{{ server.cpu }}</span>
</div>
<div class="d-flex align-center ga-2 py-1">
<VIcon icon="tabler-topology-star-3" size="16" color="medium-emphasis" />
<span class="text-body-2">{{ server.coresThreads }} @ {{ server.clockSpeed }}</span>
</div>
<div class="d-flex align-center ga-2 py-1">
<VIcon icon="tabler-database" size="16" color="medium-emphasis" />
<span class="text-body-2">{{ server.ram }} RAM</span>
</div>
<div class="d-flex align-center ga-2 py-1">
<VIcon icon="tabler-server" size="16" color="medium-emphasis" />
<span class="text-body-2">{{ server.bays }} drive bays</span>
</div>
</div>
<!-- Order Button -->
<a
v-if="server.inStock"
:href="accountUrl + '/register'"
class="text-decoration-none d-block"
>
<VBtn color="success" variant="tonal" block>
Order Now
</VBtn>
</a>
<VBtn
v-else
color="default"
variant="tonal"
block
disabled
>
Unavailable
</VBtn>
</VCardText>
</VCard>
</VCol>
</VRow>
</VContainer>
</div>
<!-- Included With Every Server -->
<VContainer class="py-16">
<div class="text-center mb-8">
<h2 class="text-h3 font-weight-bold mb-3">Included With Every Server</h2>
<p class="text-body-1 text-medium-emphasis">No hidden fees. All servers come with these essentials.</p>
</div>
<VRow justify="center">
<VCol v-for="item in included" :key="item.label" cols="6" sm="4" md="2">
<div class="text-center">
<VAvatar color="success" variant="tonal" size="48" class="mb-3">
<VIcon :icon="item.icon" size="24" />
</VAvatar>
<p class="text-body-2 font-weight-medium mb-0">{{ item.label }}</p>
</div>
</VCol>
</VRow>
</VContainer>
<!-- CTA -->
<div class="py-12" style="background: linear-gradient(135deg, rgb(var(--v-theme-success), 0.08), rgb(var(--v-theme-surface)));">
<VContainer class="text-center">
<h2 class="text-h4 font-weight-bold mb-3">Need a Custom Configuration?</h2>
<p class="text-body-1 text-medium-emphasis mb-6">
Contact us for custom builds, bulk orders, or servers with specific hardware requirements.
</p>
<div class="d-flex ga-3 justify-center flex-wrap">
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="success" size="large" rounded="lg">
Get Started
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
<a href="/contact" class="text-decoration-none">
<VBtn color="success" variant="outlined" size="large" rounded="lg">
Contact Sales
</VBtn>
</a>
</div>
</VContainer>
</div>
</div>
</template>

View File

@@ -0,0 +1,97 @@
<script lang="ts" setup>
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
interface PageProps {
domains: { marketing: string; account: string; admin: string }
}
const page = usePage()
const props = computed(() => page.props as unknown as PageProps)
const accountUrl = computed(() => `https://${props.value.domains?.account}`)
const games = [
{ name: 'Minecraft', icon: 'tabler-cube', description: 'Java & Bedrock editions with mod support.', startingAt: '$7.99/mo' },
{ name: 'Rust', icon: 'tabler-shield', description: 'High-performance Rust servers with Oxide support.', startingAt: '$14.99/mo' },
{ name: 'ARK: Survival Evolved', icon: 'tabler-dinosaur', description: 'ARK servers with cluster support.', startingAt: '$19.99/mo' },
{ name: 'Valheim', icon: 'tabler-sword', description: 'Dedicated Valheim servers with mod support.', startingAt: '$9.99/mo' },
{ name: 'CS2', icon: 'tabler-crosshair', description: 'Counter-Strike 2 competitive and casual servers.', startingAt: '$12.99/mo' },
{ name: 'Palworld', icon: 'tabler-paw', description: 'Palworld dedicated servers with full configuration.', startingAt: '$14.99/mo' },
]
const features = [
{ icon: 'tabler-bolt', title: 'Low Latency', description: 'Optimized network routing for minimal ping.' },
{ icon: 'tabler-puzzle', title: 'Mod Support', description: 'Easy plugin and mod installation with one-click tools.' },
{ icon: 'tabler-shield-check', title: 'DDoS Protection', description: 'Always-on protection to keep your server online.' },
{ icon: 'tabler-clock', title: 'Instant Setup', description: 'Your game server is ready in under 5 minutes.' },
]
</script>
<template>
<div>
<!-- Hero -->
<div class="py-16" style="background: linear-gradient(135deg, rgb(var(--v-theme-error), 0.1), rgb(var(--v-theme-surface)));">
<VContainer class="text-center">
<VChip color="error" variant="tonal" class="mb-4">Game Servers</VChip>
<h1 class="text-h2 font-weight-bold mb-3">Game Server Hosting</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular mb-8 mx-auto" style="max-width: 600px;">
Low-latency game server hosting with instant setup, mod support, and DDoS protection.
</p>
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="error" size="x-large" rounded="lg">
Get Your Server
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
</VContainer>
</div>
<!-- Supported Games -->
<VContainer class="py-16">
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Supported Games</h2>
<p class="text-body-1 text-medium-emphasis">Popular titles with more being added regularly.</p>
</div>
<VRow>
<VCol v-for="game in games" :key="game.name" cols="12" sm="6" md="4">
<VCard variant="outlined" class="h-100">
<VCardText class="d-flex align-center ga-4">
<VAvatar color="error" variant="tonal" size="48">
<VIcon :icon="game.icon" size="24" />
</VAvatar>
<div>
<h3 class="text-subtitle-1 font-weight-bold">{{ game.name }}</h3>
<p class="text-body-2 text-medium-emphasis mb-1">{{ game.description }}</p>
<span class="text-body-2 text-error font-weight-medium">From {{ game.startingAt }}</span>
</div>
</VCardText>
</VCard>
</VCol>
</VRow>
</VContainer>
<!-- Features -->
<div class="bg-surface-variant py-16">
<VContainer>
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Why Gamers Choose EZSCALE</h2>
</div>
<VRow>
<VCol v-for="feature in features" :key="feature.title" cols="12" sm="6" md="3">
<VCard variant="flat" class="text-center pa-4 h-100 bg-transparent">
<VAvatar color="error" variant="tonal" size="56" class="mb-3">
<VIcon :icon="feature.icon" size="28" />
</VAvatar>
<h3 class="text-subtitle-1 font-weight-bold mb-1">{{ feature.title }}</h3>
<p class="text-body-2 text-medium-emphasis mb-0">{{ feature.description }}</p>
</VCard>
</VCol>
</VRow>
</VContainer>
</div>
</div>
</template>

View File

@@ -0,0 +1,113 @@
<script lang="ts" setup>
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
interface PageProps {
domains: { marketing: string; account: string; admin: string }
}
const page = usePage()
const props = computed(() => page.props as unknown as PageProps)
const accountUrl = computed(() => `https://${props.value.domains?.account}`)
const features = [
{ icon: 'tabler-server', title: 'VPS Hosting', description: 'SSD VPS with VirtFusion panel, instant provisioning, and full root access. Starting at $4.20/mo.', href: '/vps-hosting', color: 'primary' },
{ icon: 'tabler-server-2', title: 'Dedicated Servers', description: 'Dell PowerEdge servers with SynergyCP management and 1Gbps connectivity. Starting at $44.39/mo.', href: '/dedicated-servers', color: 'success' },
{ icon: 'tabler-world', title: 'Web Hosting', description: 'Web hosting with Enhance panel, free SSL, Cloudflare DNS, and Redis cache. Starting at $2.39/mo.', href: '/web-hosting', color: 'warning' },
{ icon: 'tabler-device-gamepad-2', title: 'Game Servers', description: 'Low-latency game hosting for Minecraft, Rust, ARK, and more. Coming soon.', href: '/game-servers', color: 'error' },
]
const stats = [
{ value: '10,000+', label: 'Active Customers' },
{ value: '99.99%', label: 'Uptime SLA' },
{ value: '50+', label: 'Server Locations' },
{ value: '24/7', label: 'Expert Support' },
]
</script>
<template>
<div>
<!-- Hero Section -->
<div class="py-16" style="background: linear-gradient(135deg, rgb(var(--v-theme-primary), 0.1), rgb(var(--v-theme-surface)));">
<VContainer>
<VRow align="center" justify="center">
<VCol cols="12" md="8" class="text-center">
<h1 class="text-h2 text-md-h1 font-weight-bold mb-4">
Cloud Hosting
<span class="text-primary">Made Simple</span>
</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular mb-8 mx-auto" style="max-width: 600px;">
VPS, Dedicated Servers, Web Hosting, and Game Servers. Deploy in minutes with enterprise-grade infrastructure.
</p>
<div class="d-flex justify-center ga-4 flex-wrap">
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="primary" size="x-large" rounded="lg">
Start Free Trial
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
<a href="/pricing" class="text-decoration-none">
<VBtn variant="outlined" size="x-large" rounded="lg">
View Pricing
</VBtn>
</a>
</div>
</VCol>
</VRow>
</VContainer>
</div>
<!-- Features Section -->
<VContainer class="py-16">
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Our Products</h2>
<p class="text-body-1 text-medium-emphasis">Everything you need to build, deploy, and scale.</p>
</div>
<VRow>
<VCol v-for="feature in features" :key="feature.title" cols="12" sm="6" md="3">
<VCard variant="outlined" class="h-100" :href="feature.href">
<VCardText class="text-center pa-6">
<VAvatar :color="feature.color" variant="tonal" size="64" class="mb-4">
<VIcon :icon="feature.icon" size="32" />
</VAvatar>
<h3 class="text-h6 font-weight-bold mb-2">{{ feature.title }}</h3>
<p class="text-body-2 text-medium-emphasis mb-0">{{ feature.description }}</p>
</VCardText>
</VCard>
</VCol>
</VRow>
</VContainer>
<!-- Stats Section -->
<div class="bg-surface-variant py-16">
<VContainer>
<VRow>
<VCol v-for="stat in stats" :key="stat.label" cols="6" md="3" class="text-center">
<div class="text-h3 font-weight-bold text-primary">{{ stat.value }}</div>
<div class="text-body-1 text-medium-emphasis mt-1">{{ stat.label }}</div>
</VCol>
</VRow>
</VContainer>
</div>
<!-- CTA Section -->
<VContainer class="py-16">
<VCard color="primary" class="text-center pa-12">
<h2 class="text-h3 font-weight-bold text-white mb-3">Ready to get started?</h2>
<p class="text-h6 font-weight-regular mb-6" style="opacity: 0.9;">
Deploy your first server in under 60 seconds.
</p>
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="white" size="x-large" rounded="lg">
Create Free Account
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
</VCard>
</VContainer>
</div>
</template>

View File

@@ -0,0 +1,381 @@
<script lang="ts" setup>
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
interface Plan {
id: number
name: string
slug: string
description: string | null
service_type: string
price: string
currency: string
billing_cycle: string
features: Record<string, string> | null
stock_quantity: number | null
status: string
sort_order: number
}
interface PageProps {
plans: Plan[]
domains: { marketing: string; account: string; admin: string }
}
const page = usePage()
const props = computed(() => page.props as unknown as PageProps)
const accountUrl = computed(() => `https://${props.value.domains?.account}`)
const plans = computed(() => props.value.plans || [])
function getMonthlyPrice(plan: Plan): string {
const price = parseFloat(plan.price ?? '0') || 0
return price % 1 === 0 ? price.toString() : price.toFixed(2)
}
function getPlanColor(index: number): string {
const colors = ['primary', 'success', 'warning', 'error', 'info']
return colors[index % colors.length]
}
function isPopular(index: number): boolean {
return plans.value.length > 1 && index === 1
}
// Feature comparison data
const featureComparison = computed(() => {
if (plans.value.length === 0) return []
const allFeatures = new Set<string>()
plans.value.forEach(plan => {
if (plan.features) {
Object.keys(plan.features).forEach(f => allFeatures.add(f))
}
})
return Array.from(allFeatures).map(feature => ({
feature,
plans: plans.value.map(plan => ({
value: plan.features?.[feature] ?? null,
})),
}))
})
const faqs = [
{
question: 'Can I upgrade my plan later?',
answer: 'Yes! You can upgrade or downgrade your plan at any time from your account dashboard. Changes take effect immediately and billing is prorated.',
},
{
question: 'What payment methods do you accept?',
answer: 'We accept all major credit cards (Visa, Mastercard, American Express) via Stripe, as well as PayPal. Your payment information is always kept safe and secure.',
},
{
question: 'Is there a money-back guarantee?',
answer: 'Yes, all plans come with a 30-day money-back guarantee. If you\'re not satisfied, contact support for a full refund.',
},
{
question: 'Do you offer custom configurations?',
answer: 'Absolutely. Contact our sales team for custom server configurations, bulk pricing, or enterprise solutions tailored to your needs.',
},
]
</script>
<template>
<div class="pricing-page">
<VCard class="pricing-card" flat>
<!-- Plan Cards Section -->
<VContainer>
<div class="text-center">
<h3 class="text-h3 pricing-title mb-2">
Pricing Plans
</h3>
<p class="mb-0 text-body-1">
All plans include 24/7 monitoring and enterprise-grade infrastructure.
</p>
<p class="mb-2 text-body-1">
Choose the best plan to fit your needs.
</p>
</div>
<!-- Plan Cards -->
<VRow v-if="plans.length">
<VCol
v-for="(plan, index) in plans"
:key="plan.id"
cols="12"
md="4"
>
<VCard
flat
border
:class="isPopular(index) ? 'border-primary border-opacity-100' : ''"
>
<VCardText
style="block-size: 3.75rem;"
class="text-end"
>
<VChip
v-show="isPopular(index)"
label
color="primary"
size="small"
>
Popular
</VChip>
</VCardText>
<VCardText>
<!-- Plan Icon -->
<div class="text-center mb-5">
<VAvatar
:color="getPlanColor(index)"
variant="tonal"
size="80"
>
<VIcon
:icon="plan.service_type === 'vps' ? 'tabler-cloud' : plan.service_type === 'dedicated' ? 'tabler-server' : plan.service_type === 'web' ? 'tabler-world' : plan.service_type === 'game' ? 'tabler-device-gamepad-2' : 'tabler-package'"
size="40"
/>
</VAvatar>
</div>
<!-- Plan Name -->
<h4 class="text-h4 mb-1 text-center">
{{ plan.name }}
</h4>
<p class="mb-0 text-body-1 text-center">
{{ plan.description || 'High performance hosting' }}
</p>
<!-- Plan Price -->
<div class="position-relative">
<div class="d-flex justify-center pt-5 pb-10">
<div class="text-body-1 align-self-start font-weight-medium">
$
</div>
<h1 class="text-h1 font-weight-medium text-primary">
{{ getMonthlyPrice(plan) }}
</h1>
<div class="text-body-1 font-weight-medium align-self-end">
/month
</div>
</div>
</div>
<!-- Plan Features -->
<VList class="card-list mb-4">
<VListItem
v-for="(value, feature) in plan.features"
:key="String(feature)"
>
<template #prepend>
<VIcon
size="8"
icon="tabler-circle-filled"
color="rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity))"
/>
</template>
<VListItemTitle class="text-body-1">
{{ value }}
</VListItemTitle>
</VListItem>
</VList>
<!-- Plan CTA -->
<a
:href="accountUrl + '/register'"
class="text-decoration-none d-block"
>
<VBtn
block
:variant="isPopular(index) ? 'elevated' : 'tonal'"
:active="false"
>
Choose Plan
</VBtn>
</a>
</VCardText>
</VCard>
</VCol>
</VRow>
<VCard v-else variant="outlined" class="pa-12 text-center">
<VIcon icon="tabler-package" size="48" class="text-medium-emphasis mb-4" />
<h3 class="text-h5 font-weight-bold mb-2">Plans Coming Soon</h3>
<p class="text-body-1 text-medium-emphasis">
We're finalizing our plans. Check back soon or sign up to be notified.
</p>
</VCard>
</VContainer>
<!-- Feature Comparison Table -->
<VContainer v-if="plans.length && featureComparison.length">
<VCardText class="text-center py-16 pricing-section">
<h3 class="text-h3 mb-2">
Pick a plan that works best for you
</h3>
<p class="text-body-1">
Stay cool, we have a 30-day money back guarantee!
</p>
<VTable class="text-no-wrap border rounded pricing-table">
<thead>
<tr>
<th scope="col" class="py-4">
<div>Features</div>
<div class="text-body-2">Plan Comparison</div>
</th>
<th
v-for="(plan, index) in plans"
:key="plan.id"
scope="col"
class="text-center py-4"
>
<div class="position-relative">
{{ plan.name }}
<VAvatar
v-if="isPopular(index)"
size="20"
class="ms-2 position-absolute"
variant="elevated"
color="primary"
style="inset-block-end: 7px;"
>
<VIcon
icon="tabler-star"
size="14"
color="white"
/>
</VAvatar>
</div>
<div class="text-body-2">
${{ getMonthlyPrice(plan) }}/Month
</div>
</th>
</tr>
</thead>
<tbody>
<tr
v-for="row in featureComparison"
:key="row.feature"
>
<td class="text-start text-body-1 text-high-emphasis">
{{ row.feature }}
</td>
<td
v-for="(planData, pIndex) in row.plans"
:key="pIndex"
class="text-center"
>
<span v-if="planData.value" class="text-body-1">
{{ planData.value }}
</span>
<VIcon
v-else
icon="tabler-minus"
size="14"
color="secondary"
/>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="py-2" />
<td
v-for="(plan, index) in plans"
:key="plan.id"
class="text-center py-2"
>
<a
:href="accountUrl + '/register'"
class="text-decoration-none"
>
<VBtn
:variant="isPopular(index) ? 'elevated' : 'tonal'"
>
Choose Plan
</VBtn>
</a>
</td>
</tr>
</tfoot>
</VTable>
</VCardText>
</VContainer>
<!-- FAQ Section -->
<div class="faq-section-bg">
<VContainer>
<VCardText class="py-10 py-sm-16 pricing-section">
<div class="text-center">
<h4 class="text-h4 mb-2">
FAQ's
</h4>
<p class="text-body-1 mb-6">
Let us help answer the most common questions.
</p>
</div>
<VRow justify="center">
<VCol cols="12" md="8">
<VExpansionPanels>
<VExpansionPanel
v-for="(faq, index) in faqs"
:key="faq.question"
:title="faq.question"
:text="faq.answer"
:value="index"
/>
</VExpansionPanels>
</VCol>
</VRow>
</VCardText>
</VContainer>
</div>
</VCard>
</div>
</template>
<style lang="scss" scoped>
.pricing-card {
padding-block-start: 5rem !important;
}
.pricing-title {
font-weight: 800;
}
.card-list {
--v-card-list-gap: 1rem;
}
.pricing-section {
padding-block: 5.25rem !important;
padding-inline: 0 !important;
}
.faq-section-bg {
background-color: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
}
.pricing-table {
tr:nth-child(even) {
background: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
}
}
</style>
<style lang="scss">
.pricing-page {
@media (min-width: 600px) and (max-width: 960px) {
.v-container {
padding-inline: 2rem !important;
}
}
}
</style>

View File

@@ -0,0 +1,102 @@
<script lang="ts" setup>
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
const products = [
{
icon: 'tabler-server',
title: 'VPS Hosting',
description: 'High-performance SSD VPS with full root access, VirtFusion panel, and instant provisioning.',
features: ['SSD Storage', 'Full Root Access', 'Instant Provisioning', 'DDoS Protection'],
href: '/vps-hosting',
color: 'primary',
startingAt: '$4.20/mo',
},
{
icon: 'tabler-server-2',
title: 'Dedicated Servers',
description: 'Enterprise-grade Dell servers with dedicated hardware, SynergyCP management, and 1Gbps connectivity.',
features: ['Dedicated Hardware', 'SynergyCP Panel', '1Gbps Network', 'RAID Support'],
href: '/dedicated-servers',
color: 'success',
startingAt: '$44.39/mo',
},
{
icon: 'tabler-world',
title: 'Web Hosting',
description: 'Reliable web hosting with Enhance panel, free SSL, Cloudflare DNS, and Redis cache.',
features: ['Enhance Panel', 'Free SSL', 'Cloudflare DNS', 'Redis Cache'],
href: '/web-hosting',
color: 'warning',
startingAt: '$2.39/mo',
},
{
icon: 'tabler-device-gamepad-2',
title: 'Game Servers',
description: 'Contact us for custom game server hosting. Coming soon with low-latency optimized infrastructure.',
features: ['Low Latency Network', 'Mod Support', 'Instant Setup', 'DDoS Protection'],
href: '/game-servers',
color: 'error',
startingAt: 'Coming Soon',
},
{
icon: 'tabler-database',
title: 'MySQL Hosting',
description: 'Managed MySQL databases with daily backups and SSL encryption.',
features: ['Managed MySQL', 'Daily Backups', 'SSL Encrypted', 'High Availability'],
href: '/mysql-hosting',
color: 'info',
startingAt: '$6.00/mo',
},
]
</script>
<template>
<div>
<VContainer class="py-16">
<div class="text-center mb-12">
<h1 class="text-h2 font-weight-bold mb-3">Our Products</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular">
Enterprise-grade hosting solutions for every need.
</p>
</div>
<VRow>
<VCol v-for="product in products" :key="product.title" cols="12" md="6">
<VCard variant="outlined" class="h-100">
<VCardText class="pa-6">
<div class="d-flex align-center ga-4 mb-4">
<VAvatar :color="product.color" variant="tonal" size="56">
<VIcon :icon="product.icon" size="28" />
</VAvatar>
<div>
<h2 class="text-h5 font-weight-bold">{{ product.title }}</h2>
<span class="text-body-2 text-medium-emphasis">Starting at {{ product.startingAt }}</span>
</div>
</div>
<p class="text-body-1 text-medium-emphasis mb-4">{{ product.description }}</p>
<VList density="compact" class="pa-0 mb-4">
<VListItem v-for="feature in product.features" :key="feature" class="px-0">
<template #prepend>
<VIcon icon="tabler-check" :color="product.color" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ feature }}</VListItemTitle>
</VListItem>
</VList>
<a :href="product.href" class="text-decoration-none">
<VBtn :color="product.color" variant="tonal" block>
Learn More
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
</VCardText>
</VCard>
</VCol>
</VRow>
</VContainer>
</div>
</template>

View File

@@ -0,0 +1,169 @@
<script lang="ts" setup>
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
interface PageProps {
domains: { marketing: string; account: string; admin: string }
}
interface VpsPlan {
name: string
cpu: string
ram: string
storage: string
bandwidth: string
price: string
}
interface Feature {
icon: string
title: string
description: string
}
const page = usePage()
const props = computed(() => page.props as unknown as PageProps)
const accountUrl = computed<string>(() => `https://${props.value.domains?.account}`)
const features: Feature[] = [
{ icon: 'tabler-database', title: 'RAID 10 SSD Storage', description: 'Redundant SSD arrays for fast read/write speeds and data protection.' },
{ icon: 'tabler-shield-check', title: 'DDoS Protection', description: 'Enterprise-grade protection against volumetric attacks.' },
{ icon: 'tabler-rocket', title: 'Instant Provisioning', description: 'Your server is deployed within seconds of ordering.' },
{ icon: 'tabler-refresh', title: 'VM Backups', description: 'Built-in VM backup and snapshot functionality.' },
{ icon: 'tabler-terminal', title: 'Full Root Access', description: 'Complete control over your server environment.' },
{ icon: 'tabler-server', title: 'VirtFusion Panel', description: 'Powerful control panel for managing your VPS with ease.' },
]
const plans: VpsPlan[] = [
{ name: 'Micro VPS', cpu: '1 vCPU', ram: '1 GB', storage: '25 GB SSD', bandwidth: '2 TB', price: '$4.20' },
{ name: 'Mini VPS', cpu: '1 vCPU', ram: '2 GB', storage: '50 GB SSD', bandwidth: '4 TB', price: '$6.00' },
{ name: 'Dev Starter', cpu: '2 vCPU', ram: '2 GB', storage: '60 GB SSD', bandwidth: '4 TB', price: '$8.00' },
{ name: 'Basic VPS', cpu: '2 vCPU', ram: '4 GB', storage: '80 GB SSD', bandwidth: '6 TB', price: '$12.00' },
{ name: 'Storage Box', cpu: '2 vCPU', ram: '2 GB', storage: '500 GB SSD', bandwidth: '8 TB', price: '$15.00' },
{ name: 'Standard VPS', cpu: '4 vCPU', ram: '8 GB', storage: '160 GB SSD', bandwidth: '8 TB', price: '$15.60' },
{ name: 'RAM Optimized', cpu: '4 vCPU', ram: '16 GB', storage: '240 GB SSD', bandwidth: '10 TB', price: '$19.00' },
{ name: 'Advanced VPS', cpu: '6 vCPU', ram: '16 GB', storage: '320 GB SSD', bandwidth: '10 TB', price: '$21.60' },
{ name: 'Pro VPS', cpu: '8 vCPU', ram: '32 GB', storage: '640 GB SSD', bandwidth: '16 TB', price: '$30.00' },
]
const includedFeatures: string[] = [
'1 IPv4 & 1 /64 IPv6',
'Near instant provisioning',
'VM backups',
'Windows (BYOL) & Linux support',
'Intel E5-2680 v4 processors',
'Full root access',
'VirtFusion control panel',
'RAID 10 backed storage',
'14-day money back guarantee',
]
</script>
<template>
<div>
<!-- Hero -->
<div class="py-16" style="background: linear-gradient(135deg, rgb(var(--v-theme-primary), 0.1), rgb(var(--v-theme-surface)));">
<VContainer class="text-center">
<VChip color="primary" variant="tonal" class="mb-4">VPS Hosting</VChip>
<h1 class="text-h2 font-weight-bold mb-3">Virtual Private Servers</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular mb-4 mx-auto" style="max-width: 600px;">
High-performance VPS hosting with RAID 10 SSD storage, dedicated resources, and full root access from our Atlanta, GA datacenter.
</p>
<p class="text-body-1 text-medium-emphasis mb-8">
Starting at just <span class="text-primary font-weight-bold">$4.20/mo</span>
</p>
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="primary" size="x-large" rounded="lg">
Get Started
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
</VContainer>
</div>
<!-- Features -->
<VContainer class="py-16">
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Why Choose EZSCALE VPS?</h2>
</div>
<VRow>
<VCol v-for="feature in features" :key="feature.title" cols="12" sm="6" md="4">
<div class="d-flex ga-3 mb-4">
<VAvatar color="primary" variant="tonal" size="44">
<VIcon :icon="feature.icon" size="22" />
</VAvatar>
<div>
<h3 class="text-subtitle-1 font-weight-bold">{{ feature.title }}</h3>
<p class="text-body-2 text-medium-emphasis mb-0">{{ feature.description }}</p>
</div>
</div>
</VCol>
</VRow>
</VContainer>
<!-- Plans Table -->
<div class="bg-surface-variant py-16">
<VContainer>
<div class="text-center mb-8">
<h2 class="text-h3 font-weight-bold mb-3">VPS Plans</h2>
<p class="text-body-1 text-medium-emphasis">
All plans hosted in our Atlanta, GA datacenter. DDoS protection, full root access, and VirtFusion panel included.
</p>
</div>
<VCard>
<VTable>
<thead>
<tr>
<th>Plan</th>
<th>CPU</th>
<th>RAM</th>
<th>Storage</th>
<th>Bandwidth</th>
<th>Price</th>
<th />
</tr>
</thead>
<tbody>
<tr v-for="plan in plans" :key="plan.name">
<td class="font-weight-bold">{{ plan.name }}</td>
<td>{{ plan.cpu }}</td>
<td>{{ plan.ram }}</td>
<td>{{ plan.storage }}</td>
<td>{{ plan.bandwidth }}</td>
<td class="text-primary font-weight-bold">{{ plan.price }}/mo</td>
<td>
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="primary" size="small" variant="tonal">Order Now</VBtn>
</a>
</td>
</tr>
</tbody>
</VTable>
</VCard>
<!-- Included with all plans -->
<VCard class="mt-8 pa-6">
<h3 class="text-h5 font-weight-bold mb-4 text-center">Included With All Plans</h3>
<VRow>
<VCol
v-for="item in includedFeatures"
:key="item"
cols="12"
sm="6"
md="4"
>
<div class="d-flex align-center ga-2 mb-2">
<VIcon icon="tabler-circle-check" color="success" size="20" />
<span class="text-body-1">{{ item }}</span>
</div>
</VCol>
</VRow>
</VCard>
</VContainer>
</div>
</div>
</template>

View File

@@ -0,0 +1,253 @@
<script lang="ts" setup>
import { usePage } from '@inertiajs/vue3'
import { computed } from 'vue'
import MarketingLayout from '@/Layouts/MarketingLayout.vue'
defineOptions({ layout: MarketingLayout })
interface PageProps {
domains: { marketing: string; account: string; admin: string }
}
const page = usePage()
const props = computed(() => page.props as unknown as PageProps)
const accountUrl = computed(() => `https://${props.value.domains?.account}`)
interface Feature {
icon: string
title: string
description: string
}
interface Plan {
name: string
storage: string
databases: string
email: string
domains: string
bandwidth: string
ram: string
cores: string
price: string
popular?: boolean
}
const features: Feature[] = [
{ icon: 'tabler-layout-dashboard', title: 'Enhance Control Panel', description: 'Modern, intuitive control panel for effortless website and server management.' },
{ icon: 'tabler-lock', title: 'Free SSL Certificates', description: 'Auto-provisioned SSL certificates for all your domains at no extra cost.' },
{ icon: 'tabler-cloud', title: 'Cloudflare DNS', description: 'Enterprise-grade DNS with DDoS protection and global CDN included.' },
{ icon: 'tabler-database', title: 'Redis Cache', description: 'Built-in Redis object caching for blazing-fast page load times.' },
{ icon: 'tabler-brand-wordpress', title: 'WordPress Installer', description: 'One-click WordPress installation with automatic updates and optimization.' },
{ icon: 'tabler-terminal-2', title: 'SSH Access', description: 'Full SSH access for advanced users who need command-line control.' },
]
const plans: Plan[] = [
{
name: 'Small',
storage: '10 GB SSD',
databases: '2 MySQL DBs',
email: '5 Email Accounts',
domains: '1 Domain',
bandwidth: '1 TB BW',
ram: '512 MB RAM',
cores: '1 Core',
price: '$2.39',
},
{
name: 'Medium',
storage: '25 GB SSD',
databases: '6 MySQL DBs',
email: '20 Email Accounts',
domains: '4 Domains',
bandwidth: '1 TB BW',
ram: '1 GB RAM',
cores: '1 Core',
price: '$3.99',
popular: true,
},
{
name: 'Large',
storage: '100 GB SSD',
databases: 'Unlimited MySQL DBs',
email: 'Unlimited Email',
domains: '30 Domains',
bandwidth: '2 TB BW',
ram: '4 GB RAM',
cores: '4 Cores',
price: '$7.19',
},
{
name: 'Dedicated',
storage: '160 GB SSD',
databases: 'Unlimited MySQL DBs',
email: 'Unlimited Email',
domains: '100 Domains',
bandwidth: '4 TB BW',
ram: '8 GB RAM',
cores: '4 Cores',
price: '$15.99',
},
]
const includedFeatures: string[] = [
'Free SSL',
'Cloudflare DNS',
'Redis Cache',
'WordPress Installer',
'SSH Access',
'Enhance Panel',
]
</script>
<template>
<div>
<!-- Hero -->
<div class="py-16" style="background: linear-gradient(135deg, rgb(var(--v-theme-warning), 0.1), rgb(var(--v-theme-surface)));">
<VContainer class="text-center">
<VChip color="warning" variant="tonal" class="mb-4">Web Hosting</VChip>
<h1 class="text-h2 font-weight-bold mb-3">Managed Web Hosting</h1>
<p class="text-h6 text-medium-emphasis font-weight-regular mb-8 mx-auto" style="max-width: 600px;">
Fast, secure, and reliable web hosting powered by Enhance with free SSL, Cloudflare DNS, and Redis caching.
</p>
<a :href="accountUrl + '/register'" class="text-decoration-none">
<VBtn color="warning" size="x-large" rounded="lg">
Get Started
<VIcon icon="tabler-arrow-right" end />
</VBtn>
</a>
</VContainer>
</div>
<!-- Features -->
<VContainer class="py-16">
<div class="text-center mb-12">
<h2 class="text-h3 font-weight-bold mb-3">Everything You Need</h2>
<p class="text-body-1 text-medium-emphasis mx-auto" style="max-width: 550px;">
Every plan comes loaded with the tools and features you need to build and grow your website.
</p>
</div>
<VRow>
<VCol v-for="feature in features" :key="feature.title" cols="12" sm="6" md="4">
<div class="d-flex ga-3 mb-4">
<VAvatar color="warning" variant="tonal" size="44">
<VIcon :icon="feature.icon" size="22" />
</VAvatar>
<div>
<h3 class="text-subtitle-1 font-weight-bold">{{ feature.title }}</h3>
<p class="text-body-2 text-medium-emphasis mb-0">{{ feature.description }}</p>
</div>
</div>
</VCol>
</VRow>
</VContainer>
<!-- Plans -->
<div class="bg-surface-variant py-16">
<VContainer>
<div class="text-center mb-8">
<h2 class="text-h3 font-weight-bold mb-3">Hosting Plans</h2>
<p class="text-body-1 text-medium-emphasis mx-auto" style="max-width: 550px;">
Choose the plan that fits your needs. All plans include free SSL, Cloudflare DNS, and the Enhance control panel.
</p>
</div>
<VRow justify="center">
<VCol v-for="plan in plans" :key="plan.name" cols="12" sm="6" lg="3">
<VCard
:variant="plan.popular ? 'elevated' : 'outlined'"
:class="['h-100', { 'border-warning border-opacity-100': plan.popular }]"
:elevation="plan.popular ? 8 : 0"
>
<VCardText class="pa-6 text-center">
<VChip
v-if="plan.popular"
color="warning"
size="small"
class="mb-2"
>
Most Popular
</VChip>
<h3 class="text-h5 font-weight-bold mb-1">{{ plan.name }}</h3>
<div class="text-h4 font-weight-bold text-warning mb-4">
{{ plan.price }}<span class="text-body-2 text-medium-emphasis">/mo</span>
</div>
<VDivider class="mb-4" />
<VList density="compact" class="pa-0">
<VListItem class="px-0">
<template #prepend>
<VIcon icon="tabler-database" color="warning" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ plan.storage }}</VListItemTitle>
</VListItem>
<VListItem class="px-0">
<template #prepend>
<VIcon icon="tabler-stack-2" color="warning" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ plan.databases }}</VListItemTitle>
</VListItem>
<VListItem class="px-0">
<template #prepend>
<VIcon icon="tabler-mail" color="warning" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ plan.email }}</VListItemTitle>
</VListItem>
<VListItem class="px-0">
<template #prepend>
<VIcon icon="tabler-world" color="warning" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ plan.domains }}</VListItemTitle>
</VListItem>
<VListItem class="px-0">
<template #prepend>
<VIcon icon="tabler-arrows-transfer-up" color="warning" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ plan.bandwidth }}</VListItemTitle>
</VListItem>
<VListItem class="px-0">
<template #prepend>
<VIcon icon="tabler-device-desktop-analytics" color="warning" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ plan.ram }}</VListItemTitle>
</VListItem>
<VListItem class="px-0">
<template #prepend>
<VIcon icon="tabler-cpu" color="warning" size="18" class="me-2" />
</template>
<VListItemTitle class="text-body-2">{{ plan.cores }}</VListItemTitle>
</VListItem>
</VList>
<VDivider class="my-4" />
<div class="d-flex flex-wrap justify-center ga-1 mb-4">
<VChip
v-for="feat in includedFeatures"
:key="feat"
size="x-small"
variant="tonal"
color="warning"
>
{{ feat }}
</VChip>
</div>
<a :href="accountUrl + '/register'" class="text-decoration-none d-block">
<VBtn
:color="plan.popular ? 'warning' : 'warning'"
:variant="plan.popular ? 'elevated' : 'tonal'"
block
>
Choose Plan
</VBtn>
</a>
</VCardText>
</VCard>
</VCol>
</VRow>
</VContainer>
</div>
</div>
</template>