Files
iiEasy/components/BusinessLandingSection.tsx

118 lines
4.1 KiB
TypeScript
Executable File
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.
import React, { useState, useMemo } from 'react';
import { CurrentView, BusinessStory } from '../types';
import { SECTION_IDS, BUSINESS_LANDING_CONTENT } from '../constants';
import BusinessCard from './BusinessCard';
import FilterSortBar, { ViewMode, SortOptionKey, SortOption } from './FilterSortBar';
interface BusinessLandingSectionProps {
businessStories: BusinessStory[];
setCurrentView: (view: CurrentView) => void;
setSelectedItemId: (id: string | null) => void;
}
const sortOptions: SortOption[] = [
{ key: 'alphabetical', label: 'По алфавиту (А-Я)' },
];
const BusinessLandingSection: React.FC<BusinessLandingSectionProps> = ({ businessStories, setCurrentView, setSelectedItemId }) => {
const [viewMode, setViewMode] = useState<ViewMode>('grid');
const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
const [selectedSort, setSelectedSort] = useState<SortOptionKey>('alphabetical');
const availableCategories = useMemo(() => {
if (!businessStories) return [];
return Array.from(new Set(businessStories.map(p => p.category))).sort();
}, [businessStories]);
const handleCategoryChange = (category: string) => {
setSelectedCategories(prev =>
prev.includes(category)
? prev.filter(c => c !== category)
: [...prev, category]
);
};
const filteredAndSortedStories = useMemo(() => {
if (!businessStories) return [];
const filtered = selectedCategories.length > 0
? businessStories.filter(p => selectedCategories.includes(p.category))
: businessStories;
return [...filtered].sort((a, b) => {
if (selectedSort === 'alphabetical') {
return a.title.localeCompare(b.title);
}
return 0; // Only alphabetical sort is supported
});
}, [businessStories, selectedCategories, selectedSort]);
if (!businessStories) {
return (
<section
id={SECTION_IDS.businessLandingPage}
className="py-16 md:py-24 bg-white min-h-screen flex justify-center items-center"
>
<p className="text-slate-600 font-inter">Загрузка кейсов...</p>
</section>
);
}
const layoutClasses = viewMode === 'grid'
? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8"
: "flex flex-col gap-4";
return (
<section
id={SECTION_IDS.businessLandingPage}
className="py-16 md:py-24 bg-white min-h-screen"
>
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
<header className="mb-12 md:mb-16">
<h1 className="font-quicksand text-4xl sm:text-5xl md:text-6xl font-bold text-slate-900">
{BUSINESS_LANDING_CONTENT.title}
</h1>
<p className="mt-4 text-lg md:text-xl text-slate-700 max-w-3xl">
{BUSINESS_LANDING_CONTENT.subtitle}
</p>
</header>
<FilterSortBar
viewMode={viewMode}
onViewChange={setViewMode}
availableCategories={availableCategories}
selectedCategories={selectedCategories}
onCategoryChange={handleCategoryChange}
onClearCategories={() => setSelectedCategories([])}
sortOptions={sortOptions}
selectedSort={selectedSort}
onSortChange={setSelectedSort}
/>
{filteredAndSortedStories.length > 0? (
<div className={layoutClasses}>
{filteredAndSortedStories.map(story => (
<BusinessCard
key={story.id}
story={story}
setCurrentView={setCurrentView}
setSelectedItemId={setSelectedItemId}
viewMode={viewMode}
/>
))}
</div>
) : (
<div className="text-center py-10 bg-white p-6 rounded-xl">
<h2 className="text-2xl font-quicksand font-semibold text-slate-700 mb-3">{BUSINESS_LANDING_CONTENT.emptyStateTitle}</h2>
<p className="text-slate-600 font-inter">
{BUSINESS_LANDING_CONTENT.emptyStateMessage}
</p>
</div>
)}
</div>
</section>
);
};
export default BusinessLandingSection;