feat(discover): update discover UI, add new font

This commit is contained in:
ItzCrazyKns
2025-09-25 18:56:04 +05:30
parent bd8e3dfa2e
commit 8f728a2518
5 changed files with 275 additions and 52 deletions

BIN
public/fonts/pp-ed-ul.otf Normal file

Binary file not shown.

View File

@@ -1,12 +1,13 @@
'use client';
import { Search } from 'lucide-react';
import { Globe2Icon } from 'lucide-react';
import { useEffect, useState } from 'react';
import Link from 'next/link';
import { toast } from 'sonner';
import { cn } from '@/lib/utils';
import SmallNewsCard from '@/components/Discover/SmallNewsCard';
import MajorNewsCard from '@/components/Discover/MajorNewsCard';
interface Discover {
export interface Discover {
title: string;
content: string;
url: string;
@@ -75,29 +76,34 @@ const Page = () => {
return (
<>
<div>
<div className="flex flex-col pt-4">
<div className="flex items-center">
<Search />
<h1 className="text-3xl font-medium p-2">Discover</h1>
</div>
<hr className="border-t border-[#2B2C2C] my-4 w-full" />
</div>
<div className="flex flex-row items-center space-x-2 overflow-x-auto">
{topics.map((t, i) => (
<div
key={i}
className={cn(
'border-[0.1px] rounded-full text-sm px-3 py-1 text-nowrap transition duration-200 cursor-pointer',
activeTopic === t.key
? 'text-cyan-300 bg-cyan-300/30 border-cyan-300/60'
: 'border-black/30 dark:border-white/30 text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white hover:border-black/40 dark:hover:border-white/40 hover:bg-black/5 dark:hover:bg-white/5',
)}
onClick={() => setActiveTopic(t.key)}
>
<span>{t.display}</span>
<div className="flex flex-col pt-10 border-b border-light-200/20 dark:border-dark-200/20 pb-6 px-2">
<div className="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4">
<div className="flex items-center justify-center">
<Globe2Icon size={45} className="mb-2.5" />
<h1
className="text-5xl font-normal p-2"
style={{ fontFamily: 'PP Editorial, serif' }}
>
Discover
</h1>
</div>
))}
<div className="flex flex-row items-center space-x-2 overflow-x-auto">
{topics.map((t, i) => (
<div
key={i}
className={cn(
'border-[0.1px] rounded-full text-sm px-3 py-1 text-nowrap transition duration-200 cursor-pointer',
activeTopic === t.key
? 'text-cyan-700 dark:text-cyan-300 bg-cyan-300/20 border-cyan-700/60 dar:bg-cyan-300/30 dark:border-cyan-300/40'
: 'border-black/30 dark:border-white/30 text-black/70 dark:text-white/70 hover:text-black dark:hover:text-white hover:border-black/40 dark:hover:border-white/40 hover:bg-black/5 dark:hover:bg-white/5',
)}
onClick={() => setActiveTopic(t.key)}
>
<span>{t.display}</span>
</div>
))}
</div>
</div>
</div>
{loading ? (
@@ -120,34 +126,141 @@ const Page = () => {
</svg>
</div>
) : (
<div className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-4 pb-28 pt-5 lg:pb-8 w-full justify-items-center lg:justify-items-start">
{discover &&
discover?.map((item, i) => (
<Link
href={`/?q=Summary: ${item.url}`}
key={i}
className="max-w-sm rounded-lg overflow-hidden bg-light-secondary dark:bg-dark-secondary hover:-translate-y-[1px] transition duration-200"
target="_blank"
>
<img
className="object-cover w-full aspect-video"
src={
new URL(item.thumbnail).origin +
new URL(item.thumbnail).pathname +
`?id=${new URL(item.thumbnail).searchParams.get('id')}`
<div className="flex flex-col gap-4 pb-28 pt-5 lg:pb-8 w-full">
<div className="block lg:hidden">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{discover?.map((item, i) => (
<SmallNewsCard key={`mobile-${i}`} item={item} />
))}
</div>
</div>
<div className="hidden lg:block">
{discover &&
discover.length > 0 &&
(() => {
const sections = [];
let index = 0;
while (index < discover.length) {
if (sections.length > 0) {
sections.push(
<hr
key={`sep-${index}`}
className="border-t border-light-200/20 dark:border-dark-200/20 my-3 w-full"
/>,
);
}
alt={item.title}
/>
<div className="px-6 py-4">
<div className="font-bold text-lg mb-2">
{item.title.slice(0, 100)}...
</div>
<p className="text-black-70 dark:text-white/70 text-sm">
{item.content.slice(0, 100)}...
</p>
</div>
</Link>
))}
if (index < discover.length) {
sections.push(
<MajorNewsCard
key={`major-${index}`}
item={discover[index]}
isLeft={false}
/>,
);
index++;
}
if (index < discover.length) {
sections.push(
<hr
key={`sep-${index}-after`}
className="border-t border-light-200/20 dark:border-dark-200/20 my-3 w-full"
/>,
);
}
if (index < discover.length) {
const smallCards = discover.slice(index, index + 3);
sections.push(
<div
key={`small-group-${index}`}
className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-4"
>
{smallCards.map((item, i) => (
<SmallNewsCard
key={`small-${index + i}`}
item={item}
/>
))}
</div>,
);
index += 3;
}
if (index < discover.length) {
sections.push(
<hr
key={`sep-${index}-after-small`}
className="border-t border-light-200/20 dark:border-dark-200/20 my-3 w-full"
/>,
);
}
if (index < discover.length - 1) {
const twoMajorCards = discover.slice(index, index + 2);
twoMajorCards.forEach((item, i) => {
sections.push(
<MajorNewsCard
key={`double-${index + i}`}
item={item}
isLeft={i === 0}
/>,
);
if (i === 0) {
sections.push(
<hr
key={`sep-double-${index + i}`}
className="border-t border-light-200/20 dark:border-dark-200/20 my-3 w-full"
/>,
);
}
});
index += 2;
} else if (index < discover.length) {
sections.push(
<MajorNewsCard
key={`final-major-${index}`}
item={discover[index]}
isLeft={true}
/>,
);
index++;
}
if (index < discover.length) {
sections.push(
<hr
key={`sep-${index}-after-major`}
className="border-t border-light-200/20 dark:border-dark-200/20 my-3 w-full"
/>,
);
}
if (index < discover.length) {
const smallCards = discover.slice(index, index + 3);
sections.push(
<div
key={`small-group-2-${index}`}
className="grid lg:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-4"
>
{smallCards.map((item, i) => (
<SmallNewsCard
key={`small-2-${index + i}`}
item={item}
/>
))}
</div>,
);
index += 3;
}
}
return sections;
})()}
</div>
</div>
)}
</div>

View File

@@ -2,6 +2,14 @@
@tailwind components;
@tailwind utilities;
@font-face {
font-family: 'PP Editorial';
src: url('/fonts/pp-ed-ul.otf') format('opentype');
font-weight: 200;
font-style: normal;
font-display: swap;
}
@layer base {
.overflow-hidden-scrollable {
-ms-overflow-style: none;

View File

@@ -0,0 +1,70 @@
import { Discover } from '@/app/discover/page';
import Link from 'next/link';
const MajorNewsCard = ({
item,
isLeft = true,
}: {
item: Discover;
isLeft?: boolean;
}) => (
<Link
href={`/?q=Summary: ${item.url}`}
className="w-full group flex flex-row items-stretch gap-6 h-60 py-3"
target="_blank"
>
{isLeft ? (
<>
<div className="relative w-80 h-full overflow-hidden rounded-2xl flex-shrink-0">
<img
className="object-cover w-full h-full group-hover:scale-105 transition-transform duration-500"
src={
new URL(item.thumbnail).origin +
new URL(item.thumbnail).pathname +
`?id=${new URL(item.thumbnail).searchParams.get('id')}`
}
alt={item.title}
/>
</div>
<div className="flex flex-col justify-center flex-1 py-4">
<h2
className="text-3xl font-light mb-3 leading-tight line-clamp-3 group-hover:text-cyan-500 dark:group-hover:text-cyan-300 transition duration-200"
style={{ fontFamily: 'PP Editorial, serif' }}
>
{item.title}
</h2>
<p className="text-black/60 dark:text-white/60 text-base leading-relaxed line-clamp-4">
{item.content}
</p>
</div>
</>
) : (
<>
<div className="flex flex-col justify-center flex-1 py-4">
<h2
className="text-3xl font-light mb-3 leading-tight line-clamp-3 group-hover:text-cyan-500 dark:group-hover:text-cyan-300 transition duration-200"
style={{ fontFamily: 'PP Editorial, serif' }}
>
{item.title}
</h2>
<p className="text-black/60 dark:text-white/60 text-base leading-relaxed line-clamp-4">
{item.content}
</p>
</div>
<div className="relative w-80 h-full overflow-hidden rounded-2xl flex-shrink-0">
<img
className="object-cover w-full h-full group-hover:scale-105 transition-transform duration-500"
src={
new URL(item.thumbnail).origin +
new URL(item.thumbnail).pathname +
`?id=${new URL(item.thumbnail).searchParams.get('id')}`
}
alt={item.title}
/>
</div>
</>
)}
</Link>
);
export default MajorNewsCard;

View File

@@ -0,0 +1,32 @@
import { Discover } from '@/app/discover/page';
import Link from 'next/link';
const SmallNewsCard = ({ item }: { item: Discover }) => (
<Link
href={`/?q=Summary: ${item.url}`}
className="rounded-3xl overflow-hidden bg-light-secondary dark:bg-dark-secondary shadow-sm shadow-light-200/10 dark:shadow-black/25 group flex flex-col"
target="_blank"
>
<div className="relative aspect-video overflow-hidden">
<img
className="object-cover w-full h-full group-hover:scale-105 transition-transform duration-300"
src={
new URL(item.thumbnail).origin +
new URL(item.thumbnail).pathname +
`?id=${new URL(item.thumbnail).searchParams.get('id')}`
}
alt={item.title}
/>
</div>
<div className="p-4">
<h3 className="font-semibold text-sm mb-2 leading-tight line-clamp-2 group-hover:text-cyan-500 dark:group-hover:text-cyan-300 transition duration-200">
{item.title}
</h3>
<p className="text-black/60 dark:text-white/60 text-xs leading-relaxed line-clamp-2">
{item.content}
</p>
</div>
</Link>
);
export default SmallNewsCard;