build: fce83541-8c54-465f-a1fc-71388f99db57
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
IonPage,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonToolbar,
|
||||
IonButtons,
|
||||
IonButton,
|
||||
IonIcon,
|
||||
IonSpinner,
|
||||
useIonViewWillEnter,
|
||||
} from '@ionic/react';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import { supabase } from '../supabase';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { NewsItem } from '../types';
|
||||
import { chevronBackOutline, createOutline } from 'ionicons/icons';
|
||||
|
||||
const NewsDetail: React.FC = () => {
|
||||
const history = useHistory();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const { profile } = useAuth();
|
||||
const [news, setNews] = useState<NewsItem | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useIonViewWillEnter(() => {
|
||||
fetchNewsItem();
|
||||
});
|
||||
|
||||
const fetchNewsItem = async () => {
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from('news')
|
||||
.select('*')
|
||||
.eq('id', id)
|
||||
.single();
|
||||
if (error) throw error;
|
||||
setNews(data);
|
||||
} catch (err) {
|
||||
console.error('Error fetching news:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<IonPage>
|
||||
<IonHeader className="ion-no-border">
|
||||
<IonToolbar style={{ '--background': '#f5f7f4' }}>
|
||||
<IonButtons slot="start">
|
||||
<IonButton onClick={() => history.goBack()}>
|
||||
<IonIcon icon={chevronBackOutline} slot="icon-only" />
|
||||
</IonButton>
|
||||
</IonButtons>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent style={{ '--background': '#f5f7f4' }}>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
marginTop: '40px',
|
||||
}}
|
||||
>
|
||||
<IonSpinner name="crescent" />
|
||||
</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
}
|
||||
|
||||
if (!news) {
|
||||
return (
|
||||
<IonPage>
|
||||
<IonHeader className="ion-no-border">
|
||||
<IonToolbar style={{ '--background': '#f5f7f4' }}>
|
||||
<IonButtons slot="start">
|
||||
<IonButton onClick={() => history.goBack()}>
|
||||
<IonIcon icon={chevronBackOutline} slot="icon-only" />
|
||||
</IonButton>
|
||||
</IonButtons>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
<IonContent style={{ '--background': '#f5f7f4' }}>
|
||||
<div
|
||||
style={{ textAlign: 'center', marginTop: '60px', color: '#6b7280' }}
|
||||
>
|
||||
News item not found.
|
||||
</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<IonPage>
|
||||
<IonHeader className="ion-no-border">
|
||||
<IonToolbar style={{ '--background': '#f5f7f4' }}>
|
||||
<IonButtons slot="start">
|
||||
<IonButton onClick={() => history.goBack()}>
|
||||
<IonIcon icon={chevronBackOutline} slot="icon-only" />
|
||||
</IonButton>
|
||||
</IonButtons>
|
||||
{profile?.role === 'admin' && (
|
||||
<IonButtons slot="end">
|
||||
<IonButton onClick={() => history.push(`/admin/news/${news.id}`)}>
|
||||
<IonIcon
|
||||
icon={createOutline}
|
||||
slot="icon-only"
|
||||
style={{ color: '#2f6b4f' }}
|
||||
/>
|
||||
</IonButton>
|
||||
</IonButtons>
|
||||
)}
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonContent style={{ '--background': '#f5f7f4' }}>
|
||||
<div
|
||||
style={{
|
||||
padding: '0 20px 40px',
|
||||
maxWidth: '600px',
|
||||
margin: '0 auto',
|
||||
}}
|
||||
>
|
||||
{news.image_url && (
|
||||
<div style={{ marginBottom: '24px' }}>
|
||||
<img
|
||||
src={news.image_url}
|
||||
alt=""
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '240px',
|
||||
objectFit: 'cover',
|
||||
borderRadius: '24px',
|
||||
background: '#eef2ec',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
style={{
|
||||
fontSize: '14px',
|
||||
fontWeight: '600',
|
||||
color: '#2f6b4f',
|
||||
marginBottom: '12px',
|
||||
}}
|
||||
>
|
||||
{new Date(news.created_at).toLocaleDateString(undefined, {
|
||||
weekday: 'long',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
})}
|
||||
</div>
|
||||
|
||||
<h1
|
||||
style={{
|
||||
margin: '0 0 24px',
|
||||
fontSize: '28px',
|
||||
fontWeight: '800',
|
||||
color: '#1f2937',
|
||||
lineHeight: '1.2',
|
||||
}}
|
||||
>
|
||||
{news.title}
|
||||
</h1>
|
||||
|
||||
<div
|
||||
style={{
|
||||
fontSize: '16px',
|
||||
color: '#4b5563',
|
||||
lineHeight: '1.6',
|
||||
whiteSpace: 'pre-wrap',
|
||||
}}
|
||||
>
|
||||
{news.content}
|
||||
</div>
|
||||
</div>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewsDetail;
|
||||
Reference in New Issue
Block a user