Compare commits
2 Commits
3832532b17
...
b9b7a9a6cc
Author | SHA1 | Date |
---|---|---|
Juan Di Toro | b9b7a9a6cc | |
Juan Di Toro | 7c58be9d6f |
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"extends": "next/core-web-vitals"
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
36
README.md
36
README.md
|
@ -1,2 +1,36 @@
|
||||||
# web3.news
|
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
First, run the development server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
# or
|
||||||
|
yarn dev
|
||||||
|
# or
|
||||||
|
pnpm dev
|
||||||
|
# or
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||||
|
|
||||||
|
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||||
|
|
||||||
|
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||||
|
|
||||||
|
## Learn More
|
||||||
|
|
||||||
|
To learn more about Next.js, take a look at the following resources:
|
||||||
|
|
||||||
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||||
|
|
||||||
|
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {}
|
||||||
|
|
||||||
|
module.exports = nextConfig
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"name": "web3.news",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@heroicons/react": "^2.0.18",
|
||||||
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
|
"date-fns": "^2.30.0",
|
||||||
|
"next": "14.0.2",
|
||||||
|
"react": "^18",
|
||||||
|
"react-dom": "^18"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20",
|
||||||
|
"@types/react": "^18",
|
||||||
|
"@types/react-dom": "^18",
|
||||||
|
"autoprefixer": "^10.0.1",
|
||||||
|
"eslint": "^8",
|
||||||
|
"eslint-config-next": "14.0.2",
|
||||||
|
"postcss": "^8",
|
||||||
|
"tailwindcss": "^3.3.0",
|
||||||
|
"tailwindcss-animate": "^1.0.7",
|
||||||
|
"typescript": "^5"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
After Width: | Height: | Size: 629 B |
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
|
@ -0,0 +1,82 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--primary: 136, 87%, 83%;
|
||||||
|
--primary-foreground: black;
|
||||||
|
|
||||||
|
--secondary: 169 46% 37%;
|
||||||
|
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--muted: 0 0% 32%;
|
||||||
|
--muted-foreground: 0 0% 32%;
|
||||||
|
|
||||||
|
--accent: 210 40% 96.1%;
|
||||||
|
--accent-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--border: 0 0% 32%;
|
||||||
|
--input: 0 0% 32%;
|
||||||
|
--ring: 222.2 84% 4.9%;
|
||||||
|
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 222.2 84% 4.9%;
|
||||||
|
--foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--card: 222.2 84% 4.9%;
|
||||||
|
--card-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--popover: 222.2 84% 4.9%;
|
||||||
|
--popover-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--primary: 210 40% 98%;
|
||||||
|
--primary-foreground: 222.2 47.4% 11.2%;
|
||||||
|
|
||||||
|
--secondary: 217.2 32.6% 17.5%;
|
||||||
|
--secondary-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--muted: 217.2 32.6% 17.5%;
|
||||||
|
--muted-foreground: 215 20.2% 65.1%;
|
||||||
|
|
||||||
|
--accent: 217.2 32.6% 17.5%;
|
||||||
|
--accent-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 210 40% 98%;
|
||||||
|
|
||||||
|
--border: 217.2 32.6% 17.5%;
|
||||||
|
--input: 217.2 32.6% 17.5%;
|
||||||
|
--ring: 212.7 26.8% 83.9%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main astro-island {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
import { Inter } from 'next/font/google'
|
||||||
|
import './globals.css'
|
||||||
|
|
||||||
|
const inter = Inter({ subsets: ['latin'] })
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Create Next App',
|
||||||
|
description: 'Generated by create next app',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body className={`${inter.className} bg-gray-900 flex`}>{children}</body>
|
||||||
|
</html>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
import SearchBar from "@/components/SearchBar"
|
||||||
|
import Image from "next/image"
|
||||||
|
|
||||||
|
const newsItems = [
|
||||||
|
{ id: 123, timestamp: Date.now(), title: "Test", description: "Well hello" }
|
||||||
|
]
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<main className="flex w-full min-h-screen flex-col md:px-40 items-center space-y-10 py-16 mx-auto">
|
||||||
|
<SearchBar />
|
||||||
|
|
||||||
|
<div className="flex flex-row flex-wrap justify-between w-full">
|
||||||
|
<Feed />
|
||||||
|
<Feed />
|
||||||
|
<Feed />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Feed = () => {
|
||||||
|
return <section className="flex flex-col space-y-6 w-[calc(33%-24px)] max-w-md">
|
||||||
|
<header className="flex flex-row space-x-3 items-start">
|
||||||
|
<PaperIcon className="text-primary mt-1"/>
|
||||||
|
<nav>
|
||||||
|
<h3 className="text-primary text-xl">Latest community posts</h3>
|
||||||
|
<ul className="text-gray-400 text-sm list-none [&>li:hover]:cursor-pointer [&>li:hover]:text-white">
|
||||||
|
<li className="text-white inline after:content-['/'] after:mx-1 after:text-gray-400">latest</li>
|
||||||
|
<li className="text-current inline after:content-['/'] after:mx-1 after:text-gray-400">day</li>
|
||||||
|
<li className="text-current inline after:content-['/'] after:mx-1 after:text-gray-400">week</li>
|
||||||
|
<li className="text-current inline">month</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<div className="@container space-y-4 w-full">
|
||||||
|
<article className="flex bg-gray-800 flex-col @md:flex-row justify-between w-full py-4 px-6 rounded">
|
||||||
|
<span className="inline-block text-gray-500 w-full flex-1">1h ago</span>
|
||||||
|
<p className="inline-block text-white w-[25ch] flex-auto">
|
||||||
|
Bitcoin (BTC) Price Prediction: When Will Bitcoin Reach $100,000?
|
||||||
|
</p>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
}
|
||||||
|
|
||||||
|
const PaperIcon = ({className}: {className: string}) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
className={className}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M3.75 0.75V23.25H20.25V0.75H3.75ZM6.46729 2.95093H9.23364C9.64819 2.95093 9.98364 3.28674 9.98364 3.70093C9.98364 4.11511 9.64819 4.45093 9.23364 4.45093H6.46729C6.05273 4.45093 5.71729 4.11511 5.71729 3.70093C5.71729 3.28674 6.05273 2.95093 6.46729 2.95093ZM17.5327 16.9918H6.46729C6.05273 16.9918 5.71729 16.656 5.71729 16.2418C5.71729 15.8276 6.05273 15.4918 6.46729 15.4918H17.5327C17.9473 15.4918 18.2827 15.8276 18.2827 16.2418C18.2827 16.656 17.9473 16.9918 17.5327 16.9918ZM17.5327 14.1639H6.46729C6.05273 14.1639 5.71729 13.8281 5.71729 13.4139C5.71729 12.9998 6.05273 12.6639 6.46729 12.6639H17.5327C17.9473 12.6639 18.2827 12.9998 18.2827 13.4139C18.2827 13.8281 17.9473 14.1639 17.5327 14.1639ZM17.5327 11.3361H6.46729C6.05273 11.3361 5.71729 11.0002 5.71729 10.5861C5.71729 10.1719 6.05273 9.83606 6.46729 9.83606H17.5327C17.9473 9.83606 18.2827 10.1719 18.2827 10.5861C18.2827 11.0002 17.9473 11.3361 17.5327 11.3361ZM17.5327 8.50818H9.23364C8.81909 8.50818 8.48364 8.17236 8.48364 7.75818C8.48364 7.34399 8.81909 7.00818 9.23364 7.00818H17.5327C17.9473 7.00818 18.2827 7.34399 18.2827 7.75818C18.2827 8.17236 17.9473 8.50818 17.5327 8.50818Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,196 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import React, { FormEvent, useRef, useState } from "react"
|
||||||
|
import {
|
||||||
|
MagnifyingGlassIcon as SearchIcon,
|
||||||
|
FunnelIcon as FilterIcon,
|
||||||
|
ChevronDownIcon,
|
||||||
|
ChevronRightIcon
|
||||||
|
} from "@heroicons/react/24/outline" // Assuming usage of Heroicons for icons
|
||||||
|
import { formatDistanceToNow } from "date-fns" // date-fns library used for date formatting
|
||||||
|
import { flushSync } from "react-dom"
|
||||||
|
|
||||||
|
// Utility function to format dates
|
||||||
|
const formatDate = (date: string | Date) => {
|
||||||
|
const distance = formatDistanceToNow(new Date(date), { addSuffix: true })
|
||||||
|
return distance
|
||||||
|
.replace(/less than a minute?/, "<1m")
|
||||||
|
.replace(/ seconds?/, "s")
|
||||||
|
.replace(/ minutes?/, "m")
|
||||||
|
.replace(/ hours?/, "h")
|
||||||
|
.replace(/ days?/, "d")
|
||||||
|
.replace(/ weeks?/, "w")
|
||||||
|
}
|
||||||
|
|
||||||
|
const SearchBar = () => {
|
||||||
|
const inputRef = useRef<HTMLInputElement>()
|
||||||
|
const [query, setQuery] = useState("")
|
||||||
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
|
const [activeInput, setActiveInput] = useState(true)
|
||||||
|
const [results, setResults] = useState<
|
||||||
|
{
|
||||||
|
id: number
|
||||||
|
timestamp: Date
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
}[]
|
||||||
|
>([])
|
||||||
|
|
||||||
|
const handleSearch = async (event: FormEvent<HTMLFormElement>) => {
|
||||||
|
event.preventDefault()
|
||||||
|
setIsLoading(true)
|
||||||
|
// Perform search and update results state
|
||||||
|
// Assume fetchResults is a function that fetches search results
|
||||||
|
// const searchResults = await fetchResults(query);
|
||||||
|
// Mock the search results
|
||||||
|
const searchResults = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
timestamp: new Date(),
|
||||||
|
title: "Mock Title 1",
|
||||||
|
description: "Mock Description 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
timestamp: new Date(),
|
||||||
|
title: "Mock Title 2",
|
||||||
|
description: "Mock Description 2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
setResults(searchResults)
|
||||||
|
setIsLoading(false)
|
||||||
|
setActiveInput(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={`w-full p-4 border-2 ${
|
||||||
|
results.length > 0 ? "border-sky-300 bg-gray-950" : "border-primary"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<form className={`flex items-center text-lg`} onSubmit={handleSearch}>
|
||||||
|
{isLoading || results.length > 0 ? (
|
||||||
|
<span className="text-white mr-2">Searching for</span>
|
||||||
|
) : null}
|
||||||
|
{activeInput ? (
|
||||||
|
<fieldset
|
||||||
|
className={`block w-full p-0 h-auto flex-1 overflow-hidden`}
|
||||||
|
>
|
||||||
|
{results.length > 0 ? (
|
||||||
|
<span className="text-blue-300 underline-offset-4 underline mr-[-0.5px]">
|
||||||
|
{'"'}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
<input
|
||||||
|
ref={(element) => {
|
||||||
|
if (element) {
|
||||||
|
inputRef.current = element
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className={`flex-grow inline bg-transparent text-white placeholder-gray-400 outline-none ring-none ${
|
||||||
|
results.length > 0
|
||||||
|
? `text-blue-300 p-0 underline underline-offset-4`
|
||||||
|
: "w-full p-2"
|
||||||
|
}`}
|
||||||
|
placeholder={
|
||||||
|
results.length === 0
|
||||||
|
? "Search for web3 news from the community"
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
value={query}
|
||||||
|
size={query ? query.length : 1}
|
||||||
|
style={
|
||||||
|
query
|
||||||
|
? {
|
||||||
|
width: `calc(${query.length}ch+2px)`
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
onChange={(e) => setQuery(e.target.value)}
|
||||||
|
/>
|
||||||
|
{results.length > 0 ? (
|
||||||
|
<span className="text-blue-300 underline-offset-4 underline ml-[-5.5px]">
|
||||||
|
{'"'}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
""
|
||||||
|
)}
|
||||||
|
</fieldset>
|
||||||
|
) : (
|
||||||
|
<span
|
||||||
|
className="block w-full flex-1 text-blue-300"
|
||||||
|
onClick={() => {
|
||||||
|
flushSync(() => {
|
||||||
|
setActiveInput(true)
|
||||||
|
})
|
||||||
|
inputRef.current?.focus()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{'"'}
|
||||||
|
{query}
|
||||||
|
{'"'}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
{isLoading ? (
|
||||||
|
// Shadcn Loading component placeholder
|
||||||
|
<LoadingComponent />
|
||||||
|
) : (
|
||||||
|
<div className="justify-self-end w-[220px] flex">
|
||||||
|
{/* Dropdown component should be here */}
|
||||||
|
<div className="uppercase text-white text-[12px] mx-3 font-semibold">
|
||||||
|
<span>All Sites</span>
|
||||||
|
<ChevronDownIcon className="w-4 h-4 inline-block ml-2" />
|
||||||
|
</div>
|
||||||
|
{/* Dropdown component should be here */}
|
||||||
|
<div className="uppercase text-white text-[12px] mx-3 font-semibold">
|
||||||
|
<span>All Times</span>
|
||||||
|
<ChevronDownIcon className="w-4 h-4 inline-block ml-2" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{results.length > 0 && (
|
||||||
|
<>
|
||||||
|
<hr className="my-4 border-1" />
|
||||||
|
{results.map((item) => (
|
||||||
|
<div
|
||||||
|
key={item.id}
|
||||||
|
className="flex cursor-pointer flex-row items-center space-x-5 my-2 py-2 px-4 hover:bg-gray-800 rounded-md"
|
||||||
|
>
|
||||||
|
<span className="text-sm text-gray-400">
|
||||||
|
{formatDate(item.timestamp)}
|
||||||
|
</span>
|
||||||
|
<h3 className="text-md font-semibold text-white">{item.title}</h3>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<div className="mt-4 flex justify-center">
|
||||||
|
<button className="bg-secondary w-full py-7 text-white hover:bg-teal-800 transition-colors">
|
||||||
|
{results.length}+ search results for <span className="text-blue-300">{query}</span>
|
||||||
|
<ChevronRightIcon className="w-5 h-5 inline ml-2 -mt-[2px]" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Placeholder components for Shadcn
|
||||||
|
const LoadingComponent = () => {
|
||||||
|
// Replace with actual Shadcn Loading component
|
||||||
|
return <div>Loading...</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const FilterComponent = () => {
|
||||||
|
// Replace with actual Shadcn Filter component
|
||||||
|
return (
|
||||||
|
<button>
|
||||||
|
<FilterIcon className="h-5 w-5 text-white" />
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SearchBar
|
|
@ -0,0 +1,78 @@
|
||||||
|
import type { Config } from 'tailwindcss'
|
||||||
|
|
||||||
|
const config: Config = {
|
||||||
|
darkMode: ["class"],
|
||||||
|
content: [
|
||||||
|
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
|
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
|
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
container: {
|
||||||
|
center: true,
|
||||||
|
padding: "2rem",
|
||||||
|
screens: {
|
||||||
|
"2xl": "1400px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
border: "hsl(var(--border))",
|
||||||
|
input: "hsl(var(--input))",
|
||||||
|
ring: "hsl(var(--ring))",
|
||||||
|
background: "hsl(var(--background))",
|
||||||
|
foreground: "hsl(var(--foreground))",
|
||||||
|
primary: {
|
||||||
|
DEFAULT: "hsl(var(--primary))",
|
||||||
|
foreground: "hsl(var(--primary-foreground))",
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
DEFAULT: "hsl(var(--secondary))",
|
||||||
|
foreground: "hsl(var(--secondary-foreground))",
|
||||||
|
},
|
||||||
|
destructive: {
|
||||||
|
DEFAULT: "hsl(var(--destructive))",
|
||||||
|
foreground: "hsl(var(--destructive-foreground))",
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
DEFAULT: "hsl(var(--muted))",
|
||||||
|
foreground: "hsl(var(--muted-foreground))",
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
DEFAULT: "hsl(var(--accent))",
|
||||||
|
foreground: "hsl(var(--accent-foreground))",
|
||||||
|
},
|
||||||
|
popover: {
|
||||||
|
DEFAULT: "hsl(var(--popover))",
|
||||||
|
foreground: "hsl(var(--popover-foreground))",
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
DEFAULT: "hsl(var(--card))",
|
||||||
|
foreground: "hsl(var(--card-foreground))",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
lg: "var(--radius)",
|
||||||
|
md: "calc(var(--radius) - 2px)",
|
||||||
|
sm: "calc(var(--radius) - 4px)",
|
||||||
|
},
|
||||||
|
keyframes: {
|
||||||
|
"accordion-down": {
|
||||||
|
from: { height: '0' },
|
||||||
|
to: { height: "var(--radix-accordion-content-height)" },
|
||||||
|
},
|
||||||
|
"accordion-up": {
|
||||||
|
from: { height: "var(--radix-accordion-content-height)" },
|
||||||
|
to: { height: '0' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
"accordion-down": "accordion-down 0.2s ease-out",
|
||||||
|
"accordion-up": "accordion-up 0.2s ease-out",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [require('@tailwindcss/container-queries'), require("tailwindcss-animate")],
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
Loading…
Reference in New Issue