This commit is contained in:
2025-08-05 18:40:51 -05:00
parent 2a2c5a718a
commit bb5acb8f53
11 changed files with 585 additions and 134 deletions

View File

@@ -9,19 +9,65 @@
"lint": "next lint"
},
"dependencies": {
"@fontsource/jetbrains-mono": "^5.2.6",
"@hookform/resolvers": "^5.2.1",
"@radix-ui/react-accordion": "^1.2.11",
"@radix-ui/react-alert-dialog": "^1.1.14",
"@radix-ui/react-aspect-ratio": "^1.1.7",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.2",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-context-menu": "^2.2.15",
"@radix-ui/react-dialog": "^1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-hover-card": "^1.1.14",
"@radix-ui/react-label": "^2.1.7",
"@radix-ui/react-menubar": "^1.1.15",
"@radix-ui/react-navigation-menu": "^1.2.13",
"@radix-ui/react-popover": "^1.1.14",
"@radix-ui/react-progress": "^1.1.7",
"@radix-ui/react-radio-group": "^1.3.7",
"@radix-ui/react-scroll-area": "^1.2.9",
"@radix-ui/react-select": "^2.2.5",
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slider": "^1.3.5",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-switch": "^1.2.5",
"@radix-ui/react-tabs": "^1.1.12",
"@radix-ui/react-toggle": "^1.1.9",
"@radix-ui/react-toggle-group": "^1.1.10",
"@radix-ui/react-tooltip": "^1.2.7",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"input-otp": "^1.4.2",
"lucide-react": "^0.536.0",
"motion": "^12.23.12",
"next": "15.4.5",
"next-themes": "^0.4.6",
"react": "19.1.0",
"react-day-picker": "^9.8.1",
"react-dom": "19.1.0",
"next": "15.4.5"
"react-hook-form": "^7.62.0",
"react-resizable-panels": "^3.0.4",
"recharts": "2.15.4",
"sonner": "^2.0.7",
"tailwind-merge": "^3.3.1",
"vaul": "^1.1.2",
"zod": "^4.0.14"
},
"devDependencies": {
"typescript": "^5",
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4",
"eslint": "^9",
"eslint-config-next": "15.4.5",
"@eslint/eslintrc": "^3"
"tailwindcss": "^4",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5"
}
}

View File

@@ -1,5 +1,6 @@
const config = {
plugins: ["@tailwindcss/postcss"],
};
export default config;

Binary file not shown.

View File

@@ -1,26 +0,0 @@
@import "tailwindcss";
:root {
--background: #ffffff;
--foreground: #171717;
}
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
}
@media (prefers-color-scheme: dark) {
:root {
--background: #0a0a0a;
--foreground: #ededed;
}
}
body {
background: var(--background);
color: var(--foreground);
font-family: Arial, Helvetica, sans-serif;
}

View File

@@ -1,7 +1,7 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import "../styles/globals.css";
import { ThemeProvider } from "@/components/theme-provider"
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
@@ -23,11 +23,18 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="en">
<html lang="en" suppressHydrationWarning={true}>
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
className={`antialiased`}
>
{children}
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);

View File

