feat: Add news detail page with view increment and media loading

This commit is contained in:
Yoga Pangestu 2026-01-02 23:02:30 +07:00
parent 5ae26b7036
commit 0dcb798894
4 changed files with 96 additions and 0 deletions

View File

@ -67,4 +67,17 @@ public function index(Request $request)
'filters' => request()->only(['search', 'category']),
]);
}
public function show(News $news)
{
$news->load(['author', 'categories', 'tags']);
$news->increment('views');
$news->thumbnail = $news->getFirstMediaUrl('news');
return Inertia::render('home/news/pages/Show', [
'pageTitle' => 'Detail Berita',
'pageDescription' => $news->title,
'news' => $news,
]);
}
}

View File

@ -210,6 +210,7 @@ export default function MainContent({ pageTitle, pageDescription, categories, ne
onBlur={handleBlur}
tabIndex={0}
className={focusedCardIndex === news.id ? 'Mui-focused' : ''}
onClick={() => router.get(`/news/${news.slug}`)}
>
<CardMedia
component="img"

View File

@ -0,0 +1,81 @@
import CssBaseline from '@mui/material/CssBaseline';
import Container from '@mui/material/Container';
import AppTheme from '../../../theme/AppTheme';
import Navbar from '../../components/Navbar';
import Footer from '../../components/Footer';
import { Box, CardMedia, Chip, styled, Typography } from '@mui/material';
import Headline from '../../components/Headline';
export default function NewsShowPage(props) {
const news = props.news;
console.log(news.tags, news.categories)
return (
<AppTheme {...props}>
<CssBaseline enableColorScheme />
<Navbar />
<Container
maxWidth="lg"
component="main"
sx={{ display: 'flex', flexDirection: 'column', my: 16, gap: 4 }}
>
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
<div>
<Headline pageTitle={props.pageTitle} pageDescription={props.pageDescription} />
</div>
<Box
sx={{
display: 'flex',
flexDirection: { xs: 'column-reverse', md: 'row' },
width: '100%',
justifyContent: 'space-between',
alignItems: { xs: 'start', md: 'center' },
gap: 4,
overflow: 'auto',
}}
>
</Box>
<CardMedia
component="img"
alt={news.title}
image={news.thumbnail}
sx={{
aspectRatio: '16 / 9',
borderBottom: '1px solid',
borderColor: 'divider',
borderRadius: 1,
}}
/>
<Typography gutterBottom variant="caption" component="div">
{news.categories.map((category, index) =>
<Chip label={category.name} color="success" variant="outlined" sx={{ mr: 1 }} key={index} />
)}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{news.title}
</Typography>
<Typography
variant="body2"
color="text.secondary"
gutterBottom
dangerouslySetInnerHTML={{ __html: news.content }}
/>
{news.tags && news.tags.length > 0 && (
<Typography gutterBottom variant="caption" component="div">
{news.tags.map((tag, index) =>
<Chip label={tag.name} color="success" variant="outlined" sx={{ mr: 1 }} key={index} />
)}
</Typography>
)}
</Box>
</Container>
<Footer />
</AppTheme>
);
}

View File

@ -6,3 +6,4 @@
Route::get('/', [HomepageController::class, 'index'])->name('homepage');
Route::get('/news', [NewsController::class, 'index'])->name('news.index');
Route::get('/news/{news:slug}', [NewsController::class, 'show'])->name('news.show');