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:
@@ -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`,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user