Files
kovakemlak-crm/src/components/theme-customizer/theme-tab.tsx
T
egecankomur 37679e83e6 init: kovakemlak-crm project scaffold
- Next.js 16 + Appwrite multi-tenant emlak CRM
- Database: kovakemlak-db (properties, customers, customer_searches, property_matches, presentations, investors, activities, tenant_settings)
- Same stack as isletmem-kovakcrm (shadcn/ui template base)
- Modules: portföy, müşteri takibi, arama kriterleri, otomatik eşleştirme, sunum linki, yatırımcı portalı
2026-05-05 04:37:04 +03:00

291 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { Dices, Upload, Sun, Moon } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Label } from '@/components/ui/label'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Separator } from '@/components/ui/separator'
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'
import { useThemeManager } from '@/hooks/use-theme-manager'
import { useCircularTransition } from '@/hooks/use-circular-transition'
import { colorThemes, tweakcnThemes } from '@/config/theme-data'
import { radiusOptions, baseColors } from '@/config/theme-customizer-constants'
import { ColorPicker } from '@/components/color-picker'
import type { ImportedTheme } from '@/types/theme-customizer'
import React from 'react'
import "./circular-transition.css"
interface ThemeTabProps {
selectedTheme: string
setSelectedTheme: (theme: string) => void
selectedTweakcnTheme: string
setSelectedTweakcnTheme: (theme: string) => void
selectedRadius: string
setSelectedRadius: (radius: string) => void
setImportedTheme: (theme: ImportedTheme | null) => void
onImportClick: () => void
}
export function ThemeTab({
selectedTheme,
setSelectedTheme,
selectedTweakcnTheme,
setSelectedTweakcnTheme,
selectedRadius,
setSelectedRadius,
setImportedTheme,
onImportClick
}: ThemeTabProps) {
const {
isDarkMode,
brandColorsValues,
setBrandColorsValues,
applyTheme,
applyTweakcnTheme,
applyRadius,
handleColorChange
} = useThemeManager()
const { toggleTheme } = useCircularTransition()
const handleRandomShadcn = () => {
// Apply a random shadcn theme
const randomTheme = colorThemes[Math.floor(Math.random() * colorThemes.length)]
setSelectedTheme(randomTheme.value)
setSelectedTweakcnTheme("") // Clear tweakcn selection
setBrandColorsValues({}) // Clear brand colors state
setImportedTheme(null) // Clear imported theme
applyTheme(randomTheme.value, isDarkMode)
}
const handleRandomTweakcn = () => {
// Apply a random tweakcn theme
const randomTheme = tweakcnThemes[Math.floor(Math.random() * tweakcnThemes.length)]
setSelectedTweakcnTheme(randomTheme.value)
setSelectedTheme("") // Clear shadcn selection
setBrandColorsValues({}) // Clear brand colors state
setImportedTheme(null) // Clear imported theme
applyTweakcnTheme(randomTheme.preset, isDarkMode)
}
const handleRadiusSelect = (radius: string) => {
setSelectedRadius(radius)
applyRadius(radius)
}
const handleLightMode = (event: React.MouseEvent<HTMLButtonElement>) => {
if (isDarkMode === false) return
toggleTheme(event)
}
const handleDarkMode = (event: React.MouseEvent<HTMLButtonElement>) => {
if (isDarkMode === true) return
toggleTheme(event)
}
return (
<div className="p-4 space-y-6">
{/* Hazır temalar */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<Label className="text-sm font-medium">Hazır temalar</Label>
<Button variant="outline" size="sm" onClick={handleRandomShadcn} className="cursor-pointer">
<Dices className="h-3.5 w-3.5 mr-1.5" />
Rastgele
</Button>
</div>
<Select value={selectedTheme} onValueChange={(value) => {
setSelectedTheme(value)
setSelectedTweakcnTheme("") // Clear other selection
setBrandColorsValues({}) // Clear brand colors state
setImportedTheme(null) // Clear imported theme
applyTheme(value, isDarkMode)
}}>
<SelectTrigger className="w-full cursor-pointer">
<SelectValue placeholder="Tema seçin" />
</SelectTrigger>
<SelectContent className="max-h-60">
<div className="p-2">
{colorThemes.map((theme) => (
<SelectItem key={theme.value} value={theme.value} className="cursor-pointer">
<div className="flex items-center gap-2">
<div className="flex gap-1">
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.primary }}
/>
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.secondary }}
/>
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.accent }}
/>
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.muted }}
/>
</div>
<span>{theme.name}</span>
</div>
</SelectItem>
))}
</div>
</SelectContent>
</Select>
</div>
<Separator />
{/* Genişletilmiş temalar */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<Label className="text-sm font-medium">Genişletilmiş temalar</Label>
<Button variant="outline" size="sm" onClick={handleRandomTweakcn} className="cursor-pointer">
<Dices className="h-3.5 w-3.5 mr-1.5" />
Rastgele
</Button>
</div>
<Select value={selectedTweakcnTheme} onValueChange={(value) => {
setSelectedTweakcnTheme(value)
setSelectedTheme("") // Clear other selection
setBrandColorsValues({}) // Clear brand colors state
setImportedTheme(null) // Clear imported theme
const selectedPreset = tweakcnThemes.find(t => t.value === value)?.preset
if (selectedPreset) {
applyTweakcnTheme(selectedPreset, isDarkMode)
}
}}>
<SelectTrigger className="w-full cursor-pointer">
<SelectValue placeholder="Tema seçin" />
</SelectTrigger>
<SelectContent className="max-h-60">
<div className="p-2">
{tweakcnThemes.map((theme) => (
<SelectItem key={theme.value} value={theme.value} className="cursor-pointer">
<div className="flex items-center gap-2">
<div className="flex gap-1">
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.primary }}
/>
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.secondary }}
/>
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.accent }}
/>
<div
className="w-3 h-3 rounded-full border border-border/20"
style={{ backgroundColor: theme.preset.styles.light.muted }}
/>
</div>
<span>{theme.name}</span>
</div>
</SelectItem>
))}
</div>
</SelectContent>
</Select>
</div>
<Separator />
{/* Köşe yuvarlama */}
<div className="space-y-3">
<Label className="text-sm font-medium">Köşe yuvarlama</Label>
<div className="grid grid-cols-5 gap-2">
{radiusOptions.map((option) => (
<div
key={option.value}
className={`relative cursor-pointer rounded-md p-3 border transition-colors ${
selectedRadius === option.value
? "border-primary"
: "border-border hover:border-border/60"
}`}
onClick={() => handleRadiusSelect(option.value)}
>
<div className="text-center">
<div className="text-xs font-medium">{option.name}</div>
</div>
</div>
))}
</div>
</div>
<Separator />
{/* Görünüm modu */}
<div className="space-y-3">
<Label className="text-sm font-medium">Görünüm modu</Label>
<div className="grid grid-cols-2 gap-2">
<Button
variant={!isDarkMode ? "secondary" : "outline"}
size="sm"
onClick={handleLightMode}
className="cursor-pointer"
>
<Sun className="h-4 w-4 mr-1" />
Açık
</Button>
<Button
variant={isDarkMode ? "secondary" : "outline"}
size="sm"
onClick={handleDarkMode}
className="cursor-pointer"
>
<Moon className="h-4 w-4 mr-1" />
Koyu
</Button>
</div>
</div>
<Separator />
{/* Tema içe aktar */}
<div className="space-y-3">
<Button
variant="outline"
size="lg"
onClick={onImportClick}
className="w-full cursor-pointer"
>
<Upload className="h-3.5 w-3.5 mr-1.5" />
Tema içe aktar
</Button>
<p className="text-muted-foreground text-xs">
tweakcn.com gibi araçlardan dışa aktardığınız JSON tema dosyasını yükleyebilirsiniz.
</p>
</div>
{/* Marka renkleri */}
<Accordion type="single" collapsible className="w-full border-b rounded-lg">
<AccordionItem value="brand-colors" className="border border-border rounded-lg overflow-hidden">
<AccordionTrigger className="px-4 py-3 hover:no-underline hover:bg-muted/50 transition-colors">
<Label className="text-sm font-medium cursor-pointer">Marka renkleri</Label>
</AccordionTrigger>
<AccordionContent className="px-4 pb-4 pt-2 space-y-3 border-t border-border bg-muted/20">
{baseColors.map((color) => (
<div key={color.cssVar} className="flex items-center justify-between">
<ColorPicker
label={color.name}
cssVar={color.cssVar}
value={brandColorsValues[color.cssVar] || ""}
onChange={handleColorChange}
/>
</div>
))}
</AccordionContent>
</AccordionItem>
</Accordion>
</div>
)
}