feat: enhance hero section editor with tabbed interface and improved content management

This commit is contained in:
swve 2025-03-05 12:03:24 +01:00
parent 570d6d61bb
commit f45adf53e0

View file

@ -1,7 +1,7 @@
'use client'
import React from 'react'
import { LandingObject, LandingSection, LandingHeroSection, LandingTextAndImageSection, LandingLogos, LandingPeople, LandingBackground, LandingButton, LandingHeading, LandingImage, LandingFeaturedCourses } from './landing_types'
import { Plus, Eye, ArrowUpDown, Trash2, GripVertical, LayoutTemplate, ImageIcon, Users, Award, ArrowRight, Edit, Link, Upload, Save, BookOpen } from 'lucide-react'
import { Plus, Eye, ArrowUpDown, Trash2, GripVertical, LayoutTemplate, ImageIcon, Users, Award, ArrowRight, Edit, Link, Upload, Save, BookOpen, TextIcon } from 'lucide-react'
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'
import { Input } from "@components/ui/input"
import { Textarea } from "@components/ui/textarea"
@ -15,6 +15,7 @@ import { getOrgLandingMediaDirectory } from '@services/media/media'
import { getOrgCourses } from '@services/courses/courses'
import toast from 'react-hot-toast'
import useSWR from 'swr'
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@components/ui/tabs"
const SECTION_TYPES = {
hero: {
@ -504,7 +505,7 @@ const HeroSectionEditor: React.FC<{
<div className="space-y-4">
{/* Title */}
<div>
<Label htmlFor="title">Title</Label>
<Label htmlFor="title">Section Title</Label>
<Input
id="title"
value={section.title}
@ -513,8 +514,109 @@ const HeroSectionEditor: React.FC<{
/>
</div>
{/* Background */}
<Tabs defaultValue="content" className="w-full">
<TabsList className="grid w-full grid-cols-4 p-1 bg-gray-100 rounded-lg">
<TabsTrigger value="content" className="flex items-center space-x-2">
<TextIcon className="h-4 w-4" />
<span>Content</span>
</TabsTrigger>
<TabsTrigger value="background" className="flex items-center space-x-2">
<LayoutTemplate className="h-4 w-4" />
<span>Background</span>
</TabsTrigger>
<TabsTrigger value="buttons" className="flex items-center space-x-2">
<Button className="h-4 w-4" />
<span>Buttons</span>
</TabsTrigger>
<TabsTrigger value="illustration" className="flex items-center space-x-2">
<ImageIcon className="h-4 w-4" />
<span>Illustration</span>
</TabsTrigger>
</TabsList>
<TabsContent value="content" className="space-y-4 mt-4">
{/* Heading */}
<div className="space-y-4">
<div>
<Label htmlFor="heading">Heading</Label>
<Input
id="heading"
value={section.heading.text}
onChange={(e) => onChange({
...section,
heading: { ...section.heading, text: e.target.value }
})}
placeholder="Enter heading text"
/>
</div>
<div>
<Label htmlFor="headingColor">Heading Color</Label>
<div className="flex items-center space-x-2">
<Input
id="headingColor"
type="color"
value={section.heading.color}
onChange={(e) => onChange({
...section,
heading: { ...section.heading, color: e.target.value }
})}
className="w-20 h-10 p-1"
/>
<Input
value={section.heading.color}
onChange={(e) => onChange({
...section,
heading: { ...section.heading, color: e.target.value }
})}
placeholder="#000000"
className="font-mono"
/>
</div>
</div>
</div>
{/* Subheading */}
<div className="space-y-4">
<div>
<Label htmlFor="subheading">Subheading</Label>
<Input
id="subheading"
value={section.subheading.text}
onChange={(e) => onChange({
...section,
subheading: { ...section.subheading, text: e.target.value }
})}
placeholder="Enter subheading text"
/>
</div>
<div>
<Label htmlFor="subheadingColor">Subheading Color</Label>
<div className="flex items-center space-x-2">
<Input
id="subheadingColor"
type="color"
value={section.subheading.color}
onChange={(e) => onChange({
...section,
subheading: { ...section.subheading, color: e.target.value }
})}
className="w-20 h-10 p-1"
/>
<Input
value={section.subheading.color}
onChange={(e) => onChange({
...section,
subheading: { ...section.subheading, color: e.target.value }
})}
placeholder="#666666"
className="font-mono"
/>
</div>
</div>
</div>
</TabsContent>
<TabsContent value="background" className="space-y-4 mt-4">
<div>
<Label htmlFor="background">Background Type</Label>
<Select
@ -781,95 +883,14 @@ const HeroSectionEditor: React.FC<{
</div>
</div>
)}
</div>
</TabsContent>
{/* Heading */}
<div className="space-y-4">
<div>
<Label htmlFor="heading">Heading</Label>
<Input
id="heading"
value={section.heading.text}
onChange={(e) => onChange({
...section,
heading: { ...section.heading, text: e.target.value }
})}
placeholder="Enter heading text"
/>
</div>
<div>
<Label htmlFor="headingColor">Heading Color</Label>
<div className="flex items-center space-x-2">
<Input
id="headingColor"
type="color"
value={section.heading.color}
onChange={(e) => onChange({
...section,
heading: { ...section.heading, color: e.target.value }
})}
className="w-20 h-10 p-1"
/>
<Input
value={section.heading.color}
onChange={(e) => onChange({
...section,
heading: { ...section.heading, color: e.target.value }
})}
placeholder="#000000"
className="font-mono"
/>
</div>
</div>
</div>
{/* Subheading */}
<div className="space-y-4">
<div>
<Label htmlFor="subheading">Subheading</Label>
<Input
id="subheading"
value={section.subheading.text}
onChange={(e) => onChange({
...section,
subheading: { ...section.subheading, text: e.target.value }
})}
placeholder="Enter subheading text"
/>
</div>
<div>
<Label htmlFor="subheadingColor">Subheading Color</Label>
<div className="flex items-center space-x-2">
<Input
id="subheadingColor"
type="color"
value={section.subheading.color}
onChange={(e) => onChange({
...section,
subheading: { ...section.subheading, color: e.target.value }
})}
className="w-20 h-10 p-1"
/>
<Input
value={section.subheading.color}
onChange={(e) => onChange({
...section,
subheading: { ...section.subheading, color: e.target.value }
})}
placeholder="#666666"
className="font-mono"
/>
</div>
</div>
</div>
{/* Buttons */}
<div>
<Label>Buttons (Max 2)</Label>
<div className="space-y-3 mt-2">
<TabsContent value="buttons" className="space-y-4 mt-4">
<div className="space-y-3">
{section.buttons.map((button, index) => (
<div key={index} className="grid grid-cols-[1fr,1fr,auto] gap-2">
<div key={index} className="grid grid-cols-[1fr,1fr,auto] gap-2 p-4 border rounded-lg">
<div className="space-y-2">
<Label>Button Text & Colors</Label>
<Input
value={button.text}
onChange={(e) => {
@ -880,6 +901,8 @@ const HeroSectionEditor: React.FC<{
placeholder="Button text"
/>
<div className="flex items-center space-x-2">
<div className="space-y-1">
<Label className="text-xs">Text</Label>
<Input
type="color"
value={button.color}
@ -888,8 +911,11 @@ const HeroSectionEditor: React.FC<{
newButtons[index] = { ...button, color: e.target.value }
onChange({ ...section, buttons: newButtons })
}}
className="w-10 h-8 p-1"
className="w-full h-8 p-1"
/>
</div>
<div className="space-y-1">
<Label className="text-xs">Background</Label>
<Input
type="color"
value={button.background}
@ -898,11 +924,13 @@ const HeroSectionEditor: React.FC<{
newButtons[index] = { ...button, background: e.target.value }
onChange({ ...section, buttons: newButtons })
}}
className="w-10 h-8 p-1"
className="w-full h-8 p-1"
/>
</div>
</div>
</div>
<div className="space-y-2">
<Label>Button Link</Label>
<div className="flex items-center space-x-2">
<Link className="h-4 w-4 text-gray-500" />
<Input
@ -923,7 +951,7 @@ const HeroSectionEditor: React.FC<{
const newButtons = section.buttons.filter((_, i) => i !== index)
onChange({ ...section, buttons: newButtons })
}}
className="text-red-500 hover:text-red-600 hover:bg-red-50"
className="text-red-500 hover:text-red-600 hover:bg-red-50 self-start mt-8"
>
<Trash2 className="h-4 w-4" />
</Button>
@ -951,12 +979,10 @@ const HeroSectionEditor: React.FC<{
</Button>
)}
</div>
</div>
</TabsContent>
{/* Illustration */}
<TabsContent value="illustration" className="space-y-4 mt-4">
<div className="space-y-4">
<Label>Illustration</Label>
<div className="border rounded-lg p-4 space-y-4">
<div className="space-y-2">
<Label>Illustration Image</Label>
<Input
@ -1080,7 +1106,8 @@ const HeroSectionEditor: React.FC<{
</Button>
)}
</div>
</div>
</TabsContent>
</Tabs>
</div>
</div>
)