feat(ZEE-29): implement design system, dark mode, and JSON content management

- Add comprehensive design system with CSS variables, animations, and utility classes
- Implement dark mode with ThemeProvider (system preference + manual toggle)
- Create JSON-based content management system in src/content/
- Update all pages to use structured JSON content
- Add ThemeProvider component with theme toggle button
- Update Header with glass effect and animated mobile menu
- Update Footer with dark mode support
- Update documentation (README.md, CLAUDE.md, knowledge.md, proto/README.md)
- Sync with Linear (ZEE-29 completed)
This commit is contained in:
Do Siki
2026-01-24 02:30:27 +01:00
parent db464d1c48
commit d1213f9b3f
27 changed files with 3294 additions and 450 deletions
+543 -13
View File
@@ -1,26 +1,556 @@
@import "tailwindcss";
/* ========================================
mozdIT Bt. Design System
======================================== */
/* Design Tokens - Light Theme */
:root {
--background: #ffffff;
--foreground: #171717;
/* Brand Colors */
--color-primary-50: #eff6ff;
--color-primary-100: #dbeafe;
--color-primary-200: #bfdbfe;
--color-primary-300: #93c5fd;
--color-primary-400: #60a5fa;
--color-primary-500: #3b82f6;
--color-primary-600: #2563eb;
--color-primary-700: #1d4ed8;
--color-primary-800: #1e40af;
--color-primary-900: #1e3a8a;
--color-primary-950: #172554;
/* Accent Colors */
--color-accent-50: #eef2ff;
--color-accent-100: #e0e7ff;
--color-accent-200: #c7d2fe;
--color-accent-500: #6366f1;
--color-accent-600: #4f46e5;
/* Success Colors */
--color-success-50: #f0fdf4;
--color-success-500: #22c55e;
--color-success-600: #16a34a;
/* Warning Colors */
--color-warning-50: #fffbeb;
--color-warning-500: #f59e0b;
/* Error Colors */
--color-error-50: #fef2f2;
--color-error-500: #ef4444;
--color-error-600: #dc2626;
/* Neutral Colors - Light Mode */
--color-background: #ffffff;
--color-background-secondary: #f9fafb;
--color-background-tertiary: #f3f4f6;
--color-foreground: #111827;
--color-foreground-secondary: #374151;
--color-foreground-muted: #6b7280;
--color-border: #e5e7eb;
--color-border-light: #f3f4f6;
/* Shadows */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
/* Transitions */
--transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-normal: 200ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-bounce: 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
/* Spacing */
--container-padding: 1rem;
--section-spacing: 4rem;
/* Border Radius */
--radius-sm: 0.375rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--radius-xl: 1rem;
--radius-full: 9999px;
/* Fonts */
--font-sans: var(--font-geist-sans), system-ui, -apple-system, sans-serif;
--font-mono: var(--font-geist-mono), 'Fira Code', monospace;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
/* Dark Mode */
[data-theme="dark"] {
--color-background: #0f172a;
--color-background-secondary: #1e293b;
--color-background-tertiary: #334155;
--color-foreground: #f8fafc;
--color-foreground-secondary: #e2e8f0;
--color-foreground-muted: #94a3b8;
--color-border: #334155;
--color-border-light: #1e293b;
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.3);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.3);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.4);
}
/* System preference fallback */
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
:root:not([data-theme="light"]) {
--color-background: #0f172a;
--color-background-secondary: #1e293b;
--color-background-tertiary: #334155;
--color-foreground: #f8fafc;
--color-foreground-secondary: #e2e8f0;
--color-foreground-muted: #94a3b8;
--color-border: #334155;
--color-border-light: #1e293b;
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.3);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.3);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.5), 0 8px 10px -6px rgb(0 0 0 / 0.4);
}
}
/* Tailwind Theme Extension */
@theme inline {
--color-background: var(--color-background);
--color-foreground: var(--color-foreground);
--font-sans: var(--font-sans);
--font-mono: var(--font-mono);
}
/* Base Styles */
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
background: var(--color-background);
color: var(--color-foreground);
font-family: var(--font-sans);
transition: background-color var(--transition-normal), color var(--transition-normal);
}
/* Selection */
::selection {
background: var(--color-primary-500);
color: white;
}
/* Focus Styles */
:focus-visible {
outline: 2px solid var(--color-primary-500);
outline-offset: 2px;
}
/* Custom Scrollbar */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: var(--color-background-secondary);
}
::-webkit-scrollbar-thumb {
background: var(--color-border);
border-radius: var(--radius-full);
}
::-webkit-scrollbar-thumb:hover {
background: var(--color-foreground-muted);
}
/* ========================================
Utility Classes
======================================== */
/* Gradient Backgrounds */
.bg-gradient-hero {
background: linear-gradient(
135deg,
var(--color-primary-50) 0%,
var(--color-accent-50) 50%,
var(--color-primary-100) 100%
);
}
[data-theme="dark"] .bg-gradient-hero {
background: linear-gradient(
135deg,
var(--color-background-secondary) 0%,
var(--color-background-tertiary) 50%,
var(--color-background-secondary) 100%
);
}
/* Glass Effect */
.glass {
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
[data-theme="dark"] .glass {
background: rgba(15, 23, 42, 0.8);
}
/* ========================================
Animation Keyframes
======================================== */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes bounce {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.7;
}
}
@keyframes shimmer {
0% {
background-position: -200% 0;
}
100% {
background-position: 200% 0;
}
}
@keyframes spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes float {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-5px);
}
}
/* Animation Classes */
.animate-fade-in {
animation: fadeIn var(--transition-slow) ease-out forwards;
}
.animate-fade-in-up {
animation: fadeInUp 0.5s ease-out forwards;
}
.animate-fade-in-down {
animation: fadeInDown 0.5s ease-out forwards;
}
.animate-slide-in-left {
animation: slideInLeft 0.5s ease-out forwards;
}
.animate-slide-in-right {
animation: slideInRight 0.5s ease-out forwards;
}
.animate-scale-in {
animation: scaleIn 0.3s ease-out forwards;
}
.animate-bounce-slow {
animation: bounce 2s ease-in-out infinite;
}
.animate-pulse-slow {
animation: pulse 2s ease-in-out infinite;
}
.animate-float {
animation: float 3s ease-in-out infinite;
}
.animate-spin-slow {
animation: spin 3s linear infinite;
}
/* Staggered animations for children */
.stagger-children > *:nth-child(1) { animation-delay: 0ms; }
.stagger-children > *:nth-child(2) { animation-delay: 100ms; }
.stagger-children > *:nth-child(3) { animation-delay: 200ms; }
.stagger-children > *:nth-child(4) { animation-delay: 300ms; }
.stagger-children > *:nth-child(5) { animation-delay: 400ms; }
.stagger-children > *:nth-child(6) { animation-delay: 500ms; }
/* Hover Animations */
.hover-lift {
transition: transform var(--transition-normal), box-shadow var(--transition-normal);
}
.hover-lift:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-lg);
}
.hover-scale {
transition: transform var(--transition-fast);
}
.hover-scale:hover {
transform: scale(1.02);
}
.hover-glow {
transition: box-shadow var(--transition-normal);
}
.hover-glow:hover {
box-shadow: 0 0 20px rgba(59, 130, 246, 0.3);
}
/* Button Styles */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.75rem 1.5rem;
font-weight: 500;
border-radius: var(--radius-md);
transition: all var(--transition-normal);
cursor: pointer;
border: none;
text-decoration: none;
}
.btn:active {
transform: scale(0.98);
}
.btn-primary {
background: var(--color-primary-600);
color: white;
}
.btn-primary:hover {
background: var(--color-primary-700);
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.4);
}
.btn-secondary {
background: transparent;
color: var(--color-primary-600);
border: 2px solid var(--color-primary-600);
}
.btn-secondary:hover {
background: var(--color-primary-50);
}
[data-theme="dark"] .btn-secondary:hover {
background: var(--color-primary-900);
}
/* Card Styles */
.card {
background: var(--color-background);
border: 1px solid var(--color-border);
border-radius: var(--radius-xl);
padding: 2rem;
transition: all var(--transition-normal);
}
.card:hover {
border-color: var(--color-primary-200);
box-shadow: var(--shadow-md);
}
[data-theme="dark"] .card:hover {
border-color: var(--color-primary-800);
}
/* Icon Container */
.icon-container {
display: flex;
align-items: center;
justify-content: center;
width: 3rem;
height: 3rem;
background: var(--color-primary-100);
border-radius: var(--radius-lg);
transition: all var(--transition-normal);
}
.icon-container-lg {
width: 4rem;
height: 4rem;
}
[data-theme="dark"] .icon-container {
background: var(--color-primary-900);
}
.group:hover .icon-container {
background: var(--color-primary-200);
transform: scale(1.1);
}
[data-theme="dark"] .group:hover .icon-container {
background: var(--color-primary-800);
}
/* Section Styles */
.section {
padding: var(--section-spacing) 0;
}
.container {
max-width: 80rem;
margin: 0 auto;
padding: 0 var(--container-padding);
}
@media (min-width: 640px) {
:root {
--container-padding: 1.5rem;
}
}
@media (min-width: 1024px) {
:root {
--container-padding: 2rem;
}
}
/* Link Styles */
.link {
color: var(--color-primary-600);
text-decoration: none;
transition: color var(--transition-fast);
position: relative;
}
.link:hover {
color: var(--color-primary-700);
}
.link-underline::after {
content: '';
position: absolute;
bottom: -2px;
left: 0;
width: 0;
height: 2px;
background: var(--color-primary-600);
transition: width var(--transition-normal);
}
.link-underline:hover::after {
width: 100%;
}
/* Prose adjustments for dark mode */
[data-theme="dark"] .prose {
--tw-prose-body: var(--color-foreground-secondary);
--tw-prose-headings: var(--color-foreground);
--tw-prose-links: var(--color-primary-400);
--tw-prose-bold: var(--color-foreground);
}
/* Reduce motion for accessibility */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
html {
scroll-behavior: auto;
}
}
+7 -4
View File
@@ -1,12 +1,15 @@
import { siteConfig } from '@/config/site'
import { content } from '@/content'
import type { Metadata } from 'next'
const { contact: pageContent } = content.pages
export const metadata: Metadata = {
title: `Kapcsolat | ${siteConfig.general.name}`,
description: 'Vegye fel velünk a kapcsolatot! Segítünk minden IT kérdésében. Email, telefon és online űrlap is rendelkezésére áll.',
title: `${pageContent.meta.title} | ${siteConfig.general.name}`,
description: pageContent.meta.description,
openGraph: {
title: `Kapcsolat | ${siteConfig.general.name}`,
description: 'Vegye fel velünk a kapcsolatot! Segítünk minden IT kérdésében.',
title: `${pageContent.meta.title} | ${siteConfig.general.name}`,
description: pageContent.meta.description,
url: `${siteConfig.general.url}/kapcsolat`,
},
}
+42 -53
View File
@@ -1,8 +1,11 @@
'use client'
import { siteConfig } from '@/config/site'
import { content } from '@/content'
import { useState } from 'react'
const { contact: pageContent } = content.pages
export default function ContactPage() {
const [formData, setFormData] = useState({
name: '',
@@ -20,27 +23,27 @@ export default function ContactPage() {
const newErrors: Record<string, string> = {}
if (!formData.name.trim()) {
newErrors.name = 'A név megadása kötelező'
newErrors.name = pageContent.form.fields.name.error
}
if (!formData.email.trim()) {
newErrors.email = 'Az email cím megadása kötelező'
newErrors.email = pageContent.form.fields.email.errorRequired
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
newErrors.email = 'Érvénytelen email cím formátum'
newErrors.email = pageContent.form.fields.email.errorInvalid
}
if (!formData.subject.trim()) {
newErrors.subject = 'A tárgy megadása kötelező'
newErrors.subject = pageContent.form.fields.subject.error
}
if (!formData.message.trim()) {
newErrors.message = 'Az üzenet megadása kötelező'
newErrors.message = pageContent.form.fields.message.errorRequired
} else if (formData.message.trim().length < 10) {
newErrors.message = 'Az üzenet legalább 10 karakter hosszú legyen'
newErrors.message = pageContent.form.fields.message.errorMinLength
}
if (!formData.gdprConsent) {
newErrors.gdprConsent = 'Az adatkezelési tájékoztató elfogadása kötelező'
newErrors.gdprConsent = pageContent.form.fields.gdpr.error
}
setErrors(newErrors)
@@ -93,7 +96,6 @@ export default function ContactPage() {
[name]: type === 'checkbox' ? (e.target as HTMLInputElement).checked : value
}))
// Clear error when user starts typing
if (errors[name]) {
setErrors(prev => ({ ...prev, [name]: '' }))
}
@@ -105,10 +107,10 @@ export default function ContactPage() {
<section className="bg-gradient-to-r from-blue-50 to-indigo-50 py-16">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
Kapcsolat
{pageContent.hero.title}
</h1>
<p className="text-xl text-gray-600 leading-relaxed">
Vegye fel velünk a kapcsolatot! Szívesen segítünk minden IT kérdésében.
{pageContent.hero.subtitle}
</p>
</div>
</section>
@@ -119,13 +121,13 @@ export default function ContactPage() {
<div>
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-6">
Küldjön üzenetet
{pageContent.form.title}
</h2>
{submitStatus === 'success' && (
<div className="mb-6 p-4 bg-green-50 border border-green-200 rounded-md">
<p className="text-green-800">
Köszönjük üzenetét! Hamarosan felvesszük Önnel a kapcsolatot.
{pageContent.form.successMessage}
</p>
</div>
)}
@@ -133,7 +135,7 @@ export default function ContactPage() {
{submitStatus === 'error' && (
<div className="mb-6 p-4 bg-red-50 border border-red-200 rounded-md">
<p className="text-red-800">
Hiba történt az üzenet küldése során. Kérjük, próbálja újra vagy írjon közvetlenül a {siteConfig.contact.email} címre.
{pageContent.form.errorMessage.replace('{email}', siteConfig.contact.email)}
</p>
</div>
)}
@@ -141,7 +143,7 @@ export default function ContactPage() {
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1">
Név *
{pageContent.form.fields.name.label} *
</label>
<input
type="text"
@@ -152,14 +154,14 @@ export default function ContactPage() {
className={`w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.name ? 'border-red-300' : 'border-gray-300'
}`}
placeholder="Az Ön neve"
placeholder={pageContent.form.fields.name.placeholder}
/>
{errors.name && <p className="mt-1 text-sm text-red-600">{errors.name}</p>}
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1">
Email cím *
{pageContent.form.fields.email.label} *
</label>
<input
type="email"
@@ -170,14 +172,14 @@ export default function ContactPage() {
className={`w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.email ? 'border-red-300' : 'border-gray-300'
}`}
placeholder="pelda@email.hu"
placeholder={pageContent.form.fields.email.placeholder}
/>
{errors.email && <p className="mt-1 text-sm text-red-600">{errors.email}</p>}
</div>
<div>
<label htmlFor="subject" className="block text-sm font-medium text-gray-700 mb-1">
Tárgy *
{pageContent.form.fields.subject.label} *
</label>
<input
type="text"
@@ -188,14 +190,14 @@ export default function ContactPage() {
className={`w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.subject ? 'border-red-300' : 'border-gray-300'
}`}
placeholder="Miben segíthetünk?"
placeholder={pageContent.form.fields.subject.placeholder}
/>
{errors.subject && <p className="mt-1 text-sm text-red-600">{errors.subject}</p>}
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium text-gray-700 mb-1">
Üzenet *
{pageContent.form.fields.message.label} *
</label>
<textarea
id="message"
@@ -206,7 +208,7 @@ export default function ContactPage() {
className={`w-full px-3 py-2 border rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 ${
errors.message ? 'border-red-300' : 'border-gray-300'
}`}
placeholder="Írja le részletesen kérését vagy kérdését..."
placeholder={pageContent.form.fields.message.placeholder}
/>
{errors.message && <p className="mt-1 text-sm text-red-600">{errors.message}</p>}
</div>
@@ -220,9 +222,10 @@ export default function ContactPage() {
onChange={handleInputChange}
className="mt-1 h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
/>
<span className="text-sm text-gray-700">
Elfogadom az <a href="/adatkezelesi-tajekoztato" className="text-blue-600 hover:text-blue-700 underline">adatkezelési tájékoztatót</a> és hozzájárulok személyes adataim kezeléséhez a kapcsolatfelvétel céljából. *
</span>
<span
className="text-sm text-gray-700"
dangerouslySetInnerHTML={{ __html: pageContent.form.fields.gdpr.label + ' *' }}
/>
</label>
{errors.gdprConsent && <p className="mt-1 text-sm text-red-600">{errors.gdprConsent}</p>}
</div>
@@ -232,7 +235,7 @@ export default function ContactPage() {
disabled={isSubmitting}
className="w-full bg-blue-600 hover:bg-blue-700 disabled:bg-blue-400 text-white font-medium py-3 px-4 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
>
{isSubmitting ? 'Küldés...' : 'Üzenet küldése'}
{isSubmitting ? pageContent.form.submittingButton : pageContent.form.submitButton}
</button>
</form>
</div>
@@ -242,7 +245,7 @@ export default function ContactPage() {
<div className="space-y-8">
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-8">
<h2 className="text-2xl font-bold text-gray-900 mb-6">
Elérhetőségek
{pageContent.info.title}
</h2>
<div className="space-y-6">
@@ -251,7 +254,7 @@ export default function ContactPage() {
<span className="text-lg"></span>
</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Email</h3>
<h3 className="font-semibold text-gray-900 mb-1">{pageContent.info.email.title}</h3>
<a
href={`mailto:${siteConfig.contact.email}`}
className="text-blue-600 hover:text-blue-700"
@@ -259,7 +262,7 @@ export default function ContactPage() {
{siteConfig.contact.email}
</a>
<p className="text-sm text-gray-600 mt-1">
24 órán belül válaszolunk
{pageContent.info.email.responseTime}
</p>
</div>
</div>
@@ -269,7 +272,7 @@ export default function ContactPage() {
<span className="text-lg">🏢</span>
</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Cég</h3>
<h3 className="font-semibold text-gray-900 mb-1">{pageContent.info.company.title}</h3>
<p className="text-gray-700">{siteConfig.general.name}</p>
<p className="text-sm text-gray-600">{siteConfig.contact.address}</p>
</div>
@@ -280,17 +283,17 @@ export default function ContactPage() {
<span className="text-lg">🌐</span>
</div>
<div>
<h3 className="font-semibold text-gray-900 mb-1">Webmail hozzáférés</h3>
<h3 className="font-semibold text-gray-900 mb-1">{pageContent.info.webmail.title}</h3>
<a
href={siteConfig.hero.cta.primary.href}
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 hover:text-blue-700"
>
Webmail belépés
{pageContent.info.webmail.linkText}
</a>
<p className="text-sm text-gray-600 mt-1">
Ügyfeleink számára
{pageContent.info.webmail.subtitle}
</p>
</div>
</div>
@@ -300,30 +303,16 @@ export default function ContactPage() {
{/* FAQ */}
<div className="bg-gray-50 rounded-xl p-8">
<h2 className="text-xl font-bold text-gray-900 mb-6">
Gyakori kérdések
{pageContent.faq.title}
</h2>
<div className="space-y-4">
<div>
<h3 className="font-semibold text-gray-900 mb-2">Milyen gyorsan válaszolnak?</h3>
<p className="text-gray-600 text-sm">
Email üzenetekre 24 órán belül, sürgős esetekben telefonon is elérhetők vagyunk.
</p>
</div>
<div>
<h3 className="font-semibold text-gray-900 mb-2">Van ingyenes konzultáció?</h3>
<p className="text-gray-600 text-sm">
Igen! Az első konzultáció mindig ingyenes, hogy megismerjük az Ön igényeit.
</p>
</div>
<div>
<h3 className="font-semibold text-gray-900 mb-2">Milyen fizetési módokat fogadnak el?</h3>
<p className="text-gray-600 text-sm">
Banki átutalás, PayPal és kártyás fizetés is lehetséges.
</p>
</div>
{pageContent.faq.items.map((item, index) => (
<div key={index}>
<h3 className="font-semibold text-gray-900 mb-2">{item.question}</h3>
<p className="text-gray-600 text-sm">{item.answer}</p>
</div>
))}
</div>
</div>
</div>
+26 -6
View File
@@ -3,6 +3,7 @@ import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import Header from "../components/Header";
import Footer from "../components/Footer";
import { ThemeProvider } from "../components/ThemeProvider";
import { siteConfig } from "../config/site";
const geistSans = Geist({
@@ -61,15 +62,34 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="hu">
<html lang="hu" suppressHydrationWarning>
<head>
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
} else if (savedTheme === 'light') {
document.documentElement.setAttribute('data-theme', 'light');
}
})();
`,
}}
/>
</head>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased min-h-screen flex flex-col`}
style={{ background: 'var(--color-background)', color: 'var(--color-foreground)' }}
>
<Header />
<main className="flex-1">
{children}
</main>
<Footer />
<ThemeProvider>
<Header />
<main className="flex-1">
{children}
</main>
<Footer />
</ThemeProvider>
</body>
</html>
);
+198 -66
View File
@@ -1,25 +1,54 @@
import { siteConfig } from '@/config/site'
import { content } from '@/content'
const { home: pageContent } = content.pages
export default function Home() {
return (
<div className="space-y-16">
<div className="space-y-0">
{/* Hero Section */}
<section className="bg-gradient-to-r from-blue-50 to-indigo-50 py-20">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold text-gray-900 mb-6 leading-tight">
<section className="bg-gradient-hero py-20 lg:py-28 relative overflow-hidden">
{/* Background decoration */}
<div className="absolute inset-0 overflow-hidden pointer-events-none">
<div
className="absolute -top-40 -right-40 w-80 h-80 rounded-full opacity-30 animate-pulse-slow"
style={{ background: 'var(--color-primary-200)' }}
/>
<div
className="absolute -bottom-40 -left-40 w-96 h-96 rounded-full opacity-20 animate-pulse-slow"
style={{ background: 'var(--color-accent-200)', animationDelay: '1s' }}
/>
</div>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center relative z-10">
<h1
className="text-4xl md:text-5xl lg:text-6xl font-bold mb-6 leading-tight animate-fade-in-up"
style={{ color: 'var(--color-foreground)' }}
>
{siteConfig.hero.title}
</h1>
<p className="text-lg md:text-xl text-gray-600 max-w-4xl mx-auto mb-8 leading-relaxed">
<p
className="text-lg md:text-xl max-w-4xl mx-auto mb-10 leading-relaxed animate-fade-in-up"
style={{ color: 'var(--color-foreground-muted)', animationDelay: '100ms' }}
>
{siteConfig.hero.description}
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center items-center">
<div
className="flex flex-col sm:flex-row gap-4 justify-center items-center animate-fade-in-up"
style={{ animationDelay: '200ms' }}
>
<a
href={siteConfig.hero.cta.primary.href}
target={siteConfig.hero.cta.primary.external ? '_blank' : undefined}
rel={siteConfig.hero.cta.primary.external ? 'noopener noreferrer' : undefined}
className="bg-blue-600 hover:bg-blue-700 text-white font-medium px-8 py-4 rounded-md transition-colors text-lg inline-flex items-center gap-2"
className="btn btn-primary text-lg px-8 py-4 group"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<svg
className="w-5 h-5 transition-transform duration-200 group-hover:scale-110"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10" />
</svg>
{siteConfig.hero.cta.primary.text}
@@ -27,7 +56,7 @@ export default function Home() {
{siteConfig.hero.cta.secondary && (
<a
href={siteConfig.hero.cta.secondary.href}
className="border-2 border-blue-600 text-blue-600 hover:bg-blue-50 font-medium px-8 py-4 rounded-md transition-colors text-lg"
className="btn btn-secondary text-lg px-8 py-4"
>
{siteConfig.hero.cta.secondary.text}
</a>
@@ -37,19 +66,44 @@ export default function Home() {
</section>
{/* USP Section */}
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16 bg-gray-50">
<div className="text-center">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-8">
{siteConfig.about.title}
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-12">
{siteConfig.about.usps.map((usp) => (
<div key={usp.id} className="text-center">
<div className="w-16 h-16 bg-blue-100 group-hover:bg-blue-200 rounded-full flex items-center justify-center mx-auto mb-4 transition-colors">
<section
className="py-20"
style={{ background: 'var(--color-background-secondary)' }}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2
className="text-3xl md:text-4xl font-bold mb-4"
style={{ color: 'var(--color-foreground)' }}
>
{siteConfig.about.title}
</h2>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 stagger-children">
{siteConfig.about.usps.map((usp, index) => (
<div
key={usp.id}
className="group text-center p-6 rounded-xl transition-all duration-300 hover-lift animate-fade-in-up"
style={{
background: 'var(--color-background)',
border: '1px solid var(--color-border)',
animationDelay: `${index * 100}ms`
}}
>
<div
className="icon-container icon-container-lg mx-auto mb-4"
>
<span className="text-2xl">{usp.icon}</span>
</div>
<h3 className="text-lg font-semibold text-gray-900 mb-2">{usp.title}</h3>
<p className="text-gray-600">{usp.description}</p>
<h3
className="text-lg font-semibold mb-2 transition-colors duration-200"
style={{ color: 'var(--color-foreground)' }}
>
{usp.title}
</h3>
<p style={{ color: 'var(--color-foreground-muted)' }}>
{usp.description}
</p>
</div>
))}
</div>
@@ -57,64 +111,142 @@ export default function Home() {
</section>
{/* Services Section */}
<section className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-6">
{siteConfig.services.title}
</h2>
<p className="text-lg text-gray-600 max-w-3xl mx-auto">
{siteConfig.services.subtitle}
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-5xl mx-auto">
{siteConfig.services.services.map((service) => (
<div key={service.id} className="group bg-white p-8 rounded-xl shadow-sm border border-gray-200 hover:shadow-md transition-all duration-300 hover:border-blue-200">
<div className="w-12 h-12 bg-blue-100 group-hover:bg-blue-200 rounded-lg flex items-center justify-center mb-4 transition-colors">
<span className="text-xl">{service.icon}</span>
<section
className="py-20"
style={{ background: 'var(--color-background)' }}
>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2
className="text-3xl md:text-4xl font-bold mb-4"
style={{ color: 'var(--color-foreground)' }}
>
{siteConfig.services.title}
</h2>
<p
className="text-lg max-w-3xl mx-auto"
style={{ color: 'var(--color-foreground-muted)' }}
>
{siteConfig.services.subtitle}
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-5xl mx-auto">
{siteConfig.services.services.map((service, index) => (
<div
key={service.id}
className="group card hover-lift"
style={{ animationDelay: `${index * 100}ms` }}
>
<div className="icon-container mb-4">
<span className="text-xl">{service.icon}</span>
</div>
<h3
className="text-xl font-semibold mb-3 transition-colors duration-200 group-hover:text-blue-600"
style={{ color: 'var(--color-foreground)' }}
>
{service.title}
</h3>
<p
className="leading-relaxed mb-4"
style={{ color: 'var(--color-foreground-muted)' }}
>
{service.description}
</p>
<div className="mb-4">
<h4
className="text-sm font-semibold mb-2"
style={{ color: 'var(--color-foreground-secondary)' }}
>
{pageContent.serviceFeatures.title}
</h4>
<ul
className="text-sm space-y-1.5"
style={{ color: 'var(--color-foreground-muted)' }}
>
{service.features.map((feature, idx) => (
<li key={idx} className="flex items-start group/item">
<span
className="mr-2 transition-transform duration-200 group-hover/item:scale-125"
style={{ color: 'var(--color-success-500)' }}
>
</span>
{feature}
</li>
))}
</ul>
</div>
<a
href="/kapcsolat"
className="inline-flex items-center font-medium transition-all duration-200 group/link"
style={{ color: 'var(--color-primary-600)' }}
>
{service.ctaText}
<svg
className="w-4 h-4 ml-1 transition-transform duration-200 group-hover/link:translate-x-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</a>
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-3 group-hover:text-blue-600 transition-colors">{service.title}</h3>
<p className="text-gray-600 leading-relaxed">
{service.description}
</p>
<div className="mt-4">
<h4 className="text-sm font-semibold text-gray-700 mb-2">Szolgáltatás jellemzők:</h4>
<ul className="text-sm text-gray-600 space-y-1">
{service.features.map((feature, index) => (
<li key={index} className="flex items-start">
<span className="text-blue-500 mr-2"></span>
{feature}
</li>
))}
</ul>
</div>
<a href="/kapcsolat" className="inline-flex items-center text-blue-600 hover:text-blue-700 font-medium mt-4 transition-colors">
{service.ctaText}
<svg className="w-4 h-4 ml-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
</a>
</div>
))}
))}
</div>
</div>
</section>
{/* CTA Section */}
<section className="bg-gray-900 text-white py-16">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-3xl font-bold mb-4">
Kapcsolatfelvétel az első lépés
<section
className="py-20 relative overflow-hidden"
style={{ background: 'var(--color-foreground)' }}
>
{/* Animated background elements */}
<div className="absolute inset-0 overflow-hidden pointer-events-none opacity-10">
<div
className="absolute top-10 left-10 w-32 h-32 rounded-full animate-float"
style={{ background: 'var(--color-primary-500)' }}
/>
<div
className="absolute bottom-10 right-20 w-24 h-24 rounded-full animate-float"
style={{ background: 'var(--color-accent-500)', animationDelay: '0.5s' }}
/>
<div
className="absolute top-1/2 right-1/4 w-16 h-16 rounded-full animate-float"
style={{ background: 'var(--color-primary-400)', animationDelay: '1s' }}
/>
</div>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center relative z-10">
<h2
className="text-3xl md:text-4xl font-bold mb-4"
style={{ color: 'var(--color-background)' }}
>
{pageContent.cta.title}
</h2>
<p className="text-xl text-gray-300 mb-8">
Mutassuk meg, hogyan segíthetünk Önnek megvalósítani címeit!
<p
className="text-xl mb-8 max-w-2xl mx-auto"
style={{ color: 'var(--color-background)', opacity: 0.8 }}
>
{pageContent.cta.subtitle}
</p>
<a
href="/kapcsolat"
className="inline-block bg-blue-600 hover:bg-blue-700 text-white font-medium px-8 py-3 rounded-md transition-colors"
className="btn btn-primary text-lg px-8 py-4 hover-glow"
>
Kapcsolatfelvétel
{pageContent.cta.button}
<svg
className="w-5 h-5 ml-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
</svg>
</a>
</div>
</section>
</div>
);
)
}
+141 -103
View File
@@ -1,153 +1,191 @@
import { siteConfig } from '@/config/site'
import { content } from '@/content'
import type { Metadata } from 'next'
const { about: pageContent } = content.pages
export const metadata: Metadata = {
title: `Rólunk | ${siteConfig.general.name}`,
description: 'Ismerje meg a mozdIT Bt. történetét, küldetését és értékeit. Több mint 10 éve nyújtunk megbízható IT szolgáltatásokat.',
title: `${pageContent.meta.title} | ${siteConfig.general.name}`,
description: pageContent.meta.description,
openGraph: {
title: `Rólunk | ${siteConfig.general.name}`,
description: 'Ismerje meg a mozdIT Bt. történetét, küldetését és értékeit.',
title: `${pageContent.meta.title} | ${siteConfig.general.name}`,
description: pageContent.meta.ogDescription,
url: `${siteConfig.general.url}/rolunk`,
},
}
export default function AboutPage() {
return (
<div className="space-y-16 py-8">
<div className="space-y-0">
{/* Hero Section */}
<section className="bg-gradient-to-r from-blue-50 to-indigo-50 py-16">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
Rólunk
<section className="bg-gradient-hero py-16 lg:py-24 relative overflow-hidden">
<div className="absolute inset-0 overflow-hidden pointer-events-none">
<div
className="absolute -top-20 -right-20 w-60 h-60 rounded-full opacity-20 animate-pulse-slow"
style={{ background: 'var(--color-primary-300)' }}
/>
</div>
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center relative z-10">
<h1
className="text-4xl md:text-5xl font-bold mb-6 animate-fade-in-up"
style={{ color: 'var(--color-foreground)' }}
>
{pageContent.hero.title}
</h1>
<p className="text-xl text-gray-600 leading-relaxed">
Több mint 10 éve biztosítunk megbízható IT infrastruktúrát és személyes ügyfélszolgálatot
<p
className="text-xl leading-relaxed animate-fade-in-up"
style={{ color: 'var(--color-foreground-muted)', animationDelay: '100ms' }}
>
{pageContent.hero.subtitle}
</p>
</div>
</section>
{/* Story Section */}
<section className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="prose prose-lg mx-auto">
<h2 className="text-3xl font-bold text-gray-900 mb-6">Történetünk</h2>
<div className="space-y-6 text-gray-700 leading-relaxed">
<p>
A <strong>mozdIT Bt.</strong> 2010-ben alakult azzal a céllal, hogy kisvállalkozások és
magánszemélyek számára nyújtson megbízható, személyes IT szolgáltatásokat.
Alapítóink több évtizedes tapasztalattal rendelkeznek a rendszeradminisztráció
és webfejlesztés területén.
</p>
<section
className="py-16"
style={{ background: 'var(--color-background)' }}
>
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="prose prose-lg mx-auto">
<h2
className="text-3xl font-bold mb-6"
style={{ color: 'var(--color-foreground)' }}
>
{pageContent.story.title}
</h2>
<p>
Kezdetben néhány ügyfél weboldalának üzemeltetésével indultunk, ma pedig
több száz domain és email fiók működését biztosítjuk. Növekedésünk során
mindig szem előtt tartottuk az alapelveinket: <em>megbízhatóság, személyes
kapcsolat és műszaki kiválóság</em>.
</p>
<p>
Csapatunk folyamatosan képezi magát a legújabb technológiák terén, hogy
ügyfeleink mindig korszerű és biztonságos megoldásokat kapjanak. Büszkék
vagyunk arra, hogy sok ügyfelünkkel évek óta tartjuk a kapcsolatot, és
számos projektet vittünk sikerre közösen.
</p>
<div
className="space-y-6 leading-relaxed"
style={{ color: 'var(--color-foreground-secondary)' }}
>
{pageContent.story.paragraphs.map((paragraph, index) => (
<p
key={index}
dangerouslySetInnerHTML={{ __html: paragraph }}
/>
))}
</div>
</div>
</div>
</section>
{/* Mission & Values */}
<section className="bg-gray-50 py-16">
<section
className="py-16"
style={{ background: 'var(--color-background-secondary)' }}
>
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-3xl font-bold text-gray-900 mb-4">
Küldetésünk és értékeink
<h2
className="text-3xl font-bold mb-4"
style={{ color: 'var(--color-foreground)' }}
>
{pageContent.mission.title}
</h2>
<p className="text-lg text-gray-600 max-w-3xl mx-auto">
Minden nap azért dolgozunk, hogy ügyfeleink digitális jelenléte biztonságos,
stabil és hatékony legyen.
<p
className="text-lg max-w-3xl mx-auto"
style={{ color: 'var(--color-foreground-muted)' }}
>
{pageContent.mission.subtitle}
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
<div className="text-center">
<div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-2xl">🛡</span>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 stagger-children">
{pageContent.mission.values.map((item, index) => (
<div
key={item.title}
className="group text-center p-8 rounded-xl hover-lift animate-fade-in-up"
style={{
background: 'var(--color-background)',
border: '1px solid var(--color-border)',
animationDelay: `${index * 100}ms`
}}
>
<div className="icon-container icon-container-lg mx-auto mb-4">
<span className="text-2xl">{item.icon}</span>
</div>
<h3
className="text-xl font-semibold mb-3"
style={{ color: 'var(--color-foreground)' }}
>
{item.title}
</h3>
<p style={{ color: 'var(--color-foreground-muted)' }}>
{item.description}
</p>
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-3">Megbízhatóság</h3>
<p className="text-gray-600">
99.9% uptime és 24/7 monitoring biztosítja, hogy szolgáltatásaink mindig
elérhetők legyenek.
</p>
</div>
<div className="text-center">
<div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-2xl">👥</span>
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-3">Személyes kapcsolat</h3>
<p className="text-gray-600">
Minden ügyfél számít számunkra. Személyre szabott megoldásokat kínálunk
és mindig elérhetők vagyunk.
</p>
</div>
<div className="text-center">
<div className="w-16 h-16 bg-blue-100 rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-2xl"></span>
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-3">Műszaki kiválóság</h3>
<p className="text-gray-600">
Korszerű technológiák és bevált gyakorlatok alkalmazásával biztosítjuk
a legmagasabb színvonalú szolgáltatást.
</p>
</div>
))}
</div>
</div>
</section>
{/* Team Section */}
<section className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-3xl font-bold text-gray-900 mb-4">
Szakértő csapat
</h2>
<p className="text-lg text-gray-600">
Tapasztalt IT szakemberek, akik szenvedélyesen dolgoznak az ügyfeleink sikeréért
</p>
</div>
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-8">
<div className="prose prose-lg mx-auto">
<p className="text-gray-700 leading-relaxed">
Csapatunk rendszeradminisztrátorokból, webfejlesztőkből és ügyfélszolgálati
szakértőkből áll. Mindannyian több mint 10 éves tapasztalattal rendelkeznek
a maguk területén, és folyamatosan követik a technológiai újdonságokat.
</p>
<p className="text-gray-700 leading-relaxed">
Hiszünk abban, hogy a kommunikáció és a műszaki tudás együtt teremti meg
a tökéletes ügyfélélményt. Ezért minden munkatársunk nemcsak technikai
szakértő, hanem kiváló kommunikátor is.
<section
className="py-16"
style={{ background: 'var(--color-background)' }}
>
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2
className="text-3xl font-bold mb-4"
style={{ color: 'var(--color-foreground)' }}
>
{pageContent.team.title}
</h2>
<p
className="text-lg"
style={{ color: 'var(--color-foreground-muted)' }}
>
{pageContent.team.subtitle}
</p>
</div>
<div className="card">
<div className="prose prose-lg mx-auto">
{pageContent.team.paragraphs.map((paragraph, index) => (
<p
key={index}
className="leading-relaxed"
style={{ color: 'var(--color-foreground-secondary)' }}
>
{paragraph}
</p>
))}
</div>
</div>
</div>
</section>
{/* CTA Section */}
<section className="bg-gray-900 text-white py-16">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-3xl font-bold mb-4">
Legyen Ön is elégedett ügyfelünk!
<section
className="py-16 relative overflow-hidden"
style={{ background: 'var(--color-foreground)' }}
>
<div className="absolute inset-0 overflow-hidden pointer-events-none opacity-10">
<div
className="absolute top-10 right-20 w-24 h-24 rounded-full animate-float"
style={{ background: 'var(--color-primary-500)' }}
/>
</div>
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center relative z-10">
<h2
className="text-3xl font-bold mb-4"
style={{ color: 'var(--color-background)' }}
>
{pageContent.cta.title}
</h2>
<p className="text-xl text-gray-300 mb-8">
Vegye fel velünk a kapcsolatot, és beszéljük meg, hogyan segíthetünk Önnek.
<p
className="text-xl mb-8"
style={{ color: 'var(--color-background)', opacity: 0.8 }}
>
{pageContent.cta.subtitle}
</p>
<a
href="/kapcsolat"
className="inline-block bg-blue-600 hover:bg-blue-700 text-white font-medium px-8 py-3 rounded-md transition-colors"
className="btn btn-primary text-lg px-8 py-4 hover-glow"
>
Kapcsolatfelvétel
{pageContent.cta.button}
</a>
</div>
</section>
+42 -107
View File
@@ -1,12 +1,15 @@
import { siteConfig } from '@/config/site'
import { content } from '@/content'
import type { Metadata } from 'next'
const { services: pageContent } = content.pages
export const metadata: Metadata = {
title: `Szolgáltatások | ${siteConfig.general.name}`,
description: 'Webhosting, email szolgáltatás és DNS adminisztráció professzionális szinten. Ismerje meg részletes szolgáltatásainkat.',
title: `${pageContent.meta.title} | ${siteConfig.general.name}`,
description: pageContent.meta.description,
openGraph: {
title: `Szolgáltatások | ${siteConfig.general.name}`,
description: 'Webhosting, email szolgáltatás és DNS adminisztráció professzionális szinten.',
title: `${pageContent.meta.title} | ${siteConfig.general.name}`,
description: pageContent.meta.ogDescription,
url: `${siteConfig.general.url}/szolgaltatasok`,
},
}
@@ -18,10 +21,10 @@ export default function ServicesPage() {
<section className="bg-gradient-to-r from-blue-50 to-indigo-50 py-16">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h1 className="text-4xl md:text-5xl font-bold text-gray-900 mb-6">
Szolgáltatásaink
{pageContent.hero.title}
</h1>
<p className="text-xl text-gray-600 leading-relaxed">
Teljes körű IT megoldások kisvállalkozások és magánszemélyek számára
{pageContent.hero.subtitle}
</p>
</div>
</section>
@@ -39,7 +42,7 @@ export default function ServicesPage() {
<p className="text-gray-600 leading-relaxed mb-6">{service.description}</p>
<div className="mb-6">
<h3 className="text-lg font-semibold text-gray-900 mb-3">Szolgáltatás jellemzők:</h3>
<h3 className="text-lg font-semibold text-gray-900 mb-3">{content.common.labels.features}</h3>
<ul className="space-y-2">
{service.features.map((feature, index) => (
<li key={index} className="flex items-start">
@@ -69,97 +72,35 @@ export default function ServicesPage() {
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-3xl font-bold text-gray-900 mb-4">
Részletes szolgáltatásleírás
{pageContent.details.title}
</h2>
<p className="text-lg text-gray-600">
Minden szolgáltatásunk mögött évtizedes tapasztalat és modern technológia áll
{pageContent.details.subtitle}
</p>
</div>
<div className="space-y-12">
{/* Web Hosting Details */}
<div className="bg-white rounded-xl p-8 shadow-sm">
<div className="flex items-start space-x-4">
<div className="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-xl">🌐</span>
</div>
<div className="flex-1">
<h3 className="text-2xl font-bold text-gray-900 mb-4">Web Hosting részletesen</h3>
<div className="prose prose-lg text-gray-700">
<p>
Weboldalak biztonságos és gyors üzemeltetése SSD tárolással, automatikus biztonsági mentéssel
és 24/7 monitoringgal. Támogatjuk a PHP, Python, Node.js technológiákat és MySQL/PostgreSQL
adatbázisokat.
</p>
<h4 className="text-lg font-semibold text-gray-900 mt-6 mb-3">Technikai specifikációk:</h4>
<ul className="space-y-1">
<li>SSD tárhely 10GB-tól 500GB-ig</li>
<li>Havi adatforgalom: korlátlan</li>
<li>SSL tanúsítványok (Let's Encrypt vagy prémium)</li>
<li>CDN integráció a gyorsabb betöltésért</li>
<li>Automatikus napi biztonsági mentés</li>
<li>cPanel vagy egyedi admin felület</li>
</ul>
{pageContent.details.services.map((service) => (
<div key={service.title} className="bg-white rounded-xl p-8 shadow-sm">
<div className="flex items-start space-x-4">
<div className="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-xl">{service.icon}</span>
</div>
<div className="flex-1">
<h3 className="text-2xl font-bold text-gray-900 mb-4">{service.title}</h3>
<div className="prose prose-lg text-gray-700">
<p>{service.description}</p>
<h4 className="text-lg font-semibold text-gray-900 mt-6 mb-3">{service.specs.title}</h4>
<ul className="space-y-1">
{service.specs.items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
</div>
</div>
</div>
</div>
{/* Email Service Details */}
<div className="bg-white rounded-xl p-8 shadow-sm">
<div className="flex items-start space-x-4">
<div className="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-xl"></span>
</div>
<div className="flex-1">
<h3 className="text-2xl font-bold text-gray-900 mb-4">Email szolgáltatás részletesen</h3>
<div className="prose prose-lg text-gray-700">
<p>
Professzionális email fiókok saját domain névvel, spam szűréssel és vírusvédelemmel.
Webmail felület és IMAP/POP3/SMTP támogatás minden népszerű email klienssel.
</p>
<h4 className="text-lg font-semibold text-gray-900 mt-6 mb-3">Email funkciók:</h4>
<ul className="space-y-1">
<li>Korlátlan email fiókok létrehozása</li>
<li>5GB-50GB tárhelyet fiókként</li>
<li>Webmail hozzáférés (Roundcube/SOGo)</li>
<li>Mobilalkalmazás szinkronizáció</li>
<li>Spam és vírusszűrés</li>
<li>Email továbbítás és automatikus válaszok</li>
<li>Backup és archiválás</li>
</ul>
</div>
</div>
</div>
</div>
{/* DNS Administration Details */}
<div className="bg-white rounded-xl p-8 shadow-sm">
<div className="flex items-start space-x-4">
<div className="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center flex-shrink-0">
<span className="text-xl"></span>
</div>
<div className="flex-1">
<h3 className="text-2xl font-bold text-gray-900 mb-4">DNS adminisztráció részletesen</h3>
<div className="prose prose-lg text-gray-700">
<p>
Teljes DNS kezelés domain regisztrációval, átvitellel és professzionális beállításokkal.
Gyors propagáció és megbízható névszerverek világszerte.
</p>
<h4 className="text-lg font-semibold text-gray-900 mt-6 mb-3">DNS szolgáltatások:</h4>
<ul className="space-y-1">
<li>Domain regisztráció (.hu, .com, .eu, stb.)</li>
<li>Domain átvitel más szolgáltatótól</li>
<li>DNS rekord kezelés (A, CNAME, MX, TXT)</li>
<li>Subdomain beállítások</li>
<li>Redirect és forwarding szolgáltatások</li>
<li>DNSSEC támogatás</li>
<li>API hozzáférés fejlesztőknek</li>
</ul>
</div>
</div>
</div>
</div>
))}
</div>
</div>
</section>
@@ -168,24 +109,18 @@ export default function ServicesPage() {
<section className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="bg-blue-50 rounded-xl p-8 text-center">
<h2 className="text-2xl font-bold text-gray-900 mb-4">
Műszaki támogatás
{pageContent.support.title}
</h2>
<p className="text-lg text-gray-700 mb-6">
Minden szolgáltatásunkhoz teljes körű műszaki támogatást biztosítunk
{pageContent.support.subtitle}
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 text-sm">
<div>
<h3 className="font-semibold text-gray-900 mb-2">Email támogatás</h3>
<p className="text-gray-600">24 órán belüli válasz</p>
</div>
<div>
<h3 className="font-semibold text-gray-900 mb-2">Telefonos segítség</h3>
<p className="text-gray-600">Munkaidőben elérhető</p>
</div>
<div>
<h3 className="font-semibold text-gray-900 mb-2">Sürgős esetek</h3>
<p className="text-gray-600">Azonnali beavatkozás</p>
</div>
{pageContent.support.channels.map((channel) => (
<div key={channel.title}>
<h3 className="font-semibold text-gray-900 mb-2">{channel.title}</h3>
<p className="text-gray-600">{channel.description}</p>
</div>
))}
</div>
</div>
</section>
@@ -194,17 +129,17 @@ export default function ServicesPage() {
<section className="bg-gray-900 text-white py-16">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-3xl font-bold mb-4">
Kezdjük el a közös munkát!
{pageContent.cta.title}
</h2>
<p className="text-xl text-gray-300 mb-8">
Vegye fel velünk a kapcsolatot ingyenes konzultációért és egyedi ajánlatért.
{pageContent.cta.subtitle}
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="/kapcsolat"
className="inline-block bg-blue-600 hover:bg-blue-700 text-white font-medium px-8 py-3 rounded-md transition-colors"
>
Kapcsolatfelvétel
{pageContent.cta.primaryButton}
</a>
<a
href={siteConfig.hero.cta.primary.href}
@@ -212,7 +147,7 @@ export default function ServicesPage() {
rel="noopener noreferrer"
className="inline-block border-2 border-white text-white hover:bg-white hover:text-gray-900 font-medium px-8 py-3 rounded-md transition-colors"
>
Webmail belépés
{pageContent.cta.secondaryButton}
</a>
</div>
</div>