forked from UKSOURCE/hailearning.edu.vn
Initial commit
This commit is contained in:
93
app/blog/blog.json
Normal file
93
app/blog/blog.json
Normal file
@@ -0,0 +1,93 @@
|
||||
{
|
||||
"title": "Blog & Tin Tức",
|
||||
"subtitle": "Cập nhật thông tin mới nhất về visa và du lịch",
|
||||
"featured": {
|
||||
"id": "visa-schengen-2024",
|
||||
"title": "Hướng Dẫn Xin Visa Schengen 2024 - Cập Nhật Mới Nhất",
|
||||
"excerpt": "Thủ tục xin visa Schengen đã có những thay đổi quan trọng trong năm 2024. Cùng tìm hiểu chi tiết...",
|
||||
"image": "/images/schengen-visa.jpg",
|
||||
"date": "2024-01-15",
|
||||
"author": "Nguyễn Văn A",
|
||||
"category": "Visa",
|
||||
"readTime": "5 phút đọc"
|
||||
},
|
||||
"categories": [
|
||||
{
|
||||
"name": "Tất cả",
|
||||
"slug": "all",
|
||||
"count": 24
|
||||
},
|
||||
{
|
||||
"name": "Visa",
|
||||
"slug": "visa",
|
||||
"count": 12
|
||||
},
|
||||
{
|
||||
"name": "Du lịch",
|
||||
"slug": "travel",
|
||||
"count": 8
|
||||
},
|
||||
{
|
||||
"name": "Thủ tục",
|
||||
"slug": "procedures",
|
||||
"count": 4
|
||||
}
|
||||
],
|
||||
"posts": [
|
||||
{
|
||||
"id": "visa-my-2024",
|
||||
"title": "Thay Đổi Mới Trong Thủ Tục Xin Visa Mỹ 2024",
|
||||
"excerpt": "Lãnh sự quán Mỹ đã công bố những thay đổi quan trọng trong quy trình xin visa...",
|
||||
"image": "/images/us-visa.jpg",
|
||||
"date": "2024-01-10",
|
||||
"author": "Trần Thị B",
|
||||
"category": "Visa",
|
||||
"readTime": "7 phút đọc",
|
||||
"tags": ["Visa Mỹ", "Thủ tục", "2024"]
|
||||
},
|
||||
{
|
||||
"id": "du-lich-nhat-ban",
|
||||
"title": "Top 10 Địa Điểm Du Lịch Nhật Bản Không Thể Bỏ Qua",
|
||||
"excerpt": "Khám phá những điểm đến tuyệt vời nhất tại đất nước mặt trời mọc...",
|
||||
"image": "/images/japan-travel.jpg",
|
||||
"date": "2024-01-08",
|
||||
"author": "Lê Văn C",
|
||||
"category": "Du lịch",
|
||||
"readTime": "6 phút đọc",
|
||||
"tags": ["Nhật Bản", "Du lịch", "Điểm đến"]
|
||||
},
|
||||
{
|
||||
"id": "visa-han-quoc-tips",
|
||||
"title": "Bí Quyết Xin Visa Hàn Quốc Thành Công 100%",
|
||||
"excerpt": "Những kinh nghiệm quý báu từ chuyên gia để tăng tỷ lệ thành công...",
|
||||
"image": "/images/korea-visa.jpg",
|
||||
"date": "2024-01-05",
|
||||
"author": "Phạm Thị D",
|
||||
"category": "Visa",
|
||||
"readTime": "8 phút đọc",
|
||||
"tags": ["Visa Hàn Quốc", "Kinh nghiệm", "Thành công"]
|
||||
},
|
||||
{
|
||||
"id": "du-lich-chau-au",
|
||||
"title": "Lịch Trình Du Lịch Châu Âu 14 Ngày Hoàn Hảo",
|
||||
"excerpt": "Khám phá 7 quốc gia châu Âu với lịch trình được thiết kế tối ưu...",
|
||||
"image": "/images/europe-travel.jpg",
|
||||
"date": "2024-01-03",
|
||||
"author": "Hoàng Văn E",
|
||||
"category": "Du lịch",
|
||||
"readTime": "10 phút đọc",
|
||||
"tags": ["Châu Âu", "Lịch trình", "14 ngày"]
|
||||
},
|
||||
{
|
||||
"id": "thu-tuc-ho-so",
|
||||
"title": "Checklist Hồ Sơ Xin Visa - Không Bỏ Sót Gì",
|
||||
"excerpt": "Danh sách chi tiết các giấy tờ cần thiết cho từng loại visa...",
|
||||
"image": "/images/documents.jpg",
|
||||
"date": "2024-01-01",
|
||||
"author": "Vũ Thị F",
|
||||
"category": "Thủ tục",
|
||||
"readTime": "4 phút đọc",
|
||||
"tags": ["Hồ sơ", "Checklist", "Visa"]
|
||||
}
|
||||
]
|
||||
}
|
||||
144
app/blog/page.tsx
Normal file
144
app/blog/page.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import blogData from "./blog.json";
|
||||
|
||||
export default function BlogPage() {
|
||||
const [selectedCategory, setSelectedCategory] = useState("all");
|
||||
|
||||
const filteredPosts =
|
||||
selectedCategory === "all"
|
||||
? blogData.posts
|
||||
: blogData.posts.filter(
|
||||
(post) => post.category.toLowerCase() === selectedCategory,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="container mx-auto px-4 py-8">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="text-center mb-12">
|
||||
<h1 className="text-4xl font-bold text-gray-900 mb-4">
|
||||
{blogData.title}
|
||||
</h1>
|
||||
<p className="text-xl text-gray-600">{blogData.subtitle}</p>
|
||||
</div>
|
||||
|
||||
{/* Featured Post */}
|
||||
<div className="mb-12">
|
||||
<div className="bg-gradient-to-r from-blue-600 to-purple-600 rounded-lg p-8 text-white">
|
||||
<div className="flex items-center mb-4">
|
||||
<span className="bg-yellow-400 text-black px-3 py-1 rounded-full text-sm font-medium mr-4">
|
||||
Nổi bật
|
||||
</span>
|
||||
<span className="text-blue-100">
|
||||
{blogData.featured.category}
|
||||
</span>
|
||||
</div>
|
||||
<h2 className="text-3xl font-bold mb-4">
|
||||
{blogData.featured.title}
|
||||
</h2>
|
||||
<p className="text-blue-100 mb-6 text-lg">
|
||||
{blogData.featured.excerpt}
|
||||
</p>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center text-blue-100">
|
||||
<span className="mr-4">👤 {blogData.featured.author}</span>
|
||||
<span className="mr-4">📅 {blogData.featured.date}</span>
|
||||
<span>⏱️ {blogData.featured.readTime}</span>
|
||||
</div>
|
||||
<button className="bg-white text-blue-600 px-6 py-2 rounded-lg hover:bg-blue-50 transition-colors">
|
||||
Đọc thêm
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Category Filter */}
|
||||
<div className="mb-8">
|
||||
<div className="flex flex-wrap gap-4 justify-center">
|
||||
{blogData.categories.map((category) => (
|
||||
<button
|
||||
key={category.slug}
|
||||
onClick={() => setSelectedCategory(category.slug)}
|
||||
className={`px-6 py-2 rounded-full transition-colors ${
|
||||
selectedCategory === category.slug
|
||||
? "bg-blue-600 text-white"
|
||||
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
||||
}`}
|
||||
>
|
||||
{category.name} ({category.count})
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Blog Posts Grid */}
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{filteredPosts.map((post) => (
|
||||
<article
|
||||
key={post.id}
|
||||
className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow"
|
||||
>
|
||||
{/* Post Image */}
|
||||
<div className="h-48 bg-gray-200 flex items-center justify-center">
|
||||
<span className="text-gray-400">📷 {post.category}</span>
|
||||
</div>
|
||||
|
||||
{/* Post Content */}
|
||||
<div className="p-6">
|
||||
{/* Category & Date */}
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<span className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-sm">
|
||||
{post.category}
|
||||
</span>
|
||||
<span className="text-gray-500 text-sm">{post.date}</span>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<h3 className="text-xl font-semibold text-gray-900 mb-3 line-clamp-2">
|
||||
{post.title}
|
||||
</h3>
|
||||
|
||||
{/* Excerpt */}
|
||||
<p className="text-gray-700 mb-4 line-clamp-3">
|
||||
{post.excerpt}
|
||||
</p>
|
||||
|
||||
{/* Tags */}
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
{post.tags.map((tag, index) => (
|
||||
<span
|
||||
key={index}
|
||||
className="bg-gray-100 text-gray-600 px-2 py-1 rounded text-xs"
|
||||
>
|
||||
#{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Meta Info */}
|
||||
<div className="flex items-center justify-between text-sm text-gray-500">
|
||||
<span>👤 {post.author}</span>
|
||||
<span>⏱️ {post.readTime}</span>
|
||||
</div>
|
||||
|
||||
{/* Read More Button */}
|
||||
<button className="w-full mt-4 bg-blue-600 text-white py-2 px-4 rounded-lg hover:bg-blue-700 transition-colors">
|
||||
Đọc thêm
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Load More */}
|
||||
<div className="text-center mt-12">
|
||||
<button className="bg-gray-100 text-gray-700 px-8 py-3 rounded-lg hover:bg-gray-200 transition-colors">
|
||||
Xem thêm bài viết
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user