initial commit

This commit is contained in:
Mr. Algorithm 2025-09-28 23:52:33 +05:30
commit 0693aad9a7
25 changed files with 7047 additions and 0 deletions

41
.gitignore vendored Normal file
View File

@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

12
.idea/OpenStock.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/OpenStock.iml" filepath="$PROJECT_DIR$/.idea/OpenStock.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

36
README.md Normal file
View File

@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/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/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
## 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/app/building-your-application/deploying) for more details.

BIN
app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

489
app/globals.css Normal file
View File

@ -0,0 +1,489 @@
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--radius-sm: calc(var(--radius) - 4px);
--radius-md: calc(var(--radius) - 2px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
}
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.129 0.042 264.695);
--card: oklch(1 0 0);
--card-foreground: oklch(0.129 0.042 264.695);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.129 0.042 264.695);
--primary: oklch(0.208 0.042 265.755);
--primary-foreground: oklch(0.984 0.003 247.858);
--secondary: oklch(0.968 0.007 247.896);
--secondary-foreground: oklch(0.208 0.042 265.755);
--muted: oklch(0.968 0.007 247.896);
--muted-foreground: oklch(0.554 0.046 257.417);
--accent: oklch(0.968 0.007 247.896);
--accent-foreground: oklch(0.208 0.042 265.755);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.929 0.013 255.508);
--input: oklch(0.929 0.013 255.508);
--ring: oklch(0.704 0.04 256.788);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
--chart-3: oklch(0.398 0.07 227.392);
--chart-4: oklch(0.828 0.189 84.429);
--chart-5: oklch(0.769 0.188 70.08);
--sidebar: oklch(0.984 0.003 247.858);
--sidebar-foreground: oklch(0.129 0.042 264.695);
--sidebar-primary: oklch(0.208 0.042 265.755);
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
--sidebar-accent: oklch(0.968 0.007 247.896);
--sidebar-accent-foreground: oklch(0.208 0.042 265.755);
--sidebar-border: oklch(0.929 0.013 255.508);
--sidebar-ring: oklch(0.704 0.04 256.788);
}
.dark {
--background: oklch(0.129 0.042 264.695);
--foreground: oklch(0.984 0.003 247.858);
--card: oklch(0.208 0.042 265.755);
--card-foreground: oklch(0.984 0.003 247.858);
--popover: oklch(0.208 0.042 265.755);
--popover-foreground: oklch(0.984 0.003 247.858);
--primary: oklch(0.929 0.013 255.508);
--primary-foreground: oklch(0.208 0.042 265.755);
--secondary: oklch(0.279 0.041 260.031);
--secondary-foreground: oklch(0.984 0.003 247.858);
--muted: oklch(0.279 0.041 260.031);
--muted-foreground: oklch(0.704 0.04 256.788);
--accent: oklch(0.279 0.041 260.031);
--accent-foreground: oklch(0.984 0.003 247.858);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.551 0.027 264.364);
--chart-1: oklch(0.488 0.243 264.376);
--chart-2: oklch(0.696 0.17 162.48);
--chart-3: oklch(0.769 0.188 70.08);
--chart-4: oklch(0.627 0.265 303.9);
--chart-5: oklch(0.645 0.246 16.439);
--sidebar: oklch(0.208 0.042 265.755);
--sidebar-foreground: oklch(0.984 0.003 247.858);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
--sidebar-accent: oklch(0.279 0.041 260.031);
--sidebar-accent-foreground: oklch(0.984 0.003 247.858);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.551 0.027 264.364);
}
/* === CUSTOM COLOR THEME === */
@theme {
/* Extended Gray Scale */
--color-gray-900: #050505;
--color-gray-800: #141414;
--color-gray-700: #212328;
--color-gray-600: #30333A;
--color-gray-500: #9095A1;
--color-gray-400: #CCDADC;
/* Vibrant Colors */
--color-blue-600: #5862FF;
--color-yellow-400: #FDD458;
--color-yellow-500: #E8BA40;
--color-teal-400: #0FEDBE;
--color-red-500: #FF495B;
--color-orange-500: #FF8243;
--color-purple-500: #D13BFF;
}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-gray-900 text-foreground;
}
}
@layer utilities {
.container {
@apply mx-auto max-w-screen-2xl px-4 md:px-6 lg:px-8;
}
.yellow-btn {
@apply h-12 cursor-pointer bg-gradient-to-b from-yellow-400 to-yellow-500 hover:from-yellow-500 hover:to-yellow-400 text-gray-950 font-medium text-base rounded-lg shadow-lg disabled:opacity-50;
}
.home-wrapper {
@apply text-gray-400 flex-col gap-4 md:gap-10 items-center sm:items-start;
}
.home-section {
@apply w-full gap-8 grid-cols-1 md:grid-cols-2 xl:grid-cols-3;
}
.header {
@apply z-50 w-full h-[70px] bg-gray-800;
}
.header-wrapper {
@apply flex justify-between items-center px-6 py-4 text-gray-500;
}
.auth-layout {
@apply flex flex-col justify-between lg:flex-row h-screen bg-gray-900 relative overflow-hidden;
}
.auth-logo {
@apply pt-6 lg:pt-8 mb-8 lg:mb-12;
}
.auth-left-section {
@apply w-full lg:w-[45%] lg:h-screen px-6 lg:px-16 flex flex-col overflow-y-auto;
}
.auth-right-section {
@apply w-full max-lg:border-t max-lg:border-gray-600 lg:w-[55%] lg:h-screen bg-gray-800 px-6 py-4 md:p-6 lg:py-12 lg:px-18 flex flex-col justify-start;
}
.auth-blockquote {
@apply text-sm md:text-xl lg:text-2xl font-medium text-gray-400 mb-1 md:mb-6 lg:mb-8;
}
.auth-testimonial-author {
@apply text-xs md:text-lg font-bold text-gray-400 not-italic;
}
.auth-dashboard-preview {
@apply border-6 border-gray-800 left-0 hidden w-[1024px] h-auto max-w-none lg:block rounded-xl shadow-2xl;
}
.form-title {
@apply text-4xl font-bold text-gray-400 mb-10;
}
.form-label {
@apply text-sm font-medium text-gray-400;
}
.form-input {
@apply h-12 px-3 py-3 text-white text-base placeholder:text-gray-500 border-gray-600 bg-gray-800 rounded-lg focus:!border-yellow-500 focus:ring-0;
}
.select-trigger {
@apply w-full !h-12 px-3 py-3 text-base border-gray-600 bg-gray-800 text-white rounded-lg focus:!border-yellow-500 focus:ring-0;
}
.country-select-trigger {
@apply h-12 px-3 py-3 text-base w-full justify-between font-normal border-gray-600 bg-gray-800 text-gray-400 rounded-lg focus:!border-yellow-500 focus:ring-0;
}
.country-select-input {
@apply !bg-gray-800 text-gray-400 border-0 border-b border-gray-600 rounded-none focus:ring-0 placeholder:text-gray-500;
}
.country-select-empty {
@apply text-gray-500 py-6 text-center !bg-gray-800;
}
.country-select-item {
@apply text-white cursor-pointer px-3 py-2 rounded-sm bg-gray-800 hover:!bg-gray-600;
}
.footer-link {
@apply text-gray-400 font-medium hover:text-yellow-400 hover:underline transition-colors;
}
.search-text {
@apply cursor-pointer hover:text-yellow-500;
}
.search-btn {
@apply cursor-pointer px-4 py-2 w-fit flex items-center gap-2 text-sm md:text-base bg-yellow-500 hover:bg-yellow-500 text-black font-medium rounded;
}
.search-dialog {
@apply !bg-gray-800 lg:min-w-[800px] border-gray-600 fixed top-10 left-1/2 -translate-x-1/2 translate-y-10;
}
.search-field {
@apply !bg-gray-800 border-b border-gray-600 relative;
}
.search-list {
@apply !bg-gray-800 max-h-[400px];
}
.search-list-indicator {
@apply px-5 py-2
}
.search-list-empty {
@apply py-6 !bg-transparent text-center text-gray-500;
}
.search-input {
@apply !bg-gray-800 border-0 text-gray-400 placeholder:text-gray-500 focus:ring-0 text-base h-14 pr-10;
}
.search-loader {
@apply absolute right-12 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-500 animate-spin;
}
.search-count {
@apply py-2 px-4 text-sm font-medium text-gray-400 bg-gray-700 border-b border-gray-700;
}
.search-item {
@apply rounded-none my-3 px-1 w-full data-[selected=true]:bg-gray-600;
}
.search-item-link {
@apply px-2 w-full cursor-pointer border-b border-gray-600 last:border-b-0 transition-colors flex items-center gap-3;
}
.search-item-name {
@apply font-medium text-base text-gray-400;
}
.nav-list {
@apply flex flex-col sm:flex-row p-2 gap-3 sm:gap-10 font-medium;
}
.stock-details-container {
@apply w-full grid-cols-1 gap-6 xl:grid-cols-3 space-y-6 sm:space-y-8;
}
.watchlist-btn {
@apply bg-yellow-500 text-base hover:bg-yellow-500 text-gray-900 w-full rounded h-11 font-semibold cursor-pointer;
}
.watchlist-remove {
@apply bg-red-500! hover:bg-red-500! text-gray-900!
}
.watchlist-empty-container {
@apply container gap-8 flex-col items-center md:mt-10 p-6 text-center;
}
.watchlist-empty {
@apply flex flex-col items-center justify-center text-center;
}
.watchlist-star {
@apply h-16 w-16 text-gray-500 mb-4;
}
.empty-title {
@apply text-xl font-semibold text-gray-400 mb-2;
}
.empty-description {
@apply text-gray-500 mb-6 max-w-md;
}
.watchlist-container {
@apply flex flex-col-reverse lg:grid lg:grid-cols-3 gap-8;
}
.watchlist {
@apply lg:col-span-2 space-y-8;
}
.watchlist-alerts {
@apply items-start gap-6 h-full flex-col w-full lg:col-span-1;
}
.watchlist-icon-btn {
@apply w-fit cursor-pointer hover:bg-transparent! text-gray-400 hover:text-yellow-500;
}
.watchlist-icon-added {
@apply !text-yellow-500 hover:!text-yellow-600;
}
.watchlist-icon {
@apply w-8 h-8 rounded-full flex items-center justify-center bg-gray-700/50;
}
.trash-icon {
@apply h-4 w-4 text-gray-400 hover:text-red-400;
}
.star-icon {
@apply h-4 w-4;
}
.watchlist-title {
@apply text-xl md:text-2xl font-bold text-gray-100;
}
.watchlist-table {
@apply !relative overflow-hidden !w-full bg-gray-800 border !border-gray-600 !rounded-lg;
}
.table-header-row {
@apply text-gray-400 font-medium bg-gray-700 border-b border-gray-600 hover:bg-gray-700;
}
.table-header:first-child {
@apply pl-4;
}
.table-row {
@apply border-b cursor-pointer text-gray-100 border-gray-600 hover:bg-gray-700/50 transition-colors;
}
.table-cell {
@apply font-medium text-base
}
.add-alert {
@apply flex text-sm items-center whitespace-nowrap gap-1.5 px-3 w-fit py-2 text-yellow-600 border border-yellow-600/20 rounded font-medium bg-transparent hover:bg-transparent cursor-pointer transition-colors;
}
.watchlist-news {
@apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4;
}
.news-item {
@apply bg-gray-800 rounded-lg border w-full border-gray-600 p-4 duration-200 hover:border-gray-600 cursor-pointer;
}
.news-tag {
@apply inline-block w-fit px-2 py-1 mb-5 rounded bg-gray-600/60 text-green-500 text-sm font-mono font-medium;
}
.news-title {
@apply text-lg font-semibold text-gray-100 leading-tight mb-3 line-clamp-2;
}
.news-meta {
@apply flex items-center text-sm text-gray-500 mb-1;
}
.news-summary {
@apply text-gray-400 flex-1 text-base leading-relaxed mb-3 line-clamp-3;
}
.news-cta {
@apply text-sm align-bottom text-yellow-500 hover:text-gray-400;
}
.alert-dialog {
@apply bg-gray-800 border-gray-600 text-gray-400 max-w-md;
}
.alert-title {
@apply text-xl font-semibold text-gray-100;
}
.alert-list {
@apply overflow-y-auto w-full max-h-[911px] rounded-lg flex border border-gray-600 flex-col gap-4 bg-gray-800 p-3 flex-1;
}
.alert-empty {
@apply px-6 py-8 text-center text-gray-500/50;
}
.alert-item {
@apply p-4 rounded-lg bg-gray-700 border border-gray-600;
}
.alert-name {
@apply mb-2 text-lg text-yellow-500 font-semibold;
}
.alert-details {
@apply flex border-b pb-3 items-center justify-between gap-3 mb-2;
}
.alert-company {
@apply text-gray-400 text-base;
}
.alert-price {
@apply text-gray-100 font-bold;
}
.alert-actions {
@apply flex items-end justify-between;
}
.alert-update-btn {
@apply text-gray-400 rounded-full bg-transparent hover:bg-green-500/15 cursor-pointer;
}
.alert-delete-btn {
@apply text-gray-400 rounded-full hover:bg-red-600/15 bg-transparent cursor-pointer transition-colors;
}
}
/* Market News Component Styles */
.scrollbar-hide {
-ms-overflow-style: none;
scrollbar-width: none;
}
.scrollbar-hide::-webkit-scrollbar {
display: none;
}
/* TradingView Advanced Chart Widget Styles */
.tradingview-widget-container {
position: relative;
background-color: #141414 !important;
border-radius: 8px !important;
overflow: hidden !important;
}
.tv-embed-widget-wrapper__body {
background-color: #141414 !important;
}
.tradingview-widget-container__widget {
background-color: #141414 !important;
height: 100% !important;
}
.widget-stock-heatmap-container .screenerMapWrapper-BBVfGP0b {
overflow: hidden !important;
background: #141414 !important;
background-color: #141414 !important;
}
.canvasContainer-tyaAU8aH {
background: #141414 !important;
background-color: #141414 !important;
}
.tv-site-widget--bg_none {
background-color: transparent !important;
}
.tradingview-widget-copyright {
font-size: 11px;
color: #9ca3af;
text-align: center;
padding: 4px 0;
background-color: transparent;
}
.tradingview-widget-copyright a {
color: #60a5fa;
text-decoration: none;
transition: color 0.2s ease;
}
.tradingview-widget-copyright a:hover {
color: #93c5fd;
text-decoration: underline;
}
.tv-embed-widget-wrapper .tv-embed-widget-wrapper__body {
background: #141414 !important;
background-color: #141414 !important;
}
.tradingview-widget-container iframe {
background-color: #141414 !important;
width: 100% !important;
}
.custom-chart.tradingview-widget-container iframe {
border: 1px solid #30333A;
border-radius: 8px !important;
overflow: hidden !important;
}
/* Custom scrollbar that shows on hover */
.scrollbar-hide-default {
scrollbar-width: thin;
scrollbar-color: transparent transparent;
}
.scrollbar-hide-default::-webkit-scrollbar {
width: 8px;
}
.scrollbar-hide-default::-webkit-scrollbar-track {
background: transparent;
}
.scrollbar-hide-default::-webkit-scrollbar-thumb {
background-color: transparent;
border-radius: 4px;
transition: background-color 0.3s ease;
}
.scrollbar-hide-default:hover {
scrollbar-color: #30333A transparent;
}
.scrollbar-hide-default:hover::-webkit-scrollbar-thumb {
background-color: #30333A;
}
.scrollbar-hide-default::-webkit-scrollbar-thumb:hover {
background-color: #9095A1;
}

