forked from UKSOURCE/hailearning.edu.vn
feat: create Partnership and Blog functional components
This commit is contained in:
176
app/blog/blog-page.css
Normal file
176
app/blog/blog-page.css
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
/* ============================================
|
||||||
|
Blog Page — Scoped Styles
|
||||||
|
Scope: .blog-page
|
||||||
|
============================================ */
|
||||||
|
|
||||||
|
/* Reset heading override từ main.css */
|
||||||
|
.blog-page h1,
|
||||||
|
.blog-page h2,
|
||||||
|
.blog-page h3,
|
||||||
|
.blog-page h4 {
|
||||||
|
font-size: unset;
|
||||||
|
font-weight: unset;
|
||||||
|
line-height: unset;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Typography classes thay thế h1/h2/h3 */
|
||||||
|
.blog-page .blog-heading {
|
||||||
|
font-size: clamp(1.75rem, 4vw, 3rem);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .blog-card-title {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .blog-widget-title {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------- Color tokens ---------- */
|
||||||
|
|
||||||
|
.blog-page .bg-brand-blue { background-color: rgb(38, 60, 111); }
|
||||||
|
.blog-page .text-brand-blue { color: rgb(38, 60, 111); }
|
||||||
|
.blog-page .border-brand-blue { border-color: rgb(38, 60, 111); }
|
||||||
|
|
||||||
|
.blog-page .bg-brand-light { background-color: #f8fbff; }
|
||||||
|
.blog-page .text-brand-light { color: #f8fbff; }
|
||||||
|
|
||||||
|
.blog-page .bg-brand-hover { background-color: #2d3a8c; }
|
||||||
|
.blog-page .hover\:bg-brand-hover:hover { background-color: #2d3a8c; }
|
||||||
|
|
||||||
|
.blog-page .text-ui-text { color: #111827; }
|
||||||
|
.blog-page .text-ui-muted { color: #6b7280; }
|
||||||
|
.blog-page .bg-ui-bg { background-color: #f9fafb; }
|
||||||
|
.blog-page .border-ui-border { border-color: #e5e7eb; }
|
||||||
|
|
||||||
|
/* hover:text-brand-blue */
|
||||||
|
.blog-page .hover\:text-brand-blue:hover { color: #1b254b; }
|
||||||
|
.blog-page .hover\:border-brand-blue:hover { border-color: #1b254b; }
|
||||||
|
|
||||||
|
/* group-hover */
|
||||||
|
.blog-page .group:hover .group-hover\:text-brand-blue { color: #1b254b; }
|
||||||
|
.blog-page .group:hover .group-hover\:border-brand-blue { border-color: #1b254b; }
|
||||||
|
.blog-page .group:hover .group-hover\:gap-2 { gap: 0.5rem; }
|
||||||
|
.blog-page .group:hover .group-hover\:scale-105 { transform: scale(1.05); }
|
||||||
|
|
||||||
|
/* shadow tokens */
|
||||||
|
.blog-page .shadow-soft {
|
||||||
|
box-shadow: 0 1px 3px rgb(0 0 0 / 0.06), 0 1px 2px rgb(0 0 0 / 0.04);
|
||||||
|
}
|
||||||
|
.blog-page .shadow-hover {
|
||||||
|
box-shadow: 0 4px 12px rgb(0 0 0 / 0.1);
|
||||||
|
}
|
||||||
|
.blog-page .hover\:shadow-hover:hover {
|
||||||
|
box-shadow: 0 4px 12px rgb(0 0 0 / 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* border-brand-blue/20, border-brand-blue/50 */
|
||||||
|
.blog-page .border-brand-blue\/20 { border-color: rgb(27 37 75 / 0.2); }
|
||||||
|
.blog-page .border-brand-blue\/50 { border-color: rgb(27 37 75 / 0.5); }
|
||||||
|
.blog-page .hover\:border-brand-blue\/50:hover { border-color: rgb(27 37 75 / 0.5); }
|
||||||
|
|
||||||
|
/* text-brand-blue/40 */
|
||||||
|
.blog-page .text-brand-blue\/40 { color: rgb(27 37 75 / 0.4); }
|
||||||
|
|
||||||
|
/* text-brand-light/80, /60 */
|
||||||
|
.blog-page .text-brand-light\/80 { color: rgb(248 251 255 / 0.8); }
|
||||||
|
.blog-page .text-brand-light\/60 { color: rgb(248 251 255 / 0.6); }
|
||||||
|
|
||||||
|
/* bg-white/10, /90 */
|
||||||
|
.blog-page .bg-white\/10 { background-color: rgb(255 255 255 / 0.1); }
|
||||||
|
.blog-page .bg-white\/90 { background-color: rgb(255 255 255 / 0.9); }
|
||||||
|
|
||||||
|
/* border-white/20 */
|
||||||
|
.blog-page .border-white\/20 { border-color: rgb(255 255 255 / 0.2); }
|
||||||
|
|
||||||
|
/* placeholder */
|
||||||
|
.blog-page .placeholder-white\/50::placeholder { color: rgb(255 255 255 / 0.5); }
|
||||||
|
|
||||||
|
/* Category filter buttons */
|
||||||
|
.blog-page #category-filters button {
|
||||||
|
padding-left: 1.25rem !important;
|
||||||
|
padding-right: 1.25rem !important;
|
||||||
|
padding-top: 0.4rem !important;
|
||||||
|
padding-bottom: 0.4rem !important;
|
||||||
|
border-radius: 9999px !important;
|
||||||
|
font-size: 0.8rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Category filter hover — viền sáng lên */
|
||||||
|
.blog-page #category-filters button:not(:first-child):hover {
|
||||||
|
border-color: #1b254b !important;
|
||||||
|
color: #1b254b !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Newsletter input placeholder */
|
||||||
|
.blog-page .newsletter-input::placeholder {
|
||||||
|
color: rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Newsletter widget */
|
||||||
|
.blog-page .folder-tab {
|
||||||
|
background-color: #263c6f !important;
|
||||||
|
clip-path: polygon(0 0, calc(100% - 40px) 0, 100% 40px, 100% 100%, 0 100%);
|
||||||
|
border-radius: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .folder-tab input {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 0.35rem 0.75rem !important;
|
||||||
|
font-size: 0.875rem !important;
|
||||||
|
background-color: rgba(255,255,255,0.12) !important;
|
||||||
|
border: 1px solid rgba(255,255,255,0.25) !important;
|
||||||
|
color: white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .folder-tab input::placeholder {
|
||||||
|
color: rgba(255,255,255,0.5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .folder-tab button[type="submit"] {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
padding: 0.35rem 0.75rem !important;
|
||||||
|
font-size: 0.875rem !important;
|
||||||
|
font-weight: 700 !important;
|
||||||
|
background-color: white !important;
|
||||||
|
color: #1b254b !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pagination buttons */
|
||||||
|
.blog-page .border-ui-border[class*="w-10"] {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .border-ui-border[class*="w-10"]:hover {
|
||||||
|
border-color: rgb(38, 60, 111) !important;
|
||||||
|
color: rgb(38, 60, 111) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .bg-brand-blue[class*="w-10"] {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
background-color: rgb(38, 60, 111) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pagination */
|
||||||
|
.blog-page .pg-btn {
|
||||||
|
border-radius: 8px !important;
|
||||||
|
transition: border-color 0.2s, color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .pg-btn:hover {
|
||||||
|
border-color: rgb(38, 60, 111) !important;
|
||||||
|
color: rgb(38, 60, 111) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blog-page .pg-active {
|
||||||
|
background-color: rgb(38, 60, 111) !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import "./blog-page.css";
|
||||||
|
import FeaturedHero from "../components/blog/FeaturedHero";
|
||||||
|
import CategoryFilters from "../components/blog/CategoryFilters";
|
||||||
|
import NewsGrid from "../components/blog/NewsGrid";
|
||||||
|
import BlogSidebar from "../components/blog/BlogSidebar";
|
||||||
|
|
||||||
|
export default function BlogPage() {
|
||||||
|
return (
|
||||||
|
<main className="blog-page w-full min-h-screen bg-ui-bg pb-20">
|
||||||
|
<FeaturedHero />
|
||||||
|
|
||||||
|
<div className="max-w-[1440px] mx-auto px-6 lg:px-8">
|
||||||
|
<div className="flex flex-col lg:flex-row gap-12">
|
||||||
|
{/* Left: filters + news grid */}
|
||||||
|
<div className="flex-1">
|
||||||
|
<CategoryFilters />
|
||||||
|
<NewsGrid />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right: sidebar */}
|
||||||
|
<BlogSidebar />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
13
app/components/blog/BlogSidebar.tsx
Normal file
13
app/components/blog/BlogSidebar.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import NewsletterWidget from "./NewsletterWidget";
|
||||||
|
import ResearcherSpotlight from "./ResearcherSpotlight";
|
||||||
|
import UpcomingEvents from "./UpcomingEvents";
|
||||||
|
|
||||||
|
export default function BlogSidebar() {
|
||||||
|
return (
|
||||||
|
<aside className="w-full lg:w-[400px] shrink-0 space-y-8">
|
||||||
|
<NewsletterWidget />
|
||||||
|
<ResearcherSpotlight />
|
||||||
|
<UpcomingEvents />
|
||||||
|
</aside>
|
||||||
|
);
|
||||||
|
}
|
||||||
21
app/components/blog/CategoryFilters.tsx
Normal file
21
app/components/blog/CategoryFilters.tsx
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
const categories = ["All News", "Campus", "Research", "Partnerships", "Events"];
|
||||||
|
|
||||||
|
export default function CategoryFilters() {
|
||||||
|
return (
|
||||||
|
<div id="category-filters" className="flex flex-wrap items-center gap-3 mb-10 pb-6 border-b border-ui-border">
|
||||||
|
{categories.map((cat, i) => (
|
||||||
|
<button
|
||||||
|
key={cat}
|
||||||
|
style={{ borderRadius: "9999px", fontSize: "0.8rem" }}
|
||||||
|
className={
|
||||||
|
i === 0
|
||||||
|
? "px-6 py-2 bg-brand-blue text-white text-sm font-semibold shadow-sm transition-colors"
|
||||||
|
: "px-6 py-2 bg-white border border-ui-border text-ui-text hover:border-brand-blue hover:text-brand-blue text-sm font-medium transition-colors"
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{cat}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
44
app/components/blog/FeaturedHero.tsx
Normal file
44
app/components/blog/FeaturedHero.tsx
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
export default function FeaturedHero() {
|
||||||
|
return (
|
||||||
|
<section id="featured-hero" className="w-full bg-white border-b border-ui-border mb-12">
|
||||||
|
<div className="max-w-[1440px] mx-auto">
|
||||||
|
<div className="flex flex-col lg:flex-row min-h-[500px]">
|
||||||
|
{/* Left: Content */}
|
||||||
|
<div className="w-full lg:w-1/2 p-8 lg:p-16 flex flex-col justify-center">
|
||||||
|
<span className="inline-block px-3 py-1 bg-brand-light text-brand-blue border border-brand-blue/20 text-xs font-semibold mb-4 w-fit" style={{ borderRadius: "6px" }}>
|
||||||
|
Featured Research
|
||||||
|
</span>
|
||||||
|
<div className="blog-heading text-ui-text tracking-tight mb-6 leading-tight font-bold">
|
||||||
|
Pioneering Sustainable Urban Development in the Heart of Paris
|
||||||
|
</div>
|
||||||
|
<p className="text-lg text-ui-muted mb-8 leading-relaxed">
|
||||||
|
Our latest collaborative research initiative uncovers groundbreaking methods for integrating green infrastructure into historic urban environments, setting a new standard for European cities.
|
||||||
|
</p>
|
||||||
|
<div className="flex items-center gap-4 text-sm text-ui-muted mb-8 mt-4">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<img src="https://storage.googleapis.com/uxpilot-auth.appspot.com/avatars/avatar-1.jpg" alt="Author" className="w-8 h-8 rounded-full border border-ui-border" />
|
||||||
|
<span className="font-medium text-ui-text">Dr. Amélie Dubois</span>
|
||||||
|
</div>
|
||||||
|
<span>•</span>
|
||||||
|
<span>October 15, 2024</span>
|
||||||
|
<span>•</span>
|
||||||
|
<span>5 min read</span>
|
||||||
|
</div>
|
||||||
|
<a href="#" className="inline-flex items-center justify-center px-5 py-3 text-white font-semibold text-sm hover:bg-brand-hover transition-colors shadow-sm w-fit gap-2" style={{ borderRadius: "5px", backgroundColor: "rgb(38, 60, 111)" }}>
|
||||||
|
Read Full Story <i className="fas fa-arrow-right text-xs"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right: Image */}
|
||||||
|
<div className="w-full lg:w-1/2 bg-gray-100 relative min-h-[300px] lg:min-h-full">
|
||||||
|
<img
|
||||||
|
className="absolute inset-0 w-full h-full object-cover"
|
||||||
|
src="https://storage.googleapis.com/uxpilot-auth.appspot.com/75c7c284e8-18119bca345a35938b88.png"
|
||||||
|
alt="Aerial view of Paris with sustainable green roofs and modern eco-friendly architecture blending with historic buildings"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
48
app/components/blog/NewsCard.tsx
Normal file
48
app/components/blog/NewsCard.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
type NewsCardProps = {
|
||||||
|
category: string;
|
||||||
|
date: string;
|
||||||
|
title: string;
|
||||||
|
excerpt: string;
|
||||||
|
image?: string;
|
||||||
|
icon?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function NewsCard({ category, date, title, excerpt, image, icon }: NewsCardProps) {
|
||||||
|
return (
|
||||||
|
<article className="bg-white rounded-xl border border-ui-border overflow-hidden shadow-soft hover:shadow-hover hover:border-brand-blue/50 transition-all group flex flex-col">
|
||||||
|
{/* Thumbnail */}
|
||||||
|
<div className="h-48 overflow-hidden relative">
|
||||||
|
{image ? (
|
||||||
|
<img
|
||||||
|
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
||||||
|
src={image}
|
||||||
|
alt={title}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className="w-full h-full bg-brand-light flex items-center justify-center">
|
||||||
|
<i className={`${icon} text-4xl text-brand-blue/40`}></i>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="absolute top-4 left-4">
|
||||||
|
<span className="px-3 py-1 bg-white/90 backdrop-blur-sm text-brand-blue rounded-md text-xs font-bold shadow-sm">
|
||||||
|
{category}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Content */}
|
||||||
|
<div className="p-6 flex flex-col flex-1">
|
||||||
|
<div className="text-xs text-ui-muted mb-3 flex items-center gap-2">
|
||||||
|
<i className="far fa-calendar"></i> {date}
|
||||||
|
</div>
|
||||||
|
<div className="blog-card-title text-ui-text group-hover:text-brand-blue transition-colors mb-3 leading-tight font-bold">
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-ui-muted mb-6 flex-1 line-clamp-3">{excerpt}</p>
|
||||||
|
<a href="#" className="text-sm font-bold text-brand-blue flex items-center gap-1 group-hover:gap-2 transition-all pt-4">
|
||||||
|
Read more <i className="fas fa-arrow-right text-xs"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
||||||
59
app/components/blog/NewsGrid.tsx
Normal file
59
app/components/blog/NewsGrid.tsx
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import NewsCard from "./NewsCard";
|
||||||
|
|
||||||
|
const news = [
|
||||||
|
{
|
||||||
|
category: "Campus",
|
||||||
|
date: "Oct 12, 2024",
|
||||||
|
title: "New Liberal Arts Library Wing Opens to Students",
|
||||||
|
excerpt: "The state-of-the-art facility provides expanded collaborative spaces and access to over 50,000 new digital and print resources for our growing student body.",
|
||||||
|
image: "https://storage.googleapis.com/uxpilot-auth.appspot.com/8eafd095d9-314bdad36b2119266084.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Partnerships",
|
||||||
|
date: "Oct 10, 2024",
|
||||||
|
title: "ULP Announces Strategic Alliance with TechGlobal Institute",
|
||||||
|
excerpt: "A new partnership aimed at bridging the gap between liberal arts education and emerging technological paradigms in the 21st century.",
|
||||||
|
icon: "fas fa-handshake",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Events",
|
||||||
|
date: "Oct 05, 2024",
|
||||||
|
title: "Annual Global Ethics Symposium Draws Record Attendance",
|
||||||
|
excerpt: "Scholars from over 40 countries gathered at ULP this weekend to discuss the evolving landscape of international human rights and digital privacy.",
|
||||||
|
image: "https://storage.googleapis.com/uxpilot-auth.appspot.com/fc832714d8-ee7527b4d94c300aae71.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
category: "Research",
|
||||||
|
date: "Sep 28, 2024",
|
||||||
|
title: "Department of Sociology Publishes Landmark Study on Urban Migration",
|
||||||
|
excerpt: "A comprehensive 5-year study reveals shifting demographic patterns in post-industrial European cities, highlighting new socio-economic challenges.",
|
||||||
|
icon: "fas fa-flask",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function NewsGrid() {
|
||||||
|
return (
|
||||||
|
<div className="flex-1">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-12">
|
||||||
|
{news.map((item) => (
|
||||||
|
<NewsCard key={item.title} {...item} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Pagination */}
|
||||||
|
<div className="flex justify-center items-center gap-2 border-t border-ui-border pt-8">
|
||||||
|
<button className="pg-btn w-10 h-10 flex items-center justify-center border border-ui-border text-ui-muted transition-colors disabled:opacity-50" disabled>
|
||||||
|
<i className="fas fa-chevron-left"></i>
|
||||||
|
</button>
|
||||||
|
<button className="pg-btn pg-active w-10 h-10 flex items-center justify-center text-white font-bold">1</button>
|
||||||
|
<button className="pg-btn w-10 h-10 flex items-center justify-center border border-ui-border text-ui-text transition-colors font-medium">2</button>
|
||||||
|
<button className="pg-btn w-10 h-10 flex items-center justify-center border border-ui-border text-ui-text transition-colors font-medium">3</button>
|
||||||
|
<span className="text-ui-muted mx-2">...</span>
|
||||||
|
<button className="pg-btn w-10 h-10 flex items-center justify-center border border-ui-border text-ui-text transition-colors font-medium">12</button>
|
||||||
|
<button className="pg-btn w-10 h-10 flex items-center justify-center border border-ui-border text-ui-text transition-colors">
|
||||||
|
<i className="fas fa-chevron-right"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
37
app/components/blog/NewsletterWidget.tsx
Normal file
37
app/components/blog/NewsletterWidget.tsx
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
export default function NewsletterWidget() {
|
||||||
|
return (
|
||||||
|
<div className="bg-brand-blue rounded-xl p-8 text-white shadow-hover relative overflow-hidden folder-tab">
|
||||||
|
<div className="relative z-10">
|
||||||
|
<div className="blog-widget-title font-bold mb-3">Stay Informed</div>
|
||||||
|
<p className="text-sm text-brand-light/80 mb-6 leading-relaxed ">
|
||||||
|
Subscribe to our weekly newsletter for the latest research updates, campus news, and upcoming events.
|
||||||
|
</p>
|
||||||
|
<form className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
placeholder="Enter your email address"
|
||||||
|
className="w-full px-4 py-3 mt-4 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:border-white focus:ring-1 focus:ring-white text-sm"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-full py-3 bg-white text-brand-blue rounded-lg font-bold hover:bg-gray-50 transition-colors text-sm shadow-sm"
|
||||||
|
>
|
||||||
|
Subscribe Now
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<p className="text-xs text-brand-light/60 mt-4 text-center">
|
||||||
|
By subscribing, you agree to our{" "}
|
||||||
|
<a href="#" style={{ color: "inherit", textDecoration: "underline" }}>Privacy Policy</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Decorative background element */}
|
||||||
|
<div className="absolute -bottom-12 -right-12 text-white/5 text-9xl">
|
||||||
|
<i className="far fa-envelope"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
47
app/components/blog/ResearcherSpotlight.tsx
Normal file
47
app/components/blog/ResearcherSpotlight.tsx
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
const researchers = [
|
||||||
|
{
|
||||||
|
name: "Dr. Sarah Jenkins",
|
||||||
|
field: "Cognitive Linguistics",
|
||||||
|
bio: "Exploring the intersection of language processing and modern ethical frameworks in digital communication.",
|
||||||
|
avatar: "https://storage.googleapis.com/uxpilot-auth.appspot.com/avatars/avatar-5.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Prof. Marcus Chen",
|
||||||
|
field: "Economic History",
|
||||||
|
bio: "Recent recipient of the European Heritage Grant for his work on interwar economic policies.",
|
||||||
|
avatar: "https://storage.googleapis.com/uxpilot-auth.appspot.com/avatars/avatar-4.jpg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Dr. Elena Rostova",
|
||||||
|
field: "Political Science",
|
||||||
|
bio: "Leading the new comparative study on post-war democratic institutions across Western Europe.",
|
||||||
|
avatar: "https://storage.googleapis.com/uxpilot-auth.appspot.com/avatars/avatar-6.jpg",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function ResearcherSpotlight() {
|
||||||
|
return (
|
||||||
|
<div className="bg-white rounded-xl border border-ui-border shadow-soft p-6">
|
||||||
|
<div className="flex items-center justify-between mb-6 pb-4 border-b border-ui-border">
|
||||||
|
<div className="blog-widget-title font-bold text-ui-text">Researcher Spotlight</div>
|
||||||
|
<a href="#" className="text-sm text-brand-blue font-medium hover:underline">View All</a>
|
||||||
|
</div>
|
||||||
|
<div className="space-y-6">
|
||||||
|
{researchers.map((r) => (
|
||||||
|
<div key={r.name} className="flex gap-4 items-start group cursor-pointer">
|
||||||
|
<img
|
||||||
|
src={r.avatar}
|
||||||
|
alt={r.name}
|
||||||
|
className="w-16 h-16 rounded-lg object-cover border border-ui-border group-hover:border-brand-blue transition-colors"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<div className="font-bold text-ui-text text-sm group-hover:text-brand-blue transition-colors">{r.name}</div>
|
||||||
|
<p className="text-xs text-brand-blue font-medium mb-1">{r.field}</p>
|
||||||
|
<p className="text-xs text-ui-muted line-clamp-2">{r.bio}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
40
app/components/blog/UpcomingEvents.tsx
Normal file
40
app/components/blog/UpcomingEvents.tsx
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
const events = [
|
||||||
|
{
|
||||||
|
month: "Nov",
|
||||||
|
day: "12",
|
||||||
|
title: "Open Campus Day",
|
||||||
|
time: "09:00 AM - 04:00 PM",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
month: "Nov",
|
||||||
|
day: "18",
|
||||||
|
title: "Guest Lecture: Future of AI in Arts",
|
||||||
|
time: "06:00 PM - Main Hall",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function UpcomingEvents() {
|
||||||
|
return (
|
||||||
|
<div className="bg-white rounded-xl border border-ui-border shadow-soft p-6">
|
||||||
|
<div className="blog-widget-title font-bold text-ui-text mb-6 pb-4 border-b border-ui-border">
|
||||||
|
Upcoming Events
|
||||||
|
</div>
|
||||||
|
<ul className="space-y-4">
|
||||||
|
{events.map((e) => (
|
||||||
|
<li key={e.title} className="flex gap-4">
|
||||||
|
<div className="flex flex-col items-center justify-center w-12 h-12 bg-brand-light rounded-lg border border-brand-blue/20 shrink-0">
|
||||||
|
<span className="text-xs font-bold text-brand-blue uppercase">{e.month}</span>
|
||||||
|
<span className="text-lg font-bold text-ui-text leading-none">{e.day}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="text-sm font-bold text-ui-text hover:text-brand-blue cursor-pointer transition-colors">{e.title}</div>
|
||||||
|
<p className="text-xs text-ui-muted mt-1">
|
||||||
|
<i className="far fa-clock mr-1"></i>{e.time}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user