@@ -1,103 +1,176 @@
"use client";
import Image from "next/image";
import { PlaceholdersAndVanishInput } from "@/components/ui/placeholders-and-vanish-input";
import { BackgroundGradient } from "@/components/ui/background-gradient";
import { useState } from "react";
import { useRouter } from "next/navigation"; // Import useRouter
import { Search, Settings, X } from "lucide-react";
export default function Home() {
return (
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={180}
height={38}
priority
/>
<ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left">
<li className="mb-2 tracking-[-.01em]">
Get started by editing{" "}
<code className="bg-black/[.05] dark:bg-white/[.06] font-mono font-semibold px-1 py-0.5 rounded">
src/app/page.tsx
</code>
.
</li>
<li className="tracking-[-.01em]">
Save and see your changes instantly.
</li>
</ol>
const [searchQuery, setSearchQuery] = useState("");
const [showAdvanced, setShowAdvanced] = useState(false);
const [advancedFields, setAdvancedFields] = useState({
title: "",
author: "",
abstract: ""
});
<div className="flex gap-4 items-center flex-col sm:flex-row">
<a
className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={20}
height={20}
/>
Deploy now
</a>
<a
className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Read our docs
</a>
const router = useRouter(); // Initialize router
const handleAdvancedSearch = () => {
// Build query params for advanced search
const params = new URLSearchParams();
if (searchQuery) params.set("q", searchQuery);
params.set("p", "1");
params.set("pageSize", "20");
// Add advanced fields if they have values
if (advancedFields.title) params.set("title", advancedFields.title);
if (advancedFields.author) params.set("author", advancedFields.author);
if (advancedFields.abstract) params.set("abstract", advancedFields.abstract);
router.push(`/search?${params.toString()}`); // Use router.push instead of redirect
};
const handleBasicSearch = () => {
router.push("/search?q=" + searchQuery + "&p=1" + "&pageSize=" + 20); // Use router.push instead of redirect
};
return (
<div className="min-h-screen bg-white dark:bg-black flex flex-col items-center pt-32 pb-16">
<h1 className="text-center text-black dark:text-white jetbrains text-6xl mb-12">
Refinity
</h1>
{/* Main Search Bar */}
<BackgroundGradient containerClassName="w-[35vw] rounded-3xl" className={"w-full"}>
<PlaceholdersAndVanishInput
placeholders={[
"Machine Learning Algorithms For Healthcare",
"Climate Change Impact On Agriculture",
"Quantum Computing Applications In Cryptography",
"Deep Learning Techniques For Image Recognition",
"Renewable Energy Technologies And Efficiency",
"Natural Language Processing In Social Media Analysis",
"Genome Editing Tools And Ethical Considerations",
"Cybersecurity Threats And Prevention Strategies",
"Robotics Automation In Manufacturing Industry",
"Blockchain Technology For Supply Chain Management",
"AI Fairness And Bias Mitigation Methods",
"Virtual Reality Applications In Education",
"Big Data Analytics For Financial Markets",
"Nanomaterials In Drug Delivery Systems",
"Sustainable Urban Development Strategies",
"Human-Computer Interaction Design Principles",
"Neural Network Architectures For Speech Recognition",
"Privacy Issues In Internet Of Things",
"Solar Cell Efficiency Improvement Techniques",
"Autonomous Vehicles And Traffic Management",
]}
onChange={(v) => setSearchQuery(v.target.value)}
onSubmit={handleBasicSearch}
/>
</BackgroundGradient>
{/* Advanced Search Toggle */}
<div className="mt-6">
<button
onClick={() => setShowAdvanced(!showAdvanced)}
className="flex items-center gap-2 text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200 transition-colors"
>
<Settings size={16} />
<span className="text-sm">
{showAdvanced ? "Hide Advanced Search" : "Advanced Search"}
</span>
</button>
</div>
{/* Advanced Search Window */}
{showAdvanced && (
<div className="mt-8 w-[35vw] bg-gray-50 dark:bg-gray-900 border border-gray-200 dark:border-gray-700 rounded-xl p-6 shadow-lg">
<div className="flex items-center justify-between mb-6">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
Advanced Search
</h3>
<button
onClick={() => setShowAdvanced(false)}
className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
>
<X size={20} />
</button>
</div>
<div className="space-y-4">
{/* Title Search */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Title
</label>
<input
type="text"
value={advancedFields.title}
onChange={(e) => setAdvancedFields(prev => ({ ...prev, title: e.target.value }))}
placeholder="Search in article titles..."
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
{/* Author Search */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Author
</label>
<input
type="text"
value={advancedFields.author}
onChange={(e) => setAdvancedFields(prev => ({ ...prev, author: e.target.value }))}
placeholder="Search by author name..."
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
{/* Abstract Search */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
Abstract
</label>
<input
type="text"
value={advancedFields.abstract}
onChange={(e) => setAdvancedFields(prev => ({ ...prev, abstract: e.target.value }))}
placeholder="Search in abstracts..."
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent"
/>
</div>
</div>
{/* Advanced Search Button */}
<div className="mt-6 flex gap-3">
<button
onClick={handleAdvancedSearch}
className="flex-1 flex items-center justify-center gap-2 bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition-colors"
>
<Search size={16} />
Advanced Search
</button>
<button
onClick={() => {
setAdvancedFields({ title: "", author: "", abstract: "" });
setSearchQuery("");
}}
className="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800 rounded-lg transition-colors"
>
Clear
</button>
</div>
{/* Info Text */}
<p className="mt-4 text-xs text-gray-500 dark:text-gray-400">
Leave fields empty to search all content. Combine with general search above for more specific results.
</p>
</div>
)}
</div>
</main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/file.svg"
alt="File icon"
width={16}
height={16}
/>
Learn
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/window.svg"
alt="Window icon"
width={16}
height={16}
/>
Examples
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src="/globe.svg"
alt="Globe icon"
width={16}
height={16}
/>
Go to nextjs.org
</a>
</footer>
</div>
);
}
);
}

BIN
src/app/search/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

41
src/app/search/layout.tsx Normal file
View File

@@ -0,0 +1,41 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "@/styles/globals.css";
import { ThemeProvider } from "@/components/theme-provider"
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" suppressHydrationWarning={true}>
<body
className={`antialiased`}
>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
</ThemeProvider>
</body>
</html>
);
}