34
app/layout.tsx Normal file
View File

@ -0,0 +1,34 @@
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "OpenStock",
description: "OpenStock is an open-source alternative to expensive market platforms. Track real-time prices, set personalized alerts, and explore detailed company insights — built openly, for everyone, forever free.",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en" className="dark">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}

11
app/page.tsx Normal file
View File

@ -0,0 +1,11 @@
import React from 'react'
import {Button} from "@/components/ui/button";
const Page = () => {
return (
<div className="flex justify-center items-center h-screen">
<Button>Click Me</Button>
</div>
)
}
export default Page

22
components.json Normal file
View File

@ -0,0 +1,22 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}

58
components/ui/button.tsx Normal file
View File

@ -0,0 +1,58 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
icon: "size-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
function Button({
className,
variant,
size,
asChild = false,
...props
}: React.ComponentProps<"button"> &
VariantProps<typeof buttonVariants> & {
asChild?: boolean
}) {
const Comp = asChild ? Slot : "button"
return (
<Comp
data-slot="button"
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
)
}
export { Button, buttonVariants }

25
eslint.config.mjs Normal file
View File

@ -0,0 +1,25 @@
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
{
ignores: [
"node_modules/**",
".next/**",
"out/**",
"build/**",
"next-env.d.ts",
],
},
];
export default eslintConfig;

