Compare commits

...

2 Commits

5 changed files with 149 additions and 19 deletions

View File

@ -4,12 +4,12 @@ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import type { LiveBlog } from '@/lib/api'; import type { LiveBlog } from '@/lib/api';
import { import {
Clock, Clock,
MessageSquare, MessageSquare,
Eye, Eye,
Pin, Pin,
Play, Play,
Square, Square,
ChevronRight ChevronRight
} from 'lucide-react'; } from 'lucide-react';
@ -19,9 +19,9 @@ interface PinnedLiveBlogSidebarProps {
maxItems?: number; maxItems?: number;
} }
export function PinnedLiveBlogSidebar({ export function PinnedLiveBlogSidebar({
className = '', className = '',
maxItems = 3 maxItems = 3
}: PinnedLiveBlogSidebarProps) { }: PinnedLiveBlogSidebarProps) {
const { data: pinnedBlogs, isLoading, error } = usePinnedLiveBlogs(); const { data: pinnedBlogs, isLoading, error } = usePinnedLiveBlogs();
@ -31,7 +31,7 @@ export function PinnedLiveBlogSidebar({
<CardHeader> <CardHeader>
<CardTitle className="text-lg flex items-center gap-2"> <CardTitle className="text-lg flex items-center gap-2">
<Pin className="w-4 h-4" /> <Pin className="w-4 h-4" />
Pinned Live Blogs Во живо
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
@ -114,7 +114,7 @@ export function PinnedLiveBlogSidebar({
const now = new Date(); const now = new Date();
const diffMs = now.getTime() - date.getTime(); const diffMs = now.getTime() - date.getTime();
const diffMins = Math.floor(diffMs / 60000); const diffMins = Math.floor(diffMs / 60000);
if (diffMins < 60) { if (diffMins < 60) {
return `${diffMins}m ago`; return `${diffMins}m ago`;
} else if (diffMins < 1440) { } else if (diffMins < 1440) {
@ -137,13 +137,13 @@ export function PinnedLiveBlogSidebar({
<Pin className="w-4 h-4" /> <Pin className="w-4 h-4" />
Live Coverage Live Coverage
</CardTitle> </CardTitle>
<Badge variant="outline" className="text-xs"> <Badge variant="outline" className="text-xs">
{(pinnedBlogs || []).length} pinned {(pinnedBlogs || []).length} pinned
</Badge> </Badge>
</div> </div>
</CardHeader> </CardHeader>
<CardContent className="pt-0"> <CardContent className="pt-0">
{displayBlogs.length === 0 ? ( {displayBlogs.length === 0 ? (
<div className="py-6 text-center"> <div className="py-6 text-center">
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
@ -158,7 +158,7 @@ export function PinnedLiveBlogSidebar({
<div className="space-y-4"> <div className="space-y-4">
{displayBlogs.map((blog) => { {displayBlogs.map((blog) => {
const latestUpdate = getLatestUpdate(blog); const latestUpdate = getLatestUpdate(blog);
return ( return (
<Link <Link
key={blog.id} key={blog.id}
@ -177,9 +177,9 @@ export function PinnedLiveBlogSidebar({
</p> </p>
)} )}
</div> </div>
<Badge <Badge
className={`${getStatusColor(blog.status)} text-xs`} className={`${getStatusColor(blog.status)} text-xs`}
variant="outline" variant="outline"
> >
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
@ -235,4 +235,4 @@ export function PinnedLiveBlogSidebar({
</CardContent> </CardContent>
</Card> </Card>
); );
} }

View File

@ -6,7 +6,7 @@ import { Calendar, Eye, MessageSquare, Pin, ChevronDown, ChevronUp, Clock } from
import { useState } from 'react'; import { useState } from 'react';
export function PinnedLiveBlogsSidebar() { export function PinnedLiveBlogsSidebar() {
const [showUpdates, setShowUpdates] = useState(false); const [showUpdates, setShowUpdates] = useState(true);
const { data: liveBlogs, isLoading, error } = useQuery({ const { data: liveBlogs, isLoading, error } = useQuery({
queryKey: ['pinned-live-blogs'], queryKey: ['pinned-live-blogs'],

View File

@ -32,6 +32,7 @@ export function Header() {
{ to: '/science', label: 'Наука' }, { to: '/science', label: 'Наука' },
{ to: '/archive', label: 'Архива' }, { to: '/archive', label: 'Архива' },
{ to: '/live-blogs', label: 'LIVE' }, { to: '/live-blogs', label: 'LIVE' },
{ to: '/about', label: 'Упатство за употреба' },
]; ];
const adminLinks = [ const adminLinks = [

View File

@ -0,0 +1,121 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { AlertTriangle, Laugh, Coffee } from 'lucide-react';
export function AboutComponent() {
return (
<div className="py-8 max-w-4xl mx-auto">
<div className="mb-12 text-center">
<h1 className="text-4xl md:text-6xl font-display mb-4">
Упатство за употреба
</h1>
<p className="text-xl text-muted-foreground font-body">
Сè што треба да знаете за Placebo.mk
</p>
</div>
<div className="space-y-6">
<Card className="border-brutal-sm">
<CardHeader>
<div className="flex items-center gap-3">
<AlertTriangle className="w-8 h-8 text-accent" />
<CardTitle className="text-2xl font-display">Предупредување</CardTitle>
</div>
</CardHeader>
<CardContent className="space-y-4 font-body">
<p className="text-lg">
<strong>Placebo.mk</strong> е сатиричен портал за вести. Сè што читате овде е измислено, преувеличено или целосно извадено од контекст.
</p>
<p>
Ако веќе се налутивте, не се грижете - тоа е замислено. Ако сте се насмеале, уште подобро! Ако барате вистински новинарски содржини, продолжете кон следната веб-страна.
</p>
</CardContent>
</Card>
<Card className="border-brutal-sm">
<CardHeader>
<div className="flex items-center gap-3">
<Laugh className="w-8 h-8 text-accent" />
<CardTitle className="text-2xl font-display">Што е Placebo.mk?</CardTitle>
</div>
</CardHeader>
<CardContent className="space-y-4 font-body">
<p>
Сме портал кој го преработува реалноста и ја претвора во апсурд. Македонските политика, култура и спорт се сервираат со добра доза сарказам и црен хумор.
</p>
<p>
Нашата мисија е едноставна: да ве насмееме, да ве натераме да размислите и да ве потсетиме дека понекогаш вистината е толку apsурдна што единствено може да се коментира со хумор.
</p>
</CardContent>
</Card>
<Card className="border-brutal-sm">
<CardHeader>
<CardTitle className="text-2xl font-display">Правила за читање</CardTitle>
</CardHeader>
<CardContent className="font-body">
<ol className="list-decimal list-inside space-y-3">
<li>Не земајте ништо од ова сериозно (освен кафето што ќе ни го купите).</li>
<li>Ако не ви е смешно - не е за вас. Најдете друга страна.</li>
<li>Не споделувајте наши написи како вистински вести. Луѓето веќе се збунети доволно.</li>
<li>Смеата е најдобар лек. Користете ја дневно.</li>
<li>Ако ви се допаѓа, споделете. Ако не ви се допаѓа, сепак споделете. Гледаме статистики.</li>
</ol>
</CardContent>
</Card>
<Card className="border-brutal-sm">
<CardHeader>
<CardTitle className="text-2xl font-display">Категории</CardTitle>
</CardHeader>
<CardContent className="font-body">
<ul className="space-y-3">
<li>
<strong>Општо:</strong> Општи вести и теми кои не паѓаат во другите категории
</li>
<li>
<strong>Спорт:</strong> Спортски новости, победи, порази и сè помеѓу (најчесто порази)
</li>
<li>
<strong>Уметност:</strong> Култура, музика, филм и претставување дека разбираме од уметност
</li>
<li>
<strong>Наука:</strong> Научни откритија објаснети на начин што ќе разбере и вашата баба
</li>
<li>
<strong>LIVE Блогови:</strong> Покривање во реално време на настани што го заслужуваат нашето внимание
</li>
</ul>
</CardContent>
</Card>
<Card className="border-brutal-sm bg-accent/5">
<CardHeader>
<div className="flex items-center gap-3">
<Coffee className="w-8 h-8 text-accent" />
<CardTitle className="text-2xl font-display">Поддржете не</CardTitle>
</div>
</CardHeader>
<CardContent className="space-y-4 font-body">
<p>
Сатирата не се пишува сама (иако понекогаш реалноста е поапсурдна од фикцијата).
Ако ви се допаѓа она што го правиме, размислете да ни купите кафе. Или две. Или три.
</p>
<p className="text-sm text-muted-foreground">
* Сите донации одат за кафе, инспирација и плаќање на серверите. Не нудиме фискални сметки.
</p>
</CardContent>
</Card>
<div className="mt-12 p-8 border-4 border-foreground bg-foreground text-background text-center">
<p className="text-2xl font-display mb-4">
Запомнете:
</p>
<p className="text-lg font-body">
Ако не можете да препознаете сатира од вистина,<br />
проблемот не е во нас. Проблемот е во реалноста.
</p>
</div>
</div>
</div>
);
}

View File

@ -11,6 +11,7 @@ import { AuthPage } from './components/routes/AuthPage'
import { SportComponent } from './components/routes/SportComponent' import { SportComponent } from './components/routes/SportComponent'
import { ArtComponent } from './components/routes/ArtComponent' import { ArtComponent } from './components/routes/ArtComponent'
import { ScienceComponent } from './components/routes/ScienceComponent' import { ScienceComponent } from './components/routes/ScienceComponent'
import { AboutComponent } from './components/routes/AboutComponent'
import { ProtectedRoute } from './components/auth/ProtectedRoute' import { ProtectedRoute } from './components/auth/ProtectedRoute'
import { Header } from './components/layout/Header' import { Header } from './components/layout/Header'
import { HeroArticle } from './components/home/HeroArticle' import { HeroArticle } from './components/home/HeroArticle'
@ -181,6 +182,12 @@ const scienceRoute = createRoute({
component: ScienceComponent, component: ScienceComponent,
}) })
const aboutRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/about',
component: AboutComponent,
})
const articleDetailRoute = createRoute({ const articleDetailRoute = createRoute({
getParentRoute: () => rootRoute, getParentRoute: () => rootRoute,
path: '/articles/$id', path: '/articles/$id',
@ -308,6 +315,7 @@ const routeTree = rootRoute.addChildren([
sportRoute, sportRoute,
artRoute, artRoute,
scienceRoute, scienceRoute,
aboutRoute,
articleDetailRoute, articleDetailRoute,
liveBlogsRoute, liveBlogsRoute,
liveBlogDetailRoute, liveBlogDetailRoute,