289
src/app/search/page.tsx Normal file
View File

@@ -0,0 +1,289 @@
"use client";
import {getArticlesPage, getArticlesPageAdvanced} from "@/lib/CrossRefAPI"
import { useState, useEffect } from "react";
import Article from "@/components/ui/articles"
import { Search, Settings, ChevronDown, ChevronUp, X } from "lucide-react";
import {redirect, useSearchParams} from "next/navigation";
import { PlaceholdersAndVanishInput } from "@/components/ui/placeholders-and-vanish-input";
import { BackgroundGradient } from "@/components/ui/background-gradient";
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination"
import ArticlesContainer from "@/components/ui/articles";
export default function SearchPage() {
const searchParams = useSearchParams();
const page = parseInt(searchParams.get("p") ?? "1");
const pageSize = parseInt(searchParams.get("pageSize") ?? "10");
const query = searchParams.get("q") ?? "";
const titleQuery = searchParams.get("title") ?? "";
const authorQuery = searchParams.get("author") ?? "";
const abstractQuery = searchParams.get("abstract") ?? "";
const [hovered, setHovered] = useState(false);
const [showInput, setShowInput] = useState(false);
const [searchQuery, setSearchQuery] = useState(query);
const [showAdvanced, setShowAdvanced] = useState(false);
const [advancedFields, setAdvancedFields] = useState({
title: titleQuery,
author: authorQuery,
abstract: abstractQuery
});
// Control rendering input with delay for smooth collapse animation
useEffect(() => {
if (hovered) {
setShowInput(true);
} else {
const timeout = setTimeout(() => setShowInput(false), 300); // match CSS transition duration
return () => clearTimeout(timeout);
}
}, [hovered]);
// Update search query when URL changes
useEffect(() => {
setSearchQuery(query);
setAdvancedFields({
title: titleQuery,
author: authorQuery,
abstract: abstractQuery
});
}, [query, titleQuery, authorQuery, abstractQuery]);
const handleAdvancedSearch = () => {
// Build query params for advanced search
const params = new URLSearchParams();
if (searchQuery) params.set("q", searchQuery);
params.set("p", "1");
params.set("pageSize", pageSize.toString());
// Add advanced fields if they have values
if (advancedFields.title) params.set("title", advancedFields.title);
if (advancedFields.author) params.set("author", advancedFields.author);
if (advancedFields.abstract) params.set("abstract", advancedFields.abstract);
redirect(`/search?${params.toString()}`);
};
const handleBasicSearch = () => {
redirect("/search?q=" + searchQuery + "&p=1" + "&pageSize=" + pageSize);
};
const clearAdvancedFields = () => {
setAdvancedFields({ title: "", author: "", abstract: "" });
};
// Check if any advanced fields are active
const hasAdvancedFilters = titleQuery || authorQuery || abstractQuery;
return (
<div className="w-full h-full min-h-screen bg-black jetbrains flex flex-col items-center">
{/* Top Search Bar */}
<div
className="fixed top-4 left-4 z-50 flex items-center rounded-full bg-gray-900 shadow-lg"
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{!showInput ? (
<div className="p-3 flex items-center justify-center cursor-pointer">
<Search className="text-white" size={24} />
</div>
) : (
<div
className={`
transition-[width] duration-300 ease-in-out
overflow-hidden
bg-gray-800
rounded-full
p-2
flex
items-center
${hovered ? "w-[35vw]" : "w-0"}
`}
>
<BackgroundGradient containerClassName="w-full rounded-3xl" className="w-full">
<PlaceholdersAndVanishInput
placeholders={[
"Machine Learning Algorithms For Healthcare",
"Climate Change Impact On Agriculture",
"Quantum Computing Applications In Cryptography",
"Deep Learning Techniques For Image Recognition",
"Renewable Energy Technologies And Efficiency",
"Natural Language Processing In Social Media Analysis",
"Genome Editing Tools And Ethical Considerations",
"Cybersecurity Threats And Prevention Strategies",
"Robotics Automation In Manufacturing Industry",
"Blockchain Technology For Supply Chain Management",
"AI Fairness And Bias Mitigation Methods",
"Virtual Reality Applications In Education",
"Big Data Analytics For Financial Markets",
"Nanomaterials In Drug Delivery Systems",
"Sustainable Urban Development Strategies",
"Human-Computer Interaction Design Principles",
"Neural Network Architectures For Speech Recognition",
"Privacy Issues In Internet Of Things",
"Solar Cell Efficiency Improvement Techniques",
"Autonomous Vehicles And Traffic Management",
]}
onChange={(v) => setSearchQuery(v.target.value)}
onSubmit={handleBasicSearch}
value={searchQuery}
/>
</BackgroundGradient>
</div>
)}
</div>
{/* Advanced Search Toggle - Top Right */}
<div className="fixed top-4 right-4 z-50">
<button
onClick={() => setShowAdvanced(!showAdvanced)}
className={`flex items-center gap-2 px-4 py-2 rounded-full transition-all duration-300 ${
showAdvanced || hasAdvancedFilters
? "bg-blue-600 text-white shadow-lg"
: "bg-gray-800 text-gray-300 hover:bg-gray-700"
}`}
>
<Settings size={16} />
<span className="text-sm font-medium">Advanced</span>
{showAdvanced ? <ChevronUp size={16} /> : <ChevronDown size={16} />}
{hasAdvancedFilters && (
<div className="w-2 h-2 bg-white rounded-full"></div>
)}
</button>
</div>
{/* Advanced Search Panel */}
<div className={`fixed top-16 right-4 z-40 transition-all duration-300 ${
showAdvanced ? "opacity-100 translate-y-0" : "opacity-0 -translate-y-4 pointer-events-none"
}`}>
<div className="w-80 bg-gray-800 border border-gray-700 rounded-xl shadow-2xl backdrop-blur-sm">
<div className="p-6">
<div className="flex items-center justify-between mb-6">
<h3 className="text-lg font-semibold text-white">
Advanced Search
</h3>
<button
onClick={() => setShowAdvanced(false)}
className="text-gray-400 hover:text-white transition-colors"
>
<X size={20} />
</button>
</div>
<div className="space-y-4">
{/* Title Search */}
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Title
</label>
<input
type="text"
value={advancedFields.title}
onChange={(e) => setAdvancedFields(prev => ({ ...prev, title: e.target.value }))}
placeholder="Search in article titles..."
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"
/>
</div>
{/* Author Search */}
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Author
</label>
<input
type="text"
value={advancedFields.author}
onChange={(e) => setAdvancedFields(prev => ({ ...prev, author: e.target.value }))}
placeholder="Search by author name..."
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"
/>
</div>
{/* Abstract Search */}
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
Abstract
</label>
<input
type="text"
value={advancedFields.abstract}
onChange={(e) => setAdvancedFields(prev => ({ ...prev, abstract: e.target.value }))}
placeholder="Search in abstracts..."
className="w-full px-3 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white placeholder-gray-400 focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all"
/>
</div>
</div>
{/* Action Buttons */}
<div className="mt-6 flex gap-3">
<button
onClick={handleAdvancedSearch}
className="flex-1 flex items-center justify-center gap-2 bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition-colors font-medium"
>
<Search size={16} />
Search
</button>
<button
onClick={clearAdvancedFields}
className="px-4 py-2 border border-gray-600 text-gray-300 hover:bg-gray-700 rounded-lg transition-colors"
>
Clear
</button>
</div>
{/* Active Filters Indicator */}
{hasAdvancedFilters && (
<div className="mt-4 p-3 bg-blue-900/30 border border-blue-700/50 rounded-lg">
<div className="text-xs text-blue-200 mb-2">Active filters:</div>
<div className="flex flex-wrap gap-2">
{titleQuery && (
<span className="px-2 py-1 bg-blue-600/50 text-blue-200 text-xs rounded">
Title: {titleQuery}
</span>
)}
{authorQuery && (
<span className="px-2 py-1 bg-blue-600/50 text-blue-200 text-xs rounded">
Author: {authorQuery}
</span>
)}
{abstractQuery && (
<span className="px-2 py-1 bg-blue-600/50 text-blue-200 text-xs rounded">
Abstract: {abstractQuery}
</span>
)}
</div>
</div>
)}
{/* Info Text */}
<p className="mt-4 text-xs text-gray-400">
Combine with general search for more specific results.
</p>
</div>
</div>
</div>
{/* Content area below */}
<div className={"pt-[5vh] pb-[10vh]"}>
<ArticlesContainer
searchQuery={query}
page={page}
pageSize={pageSize}
advancedFields={hasAdvancedFilters ? {
title: titleQuery || undefined,
author: authorQuery || undefined,
abstract: abstractQuery || undefined
} : undefined}
/>
</div>
</div>
);
}

20
src/styles/globals.css Normal file
View File

@@ -0,0 +1,20 @@
@import "./theme.css";
@import "../../node_modules/tailwindcss/index.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Add your JetBrains Mono font */
@font-face {
font-family: 'JetBrains Mono';
src: url('/fonts/JetBrainsMono-VariableFont_wght.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
.jetbrains {
font-family: 'JetBrains Mono', monospace;
}