6
lib/utils.ts Normal file
View File

@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

7
next.config.ts Normal file
View File

@ -0,0 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
};
export default nextConfig;

6188
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

33
package.json Normal file
View File

@ -0,0 +1,33 @@
{
"name": "signalist",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev --turbopack",
"build": "next build --turbopack",
"start": "next start",
"lint": "eslint"
},
"dependencies": {
"@radix-ui/react-slot": "^1.2.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-react": "^0.544.0",
"next": "15.5.4",
"react": "19.1.0",
"react-dom": "19.1.0",
"tailwind-merge": "^3.3.1"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "15.5.4",
"tailwindcss": "^4",
"tw-animate-css": "^1.4.0",
"typescript": "^5"
}
}

5
postcss.config.mjs Normal file
View File

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

View File

@ -0,0 +1,9 @@
<svg width="130" height="30" viewBox="0 0 130 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28 8.70898L26.7593 12.9707L25.9672 12.1805L21.7839 16.1318L18.7806 18.9683L16.3251 21.2873L14.0129 18.9683L12.9229 17.8747L11.5739 16.5207L11.1695 16.1158L8.95471 13.893L8.10371 14.7154L7.81883 14.9901L6.46975 16.296L5.11698 17.6035L3.72379 18.9504L3.70539 18.9683L1.71118 20.8948L0 22.5503L2.72392 18.9683L6.46975 14.0393L7.81883 12.2661L8.98595 10.7301L11.5739 13.3275L12.6803 14.4389L12.9229 14.6815L16.3747 18.1423L16.6798 17.8533L18.0289 16.5796L18.6281 16.0141L20.3723 14.3658L21.7839 13.0332L24.3718 10.5892L23.5778 9.79892L28 8.70898Z" fill="#2DFF34"/>
<path d="M6.46975 8.70898V14.0393L2.72392 18.9683H2.71289V8.70898H6.46975Z" fill="#FFCE5F"/>
<path d="M27.1545 16.0142C27.1545 23.726 20.6921 30.0001 12.7446 30.0001C8.69002 30.0001 4.91844 28.3464 2.25154 25.5992C1.72587 25.0587 1.24431 24.4771 0.810547 23.8563L2.46658 22.2561L5.12983 19.6855L5.87054 18.9684L6.46973 18.3904L7.81881 17.0846L8.11656 16.7974L8.82052 16.1159L8.93446 16.0035L8.9363 16.0053L8.99878 15.9447L11.5738 18.5278L12.6931 19.6517L16.3857 23.3568L18.639 21.2269L20.3851 19.5803L21.0321 18.9684L21.7838 18.2584L24.3827 15.802L16.3378 26.5019L11.1804 21.3303L8.96566 19.1075L8.11652 19.9282L5.12979 22.8163L3.87444 24.0311C6.11864 26.3699 9.31122 27.7791 12.7446 27.7791C19.4294 27.7791 24.8662 22.5024 24.8662 16.0143H27.1545V16.0142Z" fill="#00B7FF"/>
<path d="M11.5739 5.60327V13.3276L8.98597 10.7302L7.81885 12.2661V5.60327H11.5739Z" fill="#FFCE5F"/>
<path d="M16.6797 3.08618V17.8534L16.3746 18.1424L12.9229 14.6816V3.08618H16.6797Z" fill="#FFCE5F"/>
<path d="M21.7838 0V13.0333L20.3722 14.3658L18.628 16.0142L18.0288 16.5797V0H21.7838Z" fill="#FFCE5F"/>
<path d="M43.812 24.384C39.324 24.384 35.94 22.104 35.94 18.168H40.308C40.308 20.16 41.82 20.904 43.764 20.904C45.372 20.904 46.188 20.256 46.188 19.368C46.188 17.904 44.484 17.52 42.108 16.8C39.132 15.888 36.468 14.736 36.468 11.664C36.468 7.92 39.396 6.456 43.092 6.456C47.1 6.456 50.244 8.568 50.364 12.048H45.996C45.804 10.728 44.748 9.936 43.092 9.936C41.796 9.936 40.884 10.368 40.884 11.352C40.884 12.504 41.844 12.888 44.028 13.536C47.268 14.496 50.604 15.408 50.604 18.96C50.604 22.248 48.108 24.384 43.812 24.384ZM55.7019 10.248H51.8619V6.84H55.7019V10.248ZM55.7019 24H51.8619V11.712H55.7019V24ZM65.6631 12.936V11.712H69.5031V22.536C69.5031 26.928 67.1271 28.392 63.3591 28.392C59.5431 28.392 57.7671 26.376 57.3351 24.408H61.2231C61.4631 25.08 62.0151 25.632 63.3591 25.632C65.0871 25.632 65.6631 24.72 65.6631 22.536V21.816H65.6151C65.1351 22.464 64.0551 23.424 62.2551 23.424C59.1111 23.424 57.0951 20.928 57.0951 17.376C57.0951 13.824 59.1111 11.328 62.2551 11.328C64.0551 11.328 65.1351 12.288 65.6151 12.936H65.6631ZM63.3111 20.544C64.8711 20.544 65.5911 19.368 65.5911 17.376C65.5911 15.384 64.8711 14.208 63.3111 14.208C61.7511 14.208 61.0311 15.384 61.0311 17.376C61.0311 19.368 61.7511 20.544 63.3111 20.544ZM79.2707 11.328C81.6467 11.328 83.2547 12.888 83.2547 15.696V24H79.4147V16.92C79.4147 15.072 78.7667 14.448 77.4947 14.448C76.0307 14.448 75.1907 15.192 75.1907 16.896V24H71.3507V11.712H75.1907V13.488H75.2387C75.8867 12.36 77.0867 11.328 79.2707 11.328ZM88.464 24.384C86.064 24.384 84.552 22.968 84.552 20.784C84.552 18.24 86.64 17.256 89.256 16.704C90.6 16.416 92.496 16.224 92.496 15C92.496 14.328 91.968 13.896 90.864 13.896C89.448 13.896 88.8 14.472 88.68 15.672H85.032C85.152 13.32 86.88 11.304 91.032 11.304C94.368 11.304 96.216 12.648 96.216 16.416V21.168C96.216 21.816 96.288 22.104 96.672 22.104C96.768 22.104 96.84 22.104 96.984 22.08V23.904C96.216 24.048 95.424 24.12 94.872 24.12C93.336 24.12 92.76 23.544 92.568 22.512H92.52C91.656 23.592 90.24 24.384 88.464 24.384ZM90.072 21.744C91.608 21.744 92.496 20.448 92.496 19.032V18C91.992 18.192 91.416 18.336 90.408 18.576C88.992 18.912 88.488 19.512 88.488 20.376C88.488 21.312 89.088 21.744 90.072 21.744ZM102.203 24H98.3629V6.84H102.203V24ZM107.916 10.248H104.076V6.84H107.916V10.248ZM107.916 24H104.076V11.712H107.916V24ZM115.237 24.384C110.941 24.384 109.261 22.32 109.165 19.92H112.765C112.885 21.144 113.701 21.744 115.165 21.744C116.293 21.744 116.797 21.384 116.797 20.688C116.797 19.584 115.573 19.464 113.797 19.056C111.637 18.552 109.405 17.688 109.405 15.192C109.405 12.888 111.325 11.328 114.781 11.328C118.717 11.328 120.253 13.32 120.373 15.48H116.773C116.653 14.496 116.125 13.968 114.853 13.968C113.797 13.968 113.341 14.352 113.341 14.952C113.341 15.768 114.061 15.816 115.909 16.248C118.333 16.824 120.733 17.544 120.733 20.4C120.733 22.968 118.789 24.384 115.237 24.384ZM127.902 21.36C128.262 21.36 128.478 21.336 128.934 21.264V23.976C128.118 24.168 127.422 24.24 126.654 24.24C123.966 24.24 122.814 23.016 122.814 20.016V14.592H121.11V11.712H122.814V8.28H126.654V11.712H128.79V14.592H126.654V19.92C126.654 21.24 127.158 21.36 127.902 21.36Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -0,0 +1,16 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_9825_21086)">
<path d="M9.53834 1.60996C9.70914 1.19932 10.2909 1.19932 10.4617 1.60996L12.5278 6.57744C12.5998 6.75056 12.7626 6.86885 12.9495 6.88383L18.3123 7.31376C18.7556 7.3493 18.9354 7.90256 18.5976 8.19189L14.5117 11.6919C14.3693 11.8139 14.3071 12.0053 14.3506 12.1876L15.5989 17.4208C15.7021 17.8534 15.2315 18.1954 14.8519 17.9635L10.2606 15.1592C10.1006 15.0615 9.89938 15.0615 9.73937 15.1592L5.14806 17.9635C4.76851 18.1954 4.29788 17.8534 4.40108 17.4208L5.64939 12.1876C5.69289 12.0053 5.6307 11.8139 5.48831 11.6919L1.40241 8.19189C1.06464 7.90256 1.24441 7.3493 1.68773 7.31376L7.05054 6.88383C7.23744 6.86885 7.40024 6.75056 7.47225 6.57744L9.53834 1.60996Z" fill="#CCDADC"/>
<g clip-path="url(#clip1_9825_21086)">
<path d="M9.53834 1.60996C9.70914 1.19932 10.2909 1.19932 10.4617 1.60996L12.5278 6.57744C12.5998 6.75056 12.7626 6.86885 12.9495 6.88383L18.3123 7.31376C18.7556 7.3493 18.9354 7.90256 18.5976 8.19189L14.5117 11.6919C14.3693 11.8139 14.3071 12.0053 14.3506 12.1876L15.5989 17.4208C15.7021 17.8534 15.2315 18.1954 14.8519 17.9635L10.2606 15.1592C10.1006 15.0615 9.89938 15.0615 9.73937 15.1592L5.14806 17.9635C4.76851 18.1954 4.29788 17.8534 4.40108 17.4208L5.64939 12.1876C5.69289 12.0053 5.6307 11.8139 5.48831 11.6919L1.40241 8.19189C1.06464 7.90256 1.24441 7.3493 1.68773 7.31376L7.05054 6.88383C7.23744 6.86885 7.40024 6.75056 7.47225 6.57744L9.53834 1.60996Z" fill="#CCDADC"/>
</g>
</g>
<defs>
<clipPath id="clip0_9825_21086">
<rect width="20" height="20" fill="white"/>
</clipPath>
<clipPath id="clip1_9825_21086">
<rect width="20" height="20" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

27
tsconfig.json Normal file
View File

@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "ES2017",
"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": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}