Merge version_2 into main #2

Merged
bender merged 1 commits from version_2 into main 2026-03-04 16:37:12 +00:00

View File

@@ -10,8 +10,107 @@ import FaqDouble from "@/components/sections/faq/FaqDouble";
import ContactText from "@/components/sections/contact/ContactText";
import FooterCard from "@/components/sections/footer/FooterCard";
import { Heart, HelpCircle, Mail, MapPin, Phone, Sparkles, Star } from "lucide-react";
import { useState } from "react";
export default function LandingPage() {
const [servicesData, setServicesData] = useState([
{
id: "01", title: "Роскошный дом", description: "Просторный современный дом с высокотехнологичным оснащением, каминами и панорамными окнами для максимального комфорта", images: [
{
id: "img-01-01", src: "http://img.b2bpic.net/free-photo/modern-spacious-room-with-large-panoramic-window_7502-7289.jpg", alt: "Премиум дом для отдыха - вид 1"},
{
id: "img-01-02", src: "http://img.b2bpic.net/free-photo/modern-spacious-room-with-large-panoramic-window_7502-7289.jpg", alt: "Премиум дом для отдыха - вид 2"},
{
id: "img-01-03", src: "http://img.b2bpic.net/free-photo/modern-spacious-room-with-large-panoramic-window_7502-7289.jpg", alt: "Премиум дом для отдыха - вид 3"},
],
},
{
id: "02", title: "Баня премиум-класса", description: "Традиционная баня из натурального дерева с парной, прохладным бассейном и комнатой отдыха для полного расслабления", images: [
{
id: "img-02-01", src: "http://img.b2bpic.net/free-photo/sauna-with-stones-thermometer-warm-benches-light-nordic-wellness_169016-69368.jpg", alt: "Роскошная баня - вид 1"},
{
id: "img-02-02", src: "http://img.b2bpic.net/free-photo/sauna-with-stones-thermometer-warm-benches-light-nordic-wellness_169016-69368.jpg", alt: "Роскошная баня - вид 2"},
{
id: "img-02-03", src: "http://img.b2bpic.net/free-photo/sauna-with-stones-thermometer-warm-benches-light-nordic-wellness_169016-69368.jpg", alt: "Роскошная баня - вид 3"},
],
},
{
id: "03", title: "Бассейны", description: "Крытый и открытый бассейны с системой подогрева воды, джакузи и лежаками для семейного отдыха", images: [
{
id: "img-03-01", src: "http://img.b2bpic.net/free-photo/watermelon-glasses-near-pool_501050-961.jpg", alt: "Премиум бассейны - вид 1"},
{
id: "img-03-02", src: "http://img.b2bpic.net/free-photo/watermelon-glasses-near-pool_501050-961.jpg", alt: "Премиум бассейны - вид 2"},
{
id: "img-03-03", src: "http://img.b2bpic.net/free-photo/watermelon-glasses-near-pool_501050-961.jpg", alt: "Премиум бассейны - вид 3"},
],
},
{
id: "04", title: "Гастрономия", description: "Профессиональные повара готовят изысканные блюда из местных ингредиентов. Возможна организация банкетов и корпоративов", images: [
{
id: "img-04-01", src: "http://img.b2bpic.net/free-photo/table-set-dinning-table_1339-3458.jpg", alt: "Ресторан и столовая - вид 1"},
{
id: "img-04-02", src: "http://img.b2bpic.net/free-photo/table-set-dinning-table_1339-3458.jpg", alt: "Ресторан и столовая - вид 2"},
{
id: "img-04-03", src: "http://img.b2bpic.net/free-photo/table-set-dinning-table_1339-3458.jpg", alt: "Ресторан и столовая - вид 3"},
],
},
]);
const handleUpdateServiceImage = (serviceId: string, imageIndex: number, newImageUrl: string) => {
setServicesData((prevData) =>
prevData.map((service) =>
service.id === serviceId
? {
...service,
images: service.images.map((img, idx) =>
idx === imageIndex ? { ...img, src: newImageUrl } : img
),
}
: service
)
);
};
const handleUpdateServiceText = (serviceId: string, field: "title" | "description", newText: string) => {
setServicesData((prevData) =>
prevData.map((service) =>
service.id === serviceId ? { ...service, [field]: newText } : service
)
);
};
const handleAddServiceImage = (serviceId: string) => {
setServicesData((prevData) =>
prevData.map((service) =>
service.id === serviceId
? {
...service,
images: [
...service.images,
{
id: `img-${service.id}-${service.images.length + 1}`,
src: "http://img.b2bpic.net/free-photo/modern-spacious-room-with-large-panoramic-window_7502-7289.jpg", alt: `${service.title} - вид ${service.images.length + 1}`,
},
],
}
: service
)
);
};
const handleRemoveServiceImage = (serviceId: string, imageIndex: number) => {
setServicesData((prevData) =>
prevData.map((service) =>
service.id === serviceId
? {
...service,
images: service.images.filter((_, idx) => idx !== imageIndex),
}
: service
)
);
};
return (
<ThemeProvider
defaultButtonVariant="hover-magnetic"
@@ -80,16 +179,11 @@ export default function LandingPage() {
<div id="services" data-section="services">
<FeatureCardThree
features={[
{
id: "01", title: "Роскошный дом", description: "Просторный современный дом с высокотехнологичным оснащением, каминами и панорамными окнами для максимального комфорта", imageSrc: "http://img.b2bpic.net/free-photo/modern-spacious-room-with-large-panoramic-window_7502-7289.jpg", imageAlt: "Премиум дом для отдыха"},
{
id: "02", title: "Баня премиум-класса", description: "Традиционная баня из натурального дерева с парной, прохладным бассейном и комнатой отдыха для полного расслабления", imageSrc: "http://img.b2bpic.net/free-photo/sauna-with-stones-thermometer-warm-benches-light-nordic-wellness_169016-69368.jpg", imageAlt: "Роскошная баня"},
{
id: "03", title: "Бассейны", description: "Крытый и открытый бассейны с системой подогрева воды, джакузи и лежаками для семейного отдыха", imageSrc: "http://img.b2bpic.net/free-photo/watermelon-glasses-near-pool_501050-961.jpg", imageAlt: "Премиум бассейны"},
{
id: "04", title: "Гастрономия", description: "Профессиональные повара готовят изысканные блюда из местных ингредиентов. Возможна организация банкетов и корпоративов", imageSrc: "http://img.b2bpic.net/free-photo/table-set-dinning-table_1339-3458.jpg", imageAlt: "Ресторан и столовая"},
]}
features={servicesData.map((service) => ({
id: service.id,
title: service.title,
description: service.description,
imageSrc: service.images[0]?.src || "", imageAlt: service.images[0]?.alt || ""}))}
textboxLayout="default"
gridVariant="four-items-2x2-equal-grid"
animationType="slide-up"
@@ -102,6 +196,78 @@ export default function LandingPage() {
/>
</div>
<div id="admin-panel" data-section="admin-panel" className="py-12 px-4 bg-slate-100">
<div className="max-w-6xl mx-auto">
<h2 className="text-3xl font-bold mb-8 text-slate-900">Панель управления услугами</h2>
<div className="space-y-8">
{servicesData.map((service) => (
<div key={service.id} className="bg-white rounded-lg shadow-md p-6">
<div className="mb-6">
<label className="block text-sm font-medium text-slate-700 mb-2">
Название услуги
</label>
<input
type="text"
value={service.title}
onChange={(e) => handleUpdateServiceText(service.id, "title", e.target.value)}
className="w-full px-3 py-2 border border-slate-300 rounded-md text-slate-900"
/>
</div>
<div className="mb-6">
<label className="block text-sm font-medium text-slate-700 mb-2">
Описание услуги
</label>
<textarea
value={service.description}
onChange={(e) => handleUpdateServiceText(service.id, "description", e.target.value)}
rows={3}
className="w-full px-3 py-2 border border-slate-300 rounded-md text-slate-900"
/>
</div>
<div className="mb-6">
<h3 className="text-lg font-semibold text-slate-900 mb-4">Фотографии ({service.images.length})</h3>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4 mb-4">
{service.images.map((image, idx) => (
<div key={image.id} className="relative">
<img
src={image.src}
alt={image.alt}
className="w-full h-32 object-cover rounded-md border border-slate-300"
/>
<div className="mt-2 space-y-2">
<input
type="text"
placeholder="URL изображения"
value={image.src}
onChange={(e) => handleUpdateServiceImage(service.id, idx, e.target.value)}
className="w-full px-2 py-1 text-sm border border-slate-300 rounded-md text-slate-900"
/>
<button
onClick={() => handleRemoveServiceImage(service.id, idx)}
className="w-full px-3 py-1 bg-red-500 text-white text-sm rounded-md hover:bg-red-600"
>
Удалить
</button>
</div>
</div>
))}
</div>
<button
onClick={() => handleAddServiceImage(service.id)}
className="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600"
>
+ Добавить фото
</button>
</div>
</div>
))}
</div>
</div>
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardFifteen
testimonial="Прекрасное место для семейного отдыха! Персонал очень внимателен, еда вкусная, все объекты идеально содержатся. Мы вернемся снова и рекомендуем друзьям."