add nextjs support

This commit is contained in:
Shreyaan 2024-09-25 13:26:21 +05:30
parent 82e50c64f0
commit d8a80e34af
16 changed files with 3580 additions and 0 deletions

3
nextjs/.eslintrc.json Normal file
View file

@ -0,0 +1,3 @@
{
"extends": ["next/core-web-vitals", "next/typescript"]
}

36
nextjs/.gitignore vendored Normal file
View file

@ -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

15
nextjs/README.md Normal file
View file

@ -0,0 +1,15 @@
## 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.

15
nextjs/next.config.mjs Normal file
View file

@ -0,0 +1,15 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "panels-cdn.imgix.net",
port: "",
pathname: "/**",
},
],
},
};
export default nextConfig;

26
nextjs/package.json Normal file
View file

@ -0,0 +1,26 @@
{
"name": "mkbsd",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"react": "^18",
"react-dom": "^18",
"next": "14.2.13"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"eslint": "^8",
"eslint-config-next": "14.2.13"
}
}

3296
nextjs/pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,8 @@
/** @type {import('postcss-load-config').Config} */
const config = {
plugins: {
tailwindcss: {},
},
};
export default config;

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

35
nextjs/src/app/layout.tsx Normal file
View file

@ -0,0 +1,35 @@
import type { Metadata } from "next";
import localFont from "next/font/local";
import "./globals.css";
const geistSans = localFont({
src: "./fonts/GeistVF.woff",
variable: "--font-geist-sans",
weight: "100 900",
});
const geistMono = localFont({
src: "./fonts/GeistMonoVF.woff",
variable: "--font-geist-mono",
weight: "100 900",
});
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">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
{children}
</body>
</html>
);
}

65
nextjs/src/app/page.tsx Normal file
View file

@ -0,0 +1,65 @@
/* eslint-disable @next/next/no-img-element */
import React from "react";
import LazyImage from "@/components/LazyImage";
async function fetchImages() {
const url =
"https://storage.googleapis.com/panels-api/data/20240916/media-1a-i-p~s";
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to fetch JSON file: ${response.statusText}`);
}
const jsonData = await response.json();
const data = jsonData.data;
if (!data) {
throw new Error('JSON does not have a "data" property at its root.');
}
const images = [];
for (const key in data) {
const subproperty = data[key];
if (subproperty && subproperty.dhd) {
images.push(subproperty.dhd);
}
}
return images;
}
function AsciiArt() {
return (
<pre className="text-xs font-mono text-gray-700 bg-gray-100 p-4 rounded-lg mb-8">
{` /$$ /$$ /$$ /$$ /$$$$$$$ /$$$$$$ /$$$$$$$
| $$$ /$$$| $$ /$$/| $$__ $$ /$$__ $$| $$__ $$
| $$$$ /$$$$| $$ /$$/ | $$ \\ $$| $$ \\__/| $$ \\ $$
| $$ $$/$$ $$| $$$$$/ | $$$$$$$ | $$$$$$ | $$ | $$
| $$ $$$| $$| $$ $$ | $$__ $$ \\____ $$| $$ | $$
| $$\\ $ | $$| $$\\ $$ | $$ \\ $$ /$$ \\ $$| $$ | $$
| $$ \\/ | $$| $$ \\ $$| $$$$$$$/| $$$$$$/| $$$$$$$/
|__/ |__/|__/ \\__/|_______/ \\______/ |_______/`}
</pre>
);
}
export default async function ImageGallery() {
const images = await fetchImages();
return (
<div className="container mx-auto px-4 py-8">
<AsciiArt />
<p className="text-lg mb-8">
🤑 Displaying images from your favorite sellout grifter&apos;s wallpaper
app...
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
{images.map((imageUrl, index) => (
<div
key={index}
className="relative h-64 rounded-lg overflow-hidden shadow-lg"
>
<LazyImage src={imageUrl} alt={`Image ${index + 1}`} />
</div>
))}
</div>
</div>
);
}

View file

@ -0,0 +1,33 @@
"use client";
import React, { useState } from "react";
import Image from "next/image";
interface LazyImageProps {
src: string;
alt: string;
}
export default function LazyImage({ src, alt }: LazyImageProps) {
const [isLoading, setIsLoading] = useState(true);
return (
<div className="relative h-full w-full">
{isLoading && (
<div className="absolute inset-0 flex items-center justify-center bg-gray-400">
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-gray-900"></div>
</div>
)}
<Image
src={src}
alt={alt}
layout="fill"
objectFit="cover"
className={`transition-opacity duration-300 ${
isLoading ? "opacity-0" : "opacity-100"
}`}
onLoadingComplete={() => setIsLoading(false)}
/>
</div>
);
}

19
nextjs/tailwind.config.ts Normal file
View file

@ -0,0 +1,19 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
},
},
},
plugins: [],
};
export default config;

26
nextjs/tsconfig.json Normal file
View file

@ -0,0 +1,26 @@
{
"compilerOptions": {
"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"]
}