Сделан частичный перевод на русский язык, пока нет перехода на числовые ID категорий в БД
This commit is contained in:
parent
448a21649e
commit
2a3f179f54
BIN
public/images/film-bg.avif
Normal file
BIN
public/images/film-bg.avif
Normal file
Binary file not shown.
After Width: | Height: | Size: 429 KiB |
BIN
public/images/main-bg-1.webp
Normal file
BIN
public/images/main-bg-1.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 435 KiB |
BIN
public/images/main-bg.webp
Normal file
BIN
public/images/main-bg.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 651 KiB |
BIN
src/assets/images/film-bg.avif
Normal file
BIN
src/assets/images/film-bg.avif
Normal file
Binary file not shown.
After Width: | Height: | Size: 429 KiB |
@ -1,6 +1,7 @@
|
|||||||
import { Clock, ThumbsUp, MapPin } from 'lucide-react';
|
import { Clock, ThumbsUp, MapPin } from 'lucide-react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Article } from '../types';
|
import { Article } from '../types';
|
||||||
|
import MinutesWord from './MinutesWord.tsx';
|
||||||
|
|
||||||
interface ArticleCardProps {
|
interface ArticleCardProps {
|
||||||
article: Article;
|
article: Article;
|
||||||
@ -40,7 +41,7 @@ export function ArticleCard({ article, featured = false }: ArticleCardProps) {
|
|||||||
<p className="text-sm font-medium text-gray-900">{article.author.name}</p>
|
<p className="text-sm font-medium text-gray-900">{article.author.name}</p>
|
||||||
<div className="flex items-center text-sm text-gray-500">
|
<div className="flex items-center text-sm text-gray-500">
|
||||||
<Clock size={14} className="mr-1" />
|
<Clock size={14} className="mr-1" />
|
||||||
{article.readTime} min read
|
{article.readTime} <MinutesWord minutes={article.readTime} /> на чтение
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -55,7 +56,7 @@ export function ArticleCard({ article, featured = false }: ArticleCardProps) {
|
|||||||
to={`/article/${article.id}`}
|
to={`/article/${article.id}`}
|
||||||
className="text-blue-600 font-medium hover:text-blue-800"
|
className="text-blue-600 font-medium hover:text-blue-800"
|
||||||
>
|
>
|
||||||
Read More →
|
Читать →
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex items-center text-gray-500">
|
<div className="flex items-center text-gray-500">
|
||||||
<ThumbsUp size={16} className="mr-1" />
|
<ThumbsUp size={16} className="mr-1" />
|
||||||
|
@ -46,10 +46,10 @@ export function FeaturedSection() {
|
|||||||
<section className="py-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto">
|
<section className="py-12 px-4 sm:px-6 lg:px-8 max-w-7xl mx-auto">
|
||||||
<div className="text-center py-12">
|
<div className="text-center py-12">
|
||||||
<h3 className="text-xl font-medium text-gray-900 mb-2">
|
<h3 className="text-xl font-medium text-gray-900 mb-2">
|
||||||
No articles found
|
Еще нет заметок
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-gray-500">
|
<p className="text-gray-500">
|
||||||
Please try a different category or city
|
Выберите другой раздел или город
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@ -61,10 +61,10 @@ export function FeaturedSection() {
|
|||||||
<div className="flex justify-between items-center mb-8">
|
<div className="flex justify-between items-center mb-8">
|
||||||
<h2 className="text-3xl font-bold text-gray-900">
|
<h2 className="text-3xl font-bold text-gray-900">
|
||||||
{city ? `${city} ` : ''}
|
{city ? `${city} ` : ''}
|
||||||
{category ? `${category} Stories` : 'Featured Stories'}
|
{category ? `${category} Статьи` : 'Тематические статьи'}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-600">
|
<p className="text-gray-600">
|
||||||
Showing {Math.min(currentPage * ARTICLES_PER_PAGE, filteredArticles.length)} of {filteredArticles.length} articles
|
Показано {Math.min(currentPage * ARTICLES_PER_PAGE, filteredArticles.length)} из {filteredArticles.length} статей
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Palette } from 'lucide-react';
|
import { Palette } from 'lucide-react';
|
||||||
|
|
||||||
export function DesignStudioLogo() {
|
export function DesignStudioLogo() {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Mail, Phone, Instagram, Twitter, Facebook, ExternalLink } from 'lucide-react';
|
import { Mail, Phone, Instagram, Twitter, Facebook, ExternalLink } from 'lucide-react';
|
||||||
import { DesignStudioLogo } from './DesignStudioLogo';
|
import { DesignStudioLogo } from './DesignStudioLogo';
|
||||||
|
@ -53,7 +53,7 @@ export function Header() {
|
|||||||
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
|
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
|
||||||
</button>
|
</button>
|
||||||
<Link to="/" className="ml-2 flex items-center space-x-2">
|
<Link to="/" className="ml-2 flex items-center space-x-2">
|
||||||
<h1 className="text-2xl font-bold text-gray-900">CultureScope</h1>
|
<h1 className="text-2xl font-bold text-gray-900">Культура</h1>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
22
src/components/MinutesWord.tsx
Normal file
22
src/components/MinutesWord.tsx
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
// Описание типа для пропсов компонента
|
||||||
|
interface MinutesWordProps {
|
||||||
|
minutes: number; // Количество минут
|
||||||
|
}
|
||||||
|
|
||||||
|
const MinutesWord: React.FC<MinutesWordProps> = ({ minutes }) => {
|
||||||
|
const getMinuteWord = (minutes: number): string => {
|
||||||
|
if (minutes === 1) {
|
||||||
|
return "минута";
|
||||||
|
}
|
||||||
|
if (minutes >= 2 && minutes <= 4) {
|
||||||
|
return "минуты";
|
||||||
|
}
|
||||||
|
return "минут";
|
||||||
|
};
|
||||||
|
|
||||||
|
return <>{getMinuteWord(minutes)}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MinutesWord;
|
@ -1,8 +1,8 @@
|
|||||||
import { Category } from '../types';
|
import { Category } from '../types';
|
||||||
|
|
||||||
const backgroundImages = {
|
const backgroundImages = {
|
||||||
Film: 'https://images.unsplash.com/photo-1478720568477-152d9b164e26?auto=format&fit=crop&q=80&w=2070',
|
Film: '/images/film-bg.avif?auto=format&fit=crop&q=80&w=2070',
|
||||||
Theater: 'https://images.unsplash.com/photo-1507676184212-d03ab07a01bf?auto=format&fit=crop&q=80&w=2070',
|
Theater: '/images/main-bg-1.webp?auto=format&fit=crop&q=80&w=2070',
|
||||||
Music: 'https://images.unsplash.com/photo-1520523839897-bd0b52f945a0?auto=format&fit=crop&q=80&w=2070',
|
Music: 'https://images.unsplash.com/photo-1520523839897-bd0b52f945a0?auto=format&fit=crop&q=80&w=2070',
|
||||||
Sports: 'https://images.unsplash.com/photo-1461896836934-ffe607ba8211?auto=format&fit=crop&q=80&w=2070',
|
Sports: 'https://images.unsplash.com/photo-1461896836934-ffe607ba8211?auto=format&fit=crop&q=80&w=2070',
|
||||||
Art: 'https://images.unsplash.com/photo-1547826039-bfc35e0f1ea8?auto=format&fit=crop&q=80&w=2070',
|
Art: 'https://images.unsplash.com/photo-1547826039-bfc35e0f1ea8?auto=format&fit=crop&q=80&w=2070',
|
||||||
|
@ -6,6 +6,7 @@ import { ReactionButtons } from '../components/ReactionButtons';
|
|||||||
import { PhotoGallery } from '../components/PhotoGallery';
|
import { PhotoGallery } from '../components/PhotoGallery';
|
||||||
import { articles } from '../data/mock';
|
import { articles } from '../data/mock';
|
||||||
import { Article } from '../types';
|
import { Article } from '../types';
|
||||||
|
import MinutesWord from '../components/MinutesWord';
|
||||||
|
|
||||||
export function ArticlePage() {
|
export function ArticlePage() {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@ -60,7 +61,7 @@ export function ArticlePage() {
|
|||||||
className="inline-flex items-center text-gray-600 hover:text-gray-900 mb-8"
|
className="inline-flex items-center text-gray-600 hover:text-gray-900 mb-8"
|
||||||
>
|
>
|
||||||
<ArrowLeft size={20} className="mr-2" />
|
<ArrowLeft size={20} className="mr-2" />
|
||||||
Back to articles
|
К списку статей
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<article>
|
<article>
|
||||||
@ -76,8 +77,8 @@ export function ArticlePage() {
|
|||||||
<p className="font-medium text-gray-900">{articleData.author.name}</p>
|
<p className="font-medium text-gray-900">{articleData.author.name}</p>
|
||||||
<div className="flex items-center text-sm text-gray-500">
|
<div className="flex items-center text-sm text-gray-500">
|
||||||
<Clock size={14} className="mr-1" />
|
<Clock size={14} className="mr-1" />
|
||||||
{articleData.readTime} min read ·{' '}
|
{articleData.readTime} <MinutesWord minutes={articleData.readTime}/> на чтение ·{' '}
|
||||||
{new Date(articleData.publishedAt).toLocaleDateString('en-US', {
|
{new Date(articleData.publishedAt).toLocaleDateString('ru-RU', {
|
||||||
month: 'long',
|
month: 'long',
|
||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
|
@ -12,31 +12,61 @@ export function HomePage() {
|
|||||||
const getHeroTitle = () => {
|
const getHeroTitle = () => {
|
||||||
if (category) {
|
if (category) {
|
||||||
return {
|
return {
|
||||||
main: `Discover ${category}`,
|
main: getCategoryTitle(category),
|
||||||
sub: getCategoryDescription(category)
|
sub: getCategoryDescription(category),
|
||||||
|
description: getCategoryText(category)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
main: 'Discover the World of',
|
main: 'Discover the World of',
|
||||||
sub: 'Arts & Culture'
|
sub: 'Все о культуре Москвы и Петербурга',
|
||||||
|
description: 'Следите за событиями культурной жизни столиц: концерты, выставки, спектакли и многое другое в одном удобном формате.'
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getCategoryTitle = (category: Category): string => {
|
||||||
|
const title = {
|
||||||
|
Film: 'Кино',
|
||||||
|
Theater: 'Театр',
|
||||||
|
Music: 'Музыка',
|
||||||
|
Sports: 'Спорт',
|
||||||
|
Art: 'Искусство',
|
||||||
|
Legends: 'Легенды',
|
||||||
|
Anniversaries: 'Юбилеи',
|
||||||
|
Memory: 'Память'
|
||||||
|
};
|
||||||
|
return title[category];
|
||||||
|
};
|
||||||
|
|
||||||
const getCategoryDescription = (category: Category): string => {
|
const getCategoryDescription = (category: Category): string => {
|
||||||
const descriptions = {
|
const descriptions = {
|
||||||
Film: 'Cinema & Motion Pictures',
|
Film: 'Свет, камера, действие! Магия кино',
|
||||||
Theater: 'Stage & Performance',
|
Theater: 'Гармония актёра и зрителя',
|
||||||
Music: 'Rhythm & Harmony',
|
Music: 'Мелодии двух столиц',
|
||||||
Sports: 'Athletics & Competition',
|
Sports: 'Сила, движение, победа',
|
||||||
Art: 'Visual & Creative Expression',
|
Art: 'Шедевры говорят с нами',
|
||||||
Legends: 'Stories & Heritage',
|
Legends: 'Истории, которые вдохновляют',
|
||||||
Anniversaries: 'Celebrations & Milestones',
|
Anniversaries: 'Вехи истории и великие даты',
|
||||||
Memory: 'History & Remembrance'
|
Memory: 'Память о великом и наследие'
|
||||||
};
|
};
|
||||||
return descriptions[category];
|
return descriptions[category];
|
||||||
};
|
};
|
||||||
|
|
||||||
const { main, sub } = getHeroTitle();
|
const getCategoryText = (category: Category): string => {
|
||||||
|
const subtexts = {
|
||||||
|
Film: 'Узнайте о кино-премьерах, фестивалях и знаковых фильмах Москвы и Петербурга. Мир кино открывается для вас.',
|
||||||
|
Theater: 'Откройте для себя театральные премьеры и закулисье лучших сцен Москвы и Петербурга.',
|
||||||
|
Music: 'Исследуйте богатый музыкальный мир двух столиц. Узнайте о лучших исполнителях и событиях.',
|
||||||
|
Sports: 'Спорт — это не только движение, но и культура. Откройте для себя спортивные события двух столиц.',
|
||||||
|
Art: 'Откройте богатство искусства Москвы и Петербурга: от классики до современного авангарда.',
|
||||||
|
Legends: 'Узнайте о великих личностях Москвы и Петербурга. Легенды, которые формируют культуру.',
|
||||||
|
Anniversaries: 'Погрузитесь в исторические события и юбилеи, которые оставляют след в культуре двух столиц.',
|
||||||
|
Memory: 'Сохраняем культурные традиции и память о великих событиях и людях.'
|
||||||
|
};
|
||||||
|
return subtexts[category];
|
||||||
|
};
|
||||||
|
|
||||||
|
const { main, sub, description } = getHeroTitle();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -62,24 +92,9 @@ export function HomePage() {
|
|||||||
<span className="block text-blue-400">{sub}</span>
|
<span className="block text-blue-400">{sub}</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p className="mt-6 text-xl text-gray-200 max-w-2xl mx-auto">
|
<p className="mt-6 text-xl text-gray-200 max-w-2xl mx-auto">
|
||||||
{category ?
|
{description}
|
||||||
`Explore the latest ${category.toLowerCase()} stories, events, and cultural highlights from around the globe.` :
|
|
||||||
'Explore the latest in art, music, theater, and cultural events from around the globe. Join us on a journey through the world\'s most inspiring creative expressions.'
|
|
||||||
}
|
|
||||||
</p>
|
</p>
|
||||||
<div className="mt-8 flex justify-center space-x-4">
|
<div className="mt-8 flex justify-center space-x-4">
|
||||||
<a
|
|
||||||
href={category ? `/?category=${category}` : '/?category=Art'}
|
|
||||||
className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 transition-colors"
|
|
||||||
>
|
|
||||||
Explore Articles
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="#featured"
|
|
||||||
className="inline-flex items-center px-6 py-3 border border-gray-300 text-base font-medium rounded-md text-white hover:bg-white/10 transition-colors"
|
|
||||||
>
|
|
||||||
Latest Stories
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user