mirror of
https://github.com/nadimkobeissi/mkbsd.git
synced 2024-12-23 03:05:31 +00:00
add nextjs support
This commit is contained in:
parent
82e50c64f0
commit
d8a80e34af
3
nextjs/.eslintrc.json
Normal file
3
nextjs/.eslintrc.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"extends": ["next/core-web-vitals", "next/typescript"]
|
||||||
|
}
|
36
nextjs/.gitignore
vendored
Normal file
36
nextjs/.gitignore
vendored
Normal 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
15
nextjs/README.md
Normal 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
15
nextjs/next.config.mjs
Normal 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
26
nextjs/package.json
Normal 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
3296
nextjs/pnpm-lock.yaml
Normal file
File diff suppressed because it is too large
Load diff
8
nextjs/postcss.config.mjs
Normal file
8
nextjs/postcss.config.mjs
Normal 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
BIN
nextjs/src/app/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
nextjs/src/app/fonts/GeistMonoVF.woff
Normal file
BIN
nextjs/src/app/fonts/GeistMonoVF.woff
Normal file
Binary file not shown.
BIN
nextjs/src/app/fonts/GeistVF.woff
Normal file
BIN
nextjs/src/app/fonts/GeistVF.woff
Normal file
Binary file not shown.
3
nextjs/src/app/globals.css
Normal file
3
nextjs/src/app/globals.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
35
nextjs/src/app/layout.tsx
Normal file
35
nextjs/src/app/layout.tsx
Normal 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
65
nextjs/src/app/page.tsx
Normal 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'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>
|
||||||
|
);
|
||||||
|
}
|
33
nextjs/src/components/LazyImage.tsx
Normal file
33
nextjs/src/components/LazyImage.tsx
Normal 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
19
nextjs/tailwind.config.ts
Normal 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
26
nextjs/tsconfig.json
Normal 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"]
|
||||||
|
}
|
Loading…
Reference in a new issue