first commit
This commit is contained in:
parent
4cfe8463ee
commit
6acf6e8635
3
.env-example
Normal file
3
.env-example
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
TRIGGER_API_KEY=set me
|
||||||
|
TRIGGER_API_URL=https://trigger.example.com
|
||||||
|
NEXT_PUBLIC_TRIGGER_PUBLIC_API_KEY=set me
|
@ -1,4 +1,15 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {}
|
const nextConfig = {
|
||||||
|
images: {
|
||||||
|
remotePatterns: [
|
||||||
|
{
|
||||||
|
protocol: "https",
|
||||||
|
hostname: "cdn.fascinated.cc",
|
||||||
|
port: "",
|
||||||
|
pathname: "/**",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig;
|
||||||
|
113
package-lock.json
generated
113
package-lock.json
generated
@ -8,6 +8,8 @@
|
|||||||
"name": "scoresaber-reloadedv2",
|
"name": "scoresaber-reloadedv2",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@heroicons/react": "^2.0.18",
|
||||||
|
"clsx": "^2.0.0",
|
||||||
"next": "13.5.5",
|
"next": "13.5.5",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18"
|
"react-dom": "^18"
|
||||||
@ -16,11 +18,13 @@
|
|||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"autoprefixer": "^10",
|
"autoprefixer": "^10.4.16",
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "13.5.5",
|
"eslint-config-next": "13.5.5",
|
||||||
"postcss": "^8",
|
"postcss": "^8.4.31",
|
||||||
"tailwindcss": "^3",
|
"prettier": "^3.0.3",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.5.6",
|
||||||
|
"tailwindcss": "^3.3.3",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -113,6 +117,14 @@
|
|||||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@heroicons/react": {
|
||||||
|
"version": "2.0.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz",
|
||||||
|
"integrity": "sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">= 16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@humanwhocodes/config-array": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.11",
|
"version": "0.11.11",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
||||||
@ -1044,6 +1056,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/clsx": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@ -3362,6 +3382,93 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin/prettier.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/prettier-plugin-tailwindcss": {
|
||||||
|
"version": "0.5.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.6.tgz",
|
||||||
|
"integrity": "sha512-2Xgb+GQlkPAUCFi3sV+NOYcSI5XgduvDBL2Zt/hwJudeKXkyvRS65c38SB0yb9UB40+1rL83I6m0RtlOQ8eHdg==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.21.3"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@ianvs/prettier-plugin-sort-imports": "*",
|
||||||
|
"@prettier/plugin-pug": "*",
|
||||||
|
"@shopify/prettier-plugin-liquid": "*",
|
||||||
|
"@shufo/prettier-plugin-blade": "*",
|
||||||
|
"@trivago/prettier-plugin-sort-imports": "*",
|
||||||
|
"prettier": "^3.0",
|
||||||
|
"prettier-plugin-astro": "*",
|
||||||
|
"prettier-plugin-css-order": "*",
|
||||||
|
"prettier-plugin-import-sort": "*",
|
||||||
|
"prettier-plugin-jsdoc": "*",
|
||||||
|
"prettier-plugin-organize-attributes": "*",
|
||||||
|
"prettier-plugin-organize-imports": "*",
|
||||||
|
"prettier-plugin-style-order": "*",
|
||||||
|
"prettier-plugin-svelte": "*"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@ianvs/prettier-plugin-sort-imports": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@prettier/plugin-pug": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@shopify/prettier-plugin-liquid": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@shufo/prettier-plugin-blade": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@trivago/prettier-plugin-sort-imports": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-astro": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-css-order": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-import-sort": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-jsdoc": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-marko": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-organize-attributes": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-organize-imports": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-style-order": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-svelte": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"prettier-plugin-twig-melody": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prop-types": {
|
"node_modules/prop-types": {
|
||||||
"version": "15.8.1",
|
"version": "15.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||||
|
22
package.json
22
package.json
@ -9,19 +9,29 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@heroicons/react": "^2.0.18",
|
||||||
|
"clsx": "^2.0.0",
|
||||||
|
"next": "13.5.5",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"next": "13.5.5"
|
"@trigger.dev/sdk": "^2.2.0",
|
||||||
|
"@trigger.dev/nextjs": "^2.2.0",
|
||||||
|
"@trigger.dev/react": "^2.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5",
|
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
"autoprefixer": "^10",
|
"autoprefixer": "^10.4.16",
|
||||||
"postcss": "^8",
|
|
||||||
"tailwindcss": "^3",
|
|
||||||
"eslint": "^8",
|
"eslint": "^8",
|
||||||
"eslint-config-next": "13.5.5"
|
"eslint-config-next": "13.5.5",
|
||||||
|
"postcss": "^8.4.31",
|
||||||
|
"prettier": "^3.0.3",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.5.6",
|
||||||
|
"tailwindcss": "^3.3.3",
|
||||||
|
"typescript": "^5"
|
||||||
|
},
|
||||||
|
"trigger.dev": {
|
||||||
|
"endpointId": "scoresaber-reloaded-3SPH"
|
||||||
}
|
}
|
||||||
}
|
}
|
3
prettier.config.js
Normal file
3
prettier.config.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: ["prettier-plugin-tailwindcss"],
|
||||||
|
};
|
18
src/app/api/player/add/route.ts
Normal file
18
src/app/api/player/add/route.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { triggerClient } from "@/trigger";
|
||||||
|
|
||||||
|
export async function GET(request: Request) {
|
||||||
|
const { searchParams } = new URL(request.url);
|
||||||
|
const id = searchParams.get("id");
|
||||||
|
if (!id) {
|
||||||
|
return Response.json({ message: "No player provided" });
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerClient.sendEvent({
|
||||||
|
name: "user.add",
|
||||||
|
payload: {
|
||||||
|
id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return Response.json({ message: "Hello from Next.js!" });
|
||||||
|
}
|
7
src/app/api/trigger/route.ts
Normal file
7
src/app/api/trigger/route.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { triggerClient } from "@/trigger";
|
||||||
|
import { createAppRoute } from "@trigger.dev/nextjs";
|
||||||
|
|
||||||
|
import "@/jobs";
|
||||||
|
|
||||||
|
//this route is used to send and receive data with Trigger.dev
|
||||||
|
export const { POST, dynamic } = createAppRoute(triggerClient);
|
@ -1,22 +1,24 @@
|
|||||||
import type { Metadata } from 'next'
|
import type { Metadata } from "next";
|
||||||
import { Inter } from 'next/font/google'
|
import { Inter } from "next/font/google";
|
||||||
import './globals.css'
|
import "./globals.css";
|
||||||
|
|
||||||
const inter = Inter({ subsets: ['latin'] })
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Create Next App',
|
title: {
|
||||||
description: 'Generated by create next app',
|
template: "Scoresaber Reloaded - %s",
|
||||||
}
|
default: "Scoresaber Reloaded",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<body className={inter.className}>{children}</body>
|
<body className={inter.className}>{children}</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
113
src/app/page.tsx
113
src/app/page.tsx
@ -1,113 +0,0 @@
|
|||||||
import Image from 'next/image'
|
|
||||||
|
|
||||||
export default function Home() {
|
|
||||||
return (
|
|
||||||
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
|
||||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
|
||||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
|
||||||
Get started by editing
|
|
||||||
<code className="font-mono font-bold">src/app/page.tsx</code>
|
|
||||||
</p>
|
|
||||||
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
|
||||||
<a
|
|
||||||
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
|
||||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
By{' '}
|
|
||||||
<Image
|
|
||||||
src="/vercel.svg"
|
|
||||||
alt="Vercel Logo"
|
|
||||||
className="dark:invert"
|
|
||||||
width={100}
|
|
||||||
height={24}
|
|
||||||
priority
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
|
|
||||||
<Image
|
|
||||||
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
|
||||||
src="/next.svg"
|
|
||||||
alt="Next.js Logo"
|
|
||||||
width={180}
|
|
||||||
height={37}
|
|
||||||
priority
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
|
||||||
<a
|
|
||||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
|
||||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
|
||||||
Docs{' '}
|
|
||||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
|
||||||
->
|
|
||||||
</span>
|
|
||||||
</h2>
|
|
||||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
|
||||||
Find in-depth information about Next.js features and API.
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
|
||||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
|
||||||
Learn{' '}
|
|
||||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
|
||||||
->
|
|
||||||
</span>
|
|
||||||
</h2>
|
|
||||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
|
||||||
Learn about Next.js in an interactive course with quizzes!
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
|
||||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
|
||||||
Templates{' '}
|
|
||||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
|
||||||
->
|
|
||||||
</span>
|
|
||||||
</h2>
|
|
||||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
|
||||||
Explore the Next.js 13 playground.
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
|
||||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
|
||||||
Deploy{' '}
|
|
||||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
|
||||||
->
|
|
||||||
</span>
|
|
||||||
</h2>
|
|
||||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
|
||||||
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
)
|
|
||||||
}
|
|
45
src/app/search/page.tsx
Normal file
45
src/app/search/page.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import Avatar from "@/components/Avatar";
|
||||||
|
import Container from "@/components/Container";
|
||||||
|
import { MagnifyingGlassIcon } from "@heroicons/react/24/solid";
|
||||||
|
|
||||||
|
import { Metadata } from "next";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Search",
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<main>
|
||||||
|
<Container>
|
||||||
|
<div className="mt-2 bg-neutral-800 w-full flex flex-col items-center justify-center rounded-sm">
|
||||||
|
<Avatar
|
||||||
|
className="m-6"
|
||||||
|
label="Player Avatar"
|
||||||
|
url="https://cdn.fascinated.cc/yb4fgdc1.jpg"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<p className="text-xl">Stranger</p>
|
||||||
|
<p className="text mt-2">Find a player profile</p>
|
||||||
|
|
||||||
|
<form className="mt-6 flex gap-2">
|
||||||
|
<input
|
||||||
|
className="bg-transparent text-xs outline-none min-w-[14rem] border-b"
|
||||||
|
type="text"
|
||||||
|
placeholder="Enter a name or ScoreSaber profile..."
|
||||||
|
/>
|
||||||
|
<button className="bg-blue-600 hover:opacity-80 transition-all transform-gpu rounded-md p-1">
|
||||||
|
<MagnifyingGlassIcon
|
||||||
|
className="font-black"
|
||||||
|
width={18}
|
||||||
|
height={18}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div className="mb-6"></div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
27
src/components/Avatar.tsx
Normal file
27
src/components/Avatar.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
|
import Image from "next/image";
|
||||||
|
|
||||||
|
interface AvatarProps {
|
||||||
|
label: string;
|
||||||
|
url: string;
|
||||||
|
className: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Avatar({
|
||||||
|
label = "Avatar",
|
||||||
|
url,
|
||||||
|
className,
|
||||||
|
}: AvatarProps) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Image
|
||||||
|
className={clsx("rounded-full", className)}
|
||||||
|
alt={label}
|
||||||
|
src={url}
|
||||||
|
width={150}
|
||||||
|
height={150}
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
24
src/components/Button.tsx
Normal file
24
src/components/Button.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import clsx from "clsx";
|
||||||
|
|
||||||
|
interface ButtonProps {
|
||||||
|
text: string;
|
||||||
|
url: string;
|
||||||
|
icon?: JSX.Element;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Button({ text, url, icon, className }: ButtonProps) {
|
||||||
|
return (
|
||||||
|
<a href={url}>
|
||||||
|
<p
|
||||||
|
className={clsx(
|
||||||
|
"font-md flex w-fit transform-gpu flex-row items-center gap-1 rounded-md bg-blue-500 p-1 pl-2 pr-2 transition-all hover:opacity-80",
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{icon}
|
||||||
|
{text}
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
}
|
12
src/components/Container.tsx
Normal file
12
src/components/Container.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import Navbar from "./Navbar";
|
||||||
|
|
||||||
|
export default function Container({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="md:max-w-[1200px] m-auto flex flex-col items-center justify-center">
|
||||||
|
<Navbar></Navbar>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
73
src/components/Navbar.tsx
Normal file
73
src/components/Navbar.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import {
|
||||||
|
CogIcon,
|
||||||
|
MagnifyingGlassIcon,
|
||||||
|
UserIcon,
|
||||||
|
} from "@heroicons/react/20/solid";
|
||||||
|
import { GlobeAltIcon } from "@heroicons/react/24/outline";
|
||||||
|
import Button from "./Button";
|
||||||
|
|
||||||
|
interface ButtonProps {
|
||||||
|
text: string;
|
||||||
|
icon?: JSX.Element;
|
||||||
|
href?: string;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
function NavbarButton({ text, icon, href, children }: ButtonProps) {
|
||||||
|
return (
|
||||||
|
<div className="group">
|
||||||
|
<a
|
||||||
|
className="flex w-fit transform-gpu items-center justify-center gap-1 rounded-sm p-3 transition-all hover:cursor-pointer hover:bg-blue-500"
|
||||||
|
href={href}
|
||||||
|
>
|
||||||
|
<>
|
||||||
|
{icon}
|
||||||
|
<p className="hidden xs:block">{text}</p>
|
||||||
|
</>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{children && (
|
||||||
|
<div className="absolute z-20 hidden divide-y rounded-sm bg-neutral-600 shadow-sm group-hover:flex">
|
||||||
|
<div className="p-2">{children}</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Navbar() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="flex h-fit w-full rounded-sm bg-neutral-800">
|
||||||
|
<NavbarButton text="Friends" icon={<UserIcon height={20} width={20} />}>
|
||||||
|
<p className="text-sm font-bold">No friends, add someone!</p>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
className="mt-2"
|
||||||
|
text="Search"
|
||||||
|
url="/search"
|
||||||
|
icon={<MagnifyingGlassIcon height={20} width={20} />}
|
||||||
|
/>
|
||||||
|
</NavbarButton>
|
||||||
|
<NavbarButton
|
||||||
|
text="Ranking"
|
||||||
|
icon={<GlobeAltIcon height={20} width={20} />}
|
||||||
|
href="/ranking/global"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="m-auto" />
|
||||||
|
|
||||||
|
<NavbarButton
|
||||||
|
text="Search"
|
||||||
|
icon={<MagnifyingGlassIcon height={20} width={20} />}
|
||||||
|
href="/search"
|
||||||
|
/>
|
||||||
|
<NavbarButton
|
||||||
|
text="Settings"
|
||||||
|
icon={<CogIcon height={20} width={20} />}
|
||||||
|
href="/settings"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
3
src/jobs/index.ts
Normal file
3
src/jobs/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// export all your job files here
|
||||||
|
|
||||||
|
export * from "./setupUser";
|
16
src/jobs/setupUser.ts
Normal file
16
src/jobs/setupUser.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { triggerClient } from "@/trigger";
|
||||||
|
import { eventTrigger } from "@trigger.dev/sdk";
|
||||||
|
|
||||||
|
triggerClient.defineJob({
|
||||||
|
id: "setup-user",
|
||||||
|
name: "Setup User: Add first time user to the database",
|
||||||
|
version: "0.0.1",
|
||||||
|
trigger: eventTrigger({
|
||||||
|
name: "user.add",
|
||||||
|
}),
|
||||||
|
run: async (payload, io, ctx) => {
|
||||||
|
const { id } = payload;
|
||||||
|
|
||||||
|
await io.logger.info(`Setup User: Running for ${id}`);
|
||||||
|
},
|
||||||
|
});
|
13
src/middleware.ts
Normal file
13
src/middleware.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import type { NextRequest } from "next/server";
|
||||||
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
|
export function middleware(request: NextRequest) {
|
||||||
|
// todo: make this redirect to the users profile if they have a profile selected
|
||||||
|
if (request.nextUrl.pathname == "/") {
|
||||||
|
return NextResponse.redirect(new URL("/search", request.url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
matcher: "/((?!api|_next/static|_next/image|favicon.ico).*)",
|
||||||
|
};
|
7
src/trigger.ts
Normal file
7
src/trigger.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { TriggerClient } from "@trigger.dev/sdk";
|
||||||
|
|
||||||
|
export const triggerClient = new TriggerClient({
|
||||||
|
id: "scoresaber-reloaded-3SPH",
|
||||||
|
apiKey: process.env.TRIGGER_API_KEY,
|
||||||
|
apiUrl: process.env.TRIGGER_API_URL,
|
||||||
|
});
|
@ -1,20 +1,26 @@
|
|||||||
import type { Config } from 'tailwindcss'
|
import type { Config } from "tailwindcss";
|
||||||
|
|
||||||
|
const defaultTheme = require("tailwindcss/defaultTheme");
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
content: [
|
content: [
|
||||||
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
|
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
|
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
|
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))',
|
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||||
'gradient-conic':
|
"gradient-conic":
|
||||||
'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))',
|
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
screens: {
|
||||||
|
xs: "545px",
|
||||||
|
...defaultTheme.screens,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
};
|
||||||
export default config
|
export default config;
|
||||||
|
Loading…
Reference in New Issue
Block a user