| @ -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 | ||||||
|  | 
 | ||||||
|  | # 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* | ||||||
|  | 
 | ||||||
|  | # local env files | ||||||
|  | .env*.local | ||||||
|  | 
 | ||||||
|  | # vercel | ||||||
|  | .vercel | ||||||
|  | 
 | ||||||
|  | # typescript | ||||||
|  | *.tsbuildinfo | ||||||
|  | next-env.d.ts | ||||||
| @ -0,0 +1,4 @@ | |||||||
|  | { | ||||||
|  |   "typescript.tsdk": "node_modules/typescript/lib", | ||||||
|  |   "typescript.enablePromptUseWorkspaceTsdk": true | ||||||
|  | } | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | 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 | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | 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. | ||||||
|  | 
 | ||||||
|  | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. | ||||||
|  | 
 | ||||||
|  | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. | ||||||
|  | 
 | ||||||
|  | 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,8 @@ | |||||||
|  | /** @type {import('next').NextConfig} */ | ||||||
|  | const nextConfig = { | ||||||
|  |   experimental: { | ||||||
|  |     appDir: true, | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports = nextConfig | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | { | ||||||
|  |   "name": "site", | ||||||
|  |   "version": "0.1.0", | ||||||
|  |   "private": true, | ||||||
|  |   "scripts": { | ||||||
|  |     "dev": "next dev", | ||||||
|  |     "build": "next build", | ||||||
|  |     "start": "next start -p 3002", | ||||||
|  |     "lint": "next lint" | ||||||
|  |   }, | ||||||
|  |   "dependencies": { | ||||||
|  |     "@next/font": "13.1.6", | ||||||
|  |     "@types/node": "18.13.0", | ||||||
|  |     "@types/react": "18.0.27", | ||||||
|  |     "@types/react-dom": "18.0.10", | ||||||
|  |     "eslint": "8.33.0", | ||||||
|  |     "eslint-config-next": "13.1.6", | ||||||
|  |     "mysql2": "^3.1.2", | ||||||
|  |     "next": "13.1.6", | ||||||
|  |     "react": "18.2.0", | ||||||
|  |     "react-dom": "18.2.0", | ||||||
|  |     "react-h5-audio-player": "^3.8.6", | ||||||
|  |     "react-yandex-metrika": "^2.6.0", | ||||||
|  |     "semantic-ui-css": "^2.5.0", | ||||||
|  |     "semantic-ui-react": "^2.1.4", | ||||||
|  |     "typescript": "4.9.5" | ||||||
|  |   } | ||||||
|  | } | ||||||
| After Width: | Height: | Size: 25 KiB | 
| After Width: | Height: | Size: 676 KiB | 
| After Width: | Height: | Size: 3.6 MiB | 
| After Width: | Height: | Size: 310 KiB | 
| After Width: | Height: | Size: 210 KiB | 
| After Width: | Height: | Size: 1.3 KiB | 
| After Width: | Height: | Size: 1.1 KiB | 
| After Width: | Height: | Size: 629 B | 
| @ -0,0 +1,107 @@ | |||||||
|  | :root { | ||||||
|  |   --max-width: 1100px; | ||||||
|  |   --border-radius: 12px; | ||||||
|  |   --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', | ||||||
|  |     'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', | ||||||
|  |     'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; | ||||||
|  | 
 | ||||||
|  |   --foreground-rgb: 0, 0, 0; | ||||||
|  |   --background-start-rgb: 214, 219, 220; | ||||||
|  |   --background-end-rgb: 255, 255, 255; | ||||||
|  | 
 | ||||||
|  |   --primary-glow: conic-gradient( | ||||||
|  |     from 180deg at 50% 50%, | ||||||
|  |     #16abff33 0deg, | ||||||
|  |     #0885ff33 55deg, | ||||||
|  |     #54d6ff33 120deg, | ||||||
|  |     #0071ff33 160deg, | ||||||
|  |     transparent 360deg | ||||||
|  |   ); | ||||||
|  |   --secondary-glow: radial-gradient( | ||||||
|  |     rgba(255, 255, 255, 1), | ||||||
|  |     rgba(255, 255, 255, 0) | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   --tile-start-rgb: 239, 245, 249; | ||||||
|  |   --tile-end-rgb: 228, 232, 233; | ||||||
|  |   --tile-border: conic-gradient( | ||||||
|  |     #00000080, | ||||||
|  |     #00000040, | ||||||
|  |     #00000030, | ||||||
|  |     #00000020, | ||||||
|  |     #00000010, | ||||||
|  |     #00000010, | ||||||
|  |     #00000080 | ||||||
|  |   ); | ||||||
|  | 
 | ||||||
|  |   --callout-rgb: 238, 240, 241; | ||||||
|  |   --callout-border-rgb: 172, 175, 176; | ||||||
|  |   --card-rgb: 180, 185, 188; | ||||||
|  |   --card-border-rgb: 131, 134, 135; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (prefers-color-scheme: dark) { | ||||||
|  |   :root { | ||||||
|  |     --foreground-rgb: 255, 255, 255; | ||||||
|  |     --background-start-rgb: 0, 0, 0; | ||||||
|  |     --background-end-rgb: 0, 0, 0; | ||||||
|  | 
 | ||||||
|  |     --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); | ||||||
|  |     --secondary-glow: linear-gradient( | ||||||
|  |       to bottom right, | ||||||
|  |       rgba(1, 65, 255, 0), | ||||||
|  |       rgba(1, 65, 255, 0), | ||||||
|  |       rgba(1, 65, 255, 0.3) | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     --tile-start-rgb: 2, 13, 46; | ||||||
|  |     --tile-end-rgb: 2, 5, 19; | ||||||
|  |     --tile-border: conic-gradient( | ||||||
|  |       #ffffff80, | ||||||
|  |       #ffffff40, | ||||||
|  |       #ffffff30, | ||||||
|  |       #ffffff20, | ||||||
|  |       #ffffff10, | ||||||
|  |       #ffffff10, | ||||||
|  |       #ffffff80 | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     --callout-rgb: 20, 20, 20; | ||||||
|  |     --callout-border-rgb: 108, 108, 108; | ||||||
|  |     --card-rgb: 100, 100, 100; | ||||||
|  |     --card-border-rgb: 200, 200, 200; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | * { | ||||||
|  |   box-sizing: border-box; | ||||||
|  |   padding: 0; | ||||||
|  |   margin: 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | html, | ||||||
|  | body { | ||||||
|  |   max-width: 100vw; | ||||||
|  |   overflow-x: hidden; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | body { | ||||||
|  |   color: rgb(var(--foreground-rgb)); | ||||||
|  |   background: linear-gradient( | ||||||
|  |       to bottom, | ||||||
|  |       transparent, | ||||||
|  |       rgb(var(--background-end-rgb)) | ||||||
|  |     ) | ||||||
|  |     rgb(var(--background-start-rgb)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | a { | ||||||
|  |   color: inherit; | ||||||
|  |   text-decoration: none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (prefers-color-scheme: dark) { | ||||||
|  |   html { | ||||||
|  |     color-scheme: dark; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | export default function Head() { | ||||||
|  |   return ( | ||||||
|  |     <> | ||||||
|  |       <title>Create Next App</title> | ||||||
|  |       <meta content="width=device-width, initial-scale=1" name="viewport" /> | ||||||
|  |       <meta name="description" content="Generated by create next app" /> | ||||||
|  |       <link rel="icon" href="/favicon.ico" /> | ||||||
|  |     </> | ||||||
|  |   ) | ||||||
|  | } | ||||||
| @ -0,0 +1,18 @@ | |||||||
|  | import './globals.css' | ||||||
|  | 
 | ||||||
|  | export default function RootLayout({ | ||||||
|  |   children, | ||||||
|  | }: { | ||||||
|  |   children: React.ReactNode | ||||||
|  | }) { | ||||||
|  |   return ( | ||||||
|  |     <html lang="en"> | ||||||
|  |       {/* | ||||||
|  |         <head /> will contain the components returned by the nearest parent | ||||||
|  |         head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
 | ||||||
|  |       */} | ||||||
|  |       <head /> | ||||||
|  |       <body>{children}</body> | ||||||
|  |     </html> | ||||||
|  |   ) | ||||||
|  | } | ||||||
| @ -0,0 +1,271 @@ | |||||||
|  | .main { | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   justify-content: space-between; | ||||||
|  |   align-items: center; | ||||||
|  |   padding: 6rem; | ||||||
|  |   min-height: 100vh; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .description { | ||||||
|  |   display: inherit; | ||||||
|  |   justify-content: inherit; | ||||||
|  |   align-items: inherit; | ||||||
|  |   font-size: 0.85rem; | ||||||
|  |   max-width: var(--max-width); | ||||||
|  |   width: 100%; | ||||||
|  |   z-index: 2; | ||||||
|  |   font-family: var(--font-mono); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .description a { | ||||||
|  |   display: flex; | ||||||
|  |   align-items: center; | ||||||
|  |   justify-content: center; | ||||||
|  |   gap: 0.5rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .description p { | ||||||
|  |   position: relative; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 1rem; | ||||||
|  |   background-color: rgba(var(--callout-rgb), 0.5); | ||||||
|  |   border: 1px solid rgba(var(--callout-border-rgb), 0.3); | ||||||
|  |   border-radius: var(--border-radius); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .code { | ||||||
|  |   font-weight: 700; | ||||||
|  |   font-family: var(--font-mono); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .grid { | ||||||
|  |   display: grid; | ||||||
|  |   grid-template-columns: repeat(3, minmax(33%, auto)); | ||||||
|  |   width: var(--max-width); | ||||||
|  |   max-width: 100%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card { | ||||||
|  |   padding: 1rem 1.2rem; | ||||||
|  |   border-radius: var(--border-radius); | ||||||
|  |   background: rgba(var(--card-rgb), 0); | ||||||
|  |   border: 1px solid rgba(var(--card-border-rgb), 0); | ||||||
|  |   transition: background 200ms, border 200ms; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card span { | ||||||
|  |   display: inline-block; | ||||||
|  |   transition: transform 200ms; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card h2 { | ||||||
|  |   font-weight: 600; | ||||||
|  |   margin-bottom: 0.7rem; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .card p { | ||||||
|  |   margin: 0; | ||||||
|  |   opacity: 0.6; | ||||||
|  |   font-size: 0.9rem; | ||||||
|  |   line-height: 1.5; | ||||||
|  |   max-width: 34ch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .center { | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  |   position: relative; | ||||||
|  |   padding: 4rem 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .center::before { | ||||||
|  |   background: var(--secondary-glow); | ||||||
|  |   border-radius: 50%; | ||||||
|  |   width: 480px; | ||||||
|  |   height: 360px; | ||||||
|  |   margin-left: -400px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .center::after { | ||||||
|  |   background: var(--primary-glow); | ||||||
|  |   width: 240px; | ||||||
|  |   height: 180px; | ||||||
|  |   z-index: -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .center::before, | ||||||
|  | .center::after { | ||||||
|  |   content: ''; | ||||||
|  |   left: 50%; | ||||||
|  |   position: absolute; | ||||||
|  |   filter: blur(45px); | ||||||
|  |   transform: translateZ(0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .logo, | ||||||
|  | .thirteen { | ||||||
|  |   position: relative; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .thirteen { | ||||||
|  |   display: flex; | ||||||
|  |   justify-content: center; | ||||||
|  |   align-items: center; | ||||||
|  |   width: 75px; | ||||||
|  |   height: 75px; | ||||||
|  |   padding: 25px 10px; | ||||||
|  |   margin-left: 16px; | ||||||
|  |   transform: translateZ(0); | ||||||
|  |   border-radius: var(--border-radius); | ||||||
|  |   overflow: hidden; | ||||||
|  |   box-shadow: 0px 2px 8px -1px #0000001a; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .thirteen::before, | ||||||
|  | .thirteen::after { | ||||||
|  |   content: ''; | ||||||
|  |   position: absolute; | ||||||
|  |   z-index: -1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Conic Gradient Animation */ | ||||||
|  | .thirteen::before { | ||||||
|  |   animation: 6s rotate linear infinite; | ||||||
|  |   width: 200%; | ||||||
|  |   height: 200%; | ||||||
|  |   background: var(--tile-border); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Inner Square */ | ||||||
|  | .thirteen::after { | ||||||
|  |   inset: 0; | ||||||
|  |   padding: 1px; | ||||||
|  |   border-radius: var(--border-radius); | ||||||
|  |   background: linear-gradient( | ||||||
|  |     to bottom right, | ||||||
|  |     rgba(var(--tile-start-rgb), 1), | ||||||
|  |     rgba(var(--tile-end-rgb), 1) | ||||||
|  |   ); | ||||||
|  |   background-clip: content-box; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Enable hover only on non-touch devices */ | ||||||
|  | @media (hover: hover) and (pointer: fine) { | ||||||
|  |   .card:hover { | ||||||
|  |     background: rgba(var(--card-rgb), 0.1); | ||||||
|  |     border: 1px solid rgba(var(--card-border-rgb), 0.15); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .card:hover span { | ||||||
|  |     transform: translateX(4px); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (prefers-reduced-motion) { | ||||||
|  |   .thirteen::before { | ||||||
|  |     animation: none; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .card:hover span { | ||||||
|  |     transform: none; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Mobile and Tablet */ | ||||||
|  | @media (max-width: 1023px) { | ||||||
|  |   .content { | ||||||
|  |     padding: 4rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .grid { | ||||||
|  |     grid-template-columns: 1fr; | ||||||
|  |     margin-bottom: 120px; | ||||||
|  |     max-width: 320px; | ||||||
|  |     text-align: center; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .card { | ||||||
|  |     padding: 1rem 2.5rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .card h2 { | ||||||
|  |     margin-bottom: 0.5rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .center { | ||||||
|  |     padding: 8rem 0 6rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .center::before { | ||||||
|  |     transform: none; | ||||||
|  |     height: 300px; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .description { | ||||||
|  |     font-size: 0.8rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .description a { | ||||||
|  |     padding: 1rem; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .description p, | ||||||
|  |   .description div { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     position: fixed; | ||||||
|  |     width: 100%; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .description p { | ||||||
|  |     align-items: center; | ||||||
|  |     inset: 0 0 auto; | ||||||
|  |     padding: 2rem 1rem 1.4rem; | ||||||
|  |     border-radius: 0; | ||||||
|  |     border: none; | ||||||
|  |     border-bottom: 1px solid rgba(var(--callout-border-rgb), 0.25); | ||||||
|  |     background: linear-gradient( | ||||||
|  |       to bottom, | ||||||
|  |       rgba(var(--background-start-rgb), 1), | ||||||
|  |       rgba(var(--callout-rgb), 0.5) | ||||||
|  |     ); | ||||||
|  |     background-clip: padding-box; | ||||||
|  |     backdrop-filter: blur(24px); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .description div { | ||||||
|  |     align-items: flex-end; | ||||||
|  |     pointer-events: none; | ||||||
|  |     inset: auto 0 0; | ||||||
|  |     padding: 2rem; | ||||||
|  |     height: 200px; | ||||||
|  |     background: linear-gradient( | ||||||
|  |       to bottom, | ||||||
|  |       transparent 0%, | ||||||
|  |       rgb(var(--background-end-rgb)) 40% | ||||||
|  |     ); | ||||||
|  |     z-index: 1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (prefers-color-scheme: dark) { | ||||||
|  |   .vercelLogo { | ||||||
|  |     filter: invert(1); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .logo, | ||||||
|  |   .thirteen img { | ||||||
|  |     filter: invert(1) drop-shadow(0 0 0.3rem #ffffff70); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @keyframes rotate { | ||||||
|  |   from { | ||||||
|  |     transform: rotate(360deg); | ||||||
|  |   } | ||||||
|  |   to { | ||||||
|  |     transform: rotate(0deg); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,146 @@ | |||||||
|  | "use client"; | ||||||
|  | 
 | ||||||
|  | import React, { useState, useEffect} from 'react'; | ||||||
|  | import { | ||||||
|  |   Container, | ||||||
|  |   Grid, | ||||||
|  |   Header, | ||||||
|  |   List, | ||||||
|  |   Segment, | ||||||
|  |   Label, | ||||||
|  | } from 'semantic-ui-react'; | ||||||
|  | import { Item } from 'semantic-ui-react'; | ||||||
|  | import 'semantic-ui-css/semantic.min.css'; | ||||||
|  | import AudioPlayer from 'react-h5-audio-player'; | ||||||
|  | import 'react-h5-audio-player/lib/styles.css'; | ||||||
|  | 
 | ||||||
|  | type Props = { | ||||||
|  |   id: number; | ||||||
|  |   audio: string; | ||||||
|  |   description: string; | ||||||
|  |   urlImg: string; | ||||||
|  |   title_items: string; | ||||||
|  |   children: Node; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const Views = async (e : number) =>{ | ||||||
|  |   console.log('id:',e) | ||||||
|  |     await fetch('/api/podcasts/views', {method: 'POST', body: e as any}) | ||||||
|  |     .then((data) => { | ||||||
|  |       console.log(data) | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const PodcastBlocks: React.FC<Props> = ({id, audio, description, urlImg, title_items}) => ( | ||||||
|  |   <> | ||||||
|  |   <Item> | ||||||
|  |       <Item.Image size='medium' src={'img/'+urlImg} /> | ||||||
|  |       <Item.Content> | ||||||
|  |         <Item.Header as='a'>{title_items}</Item.Header> | ||||||
|  |         <Item.Meta> | ||||||
|  |           <span className='cinema'></span> | ||||||
|  |         </Item.Meta> | ||||||
|  |         <Item.Description> | ||||||
|  |           {description} | ||||||
|  |         </Item.Description> | ||||||
|  |         <AudioPlayer | ||||||
|  |           src={"audio/"+audio} | ||||||
|  |           onPlay={e => Views(id)} | ||||||
|  |         /> | ||||||
|  |         <Item.Extra> | ||||||
|  |           <Label icon='globe' content='-' /> | ||||||
|  |         </Item.Extra> | ||||||
|  |       </Item.Content> | ||||||
|  |     </Item> | ||||||
|  |   </> | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export default function Home() { | ||||||
|  |   interface IUser { | ||||||
|  |     [x: string]: any; | ||||||
|  |     name: string; | ||||||
|  |   }; | ||||||
|  |   const [data, setData] = useState<IUser>(); | ||||||
|  |   const [isLoading, setLoading] = useState(false) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   useEffect(() => { | ||||||
|  |     setLoading(true) | ||||||
|  |     fetch('/api/podcasts/all') | ||||||
|  |       .then((res) => res.json()) | ||||||
|  |       .then((data) => { | ||||||
|  |         setData(data); | ||||||
|  |         setLoading(false); | ||||||
|  |       }) | ||||||
|  |   }, []) | ||||||
|  | 
 | ||||||
|  |   if (isLoading) return <p>Загрузка...</p> | ||||||
|  |   if (!data) return <p>Нет интернета</p> | ||||||
|  | 
 | ||||||
|  |   const podcasts = data.map((obj: JSX.IntrinsicAttributes & Props, index: React.Key | null | undefined) => <PodcastBlocks key={index} {...obj}/> ); | ||||||
|  | 
 | ||||||
|  |   return ( | ||||||
|  |     <> | ||||||
|  |     <Segment style={{ padding: '8em 0em' }} vertical> | ||||||
|  |       <Grid container stackable textAlign='center'> | ||||||
|  |         <Grid.Row> | ||||||
|  |           <Grid.Column width={12} textAlign='center'> | ||||||
|  |             <Header as='h3'  style={{ fontSize: '4em' }}> | ||||||
|  |               BlogBaster | ||||||
|  |             </Header> | ||||||
|  |             <Header as='h3' style={{ fontSize: '2em' }}> | ||||||
|  |             Увлечены. Качественно. | ||||||
|  |             За новое звучание. | ||||||
|  |             </Header> | ||||||
|  |             <p style={{ fontSize: '1.33em' }}> | ||||||
|  |             Если вы хотите стать нашим партнером или рекламодателем — пишите на podcast@blogbaster.xyz | ||||||
|  |             </p> | ||||||
|  |           </Grid.Column> | ||||||
|  |         </Grid.Row> | ||||||
|  |       </Grid> | ||||||
|  |     </Segment> | ||||||
|  |     <Segment style={{ padding: '8em 0em' }} vertical> | ||||||
|  |       <Container textAlign='left'> | ||||||
|  |         <Item.Group> | ||||||
|  |           {podcasts} | ||||||
|  |         </Item.Group> | ||||||
|  |       </Container> | ||||||
|  |     </Segment> | ||||||
|  | 
 | ||||||
|  |     <Segment inverted vertical style={{ padding: '5em 0em' }}> | ||||||
|  |       <Container> | ||||||
|  |         <Grid divided inverted stackable> | ||||||
|  |           <Grid.Row> | ||||||
|  |             <Grid.Column width={3}> | ||||||
|  |               <Header inverted as='h4' content='Социальные сети' /> | ||||||
|  |               <List link inverted> | ||||||
|  |                 <List.Item as='a'>Вконтакте</List.Item> | ||||||
|  |                 <List.Item as='a'>Telegram</List.Item> | ||||||
|  |               </List> | ||||||
|  |             </Grid.Column> | ||||||
|  |             <Grid.Column width={3}> | ||||||
|  |               <Header inverted as='h4' content='Платформы' /> | ||||||
|  |               <List link inverted> | ||||||
|  |                 <List.Item as='a'>Яндекс музыка</List.Item> | ||||||
|  |                 <List.Item as='a'>Google подкасты</List.Item> | ||||||
|  |                 <List.Item as='a'>Apple подкасты</List.Item> | ||||||
|  |               </List> | ||||||
|  |             </Grid.Column> | ||||||
|  |             <Grid.Column width={7}> | ||||||
|  |               <Header as='h4' inverted> | ||||||
|  |                 О нас | ||||||
|  |               </Header> | ||||||
|  |               <p> | ||||||
|  |                 BlogBaster 2022 | ||||||
|  |               </p> | ||||||
|  |             </Grid.Column> | ||||||
|  |           </Grid.Row> | ||||||
|  |         </Grid> | ||||||
|  |       </Container> | ||||||
|  |     </Segment> | ||||||
|  |   </> | ||||||
|  |   ) | ||||||
|  | } | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | import { writeFileSync } from "fs"; | ||||||
|  | import { getAllPosts } from "./posts"; | ||||||
|  | import RSS from "rss"; | ||||||
|  | const post = [{title:'ddee', url:'dfdf', date:'12.12.22', description:'dfdf dfdf dfdf'}] | ||||||
|  | export default async function getRSS() { | ||||||
|  |   const siteURL = "https://yourdomain.com"; | ||||||
|  |   const allBlogs = getAllPosts(); | ||||||
|  | 
 | ||||||
|  |   const feed = new RSS({ | ||||||
|  |     title: "Your Name", | ||||||
|  |     description: "your description", | ||||||
|  |     site_url: siteURL, | ||||||
|  |     feed_url: `${siteURL}/feed.xml`, | ||||||
|  |     language: "en", | ||||||
|  |     pubDate: new Date(), | ||||||
|  |     copyright: `All rights reserved ${new Date().getFullYear()}, Your Name`, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   post.map((post) => { | ||||||
|  |     feed.item({ | ||||||
|  |       title: post.title, | ||||||
|  |       url: `${siteURL}/blogs/${post.slug}`, | ||||||
|  |       date: post.date, | ||||||
|  |       description: post.excerpt, | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   writeFileSync("../../public/feed.xml", feed.xml({ indent: true })); | ||||||
|  | } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | export function getAllPosts() { | ||||||
|  |     const posts = getSlugs() | ||||||
|  |       .map((slug) => { | ||||||
|  |         return getFrontMatter(slug); | ||||||
|  |       }) | ||||||
|  |       .filter((post) => post != null || post != undefined) // Filter post if it is not published
 | ||||||
|  |       .sort((a, b) => { | ||||||
|  |         if (new Date(a.date) > new Date(b.date)) return -1; | ||||||
|  |         if (new Date(a.date) < new Date(b.date)) return 1; | ||||||
|  |         return 0; | ||||||
|  |       }); | ||||||
|  |     return posts; | ||||||
|  |   } | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | import Select from "../../../server/db/select"; | ||||||
|  | import type { NextApiRequest, NextApiResponse } from 'next'; | ||||||
|  | 
 | ||||||
|  | const sql = "SELECT items.id, urlImg,items.description, items.title_items, items.audio FROM podcasts, items WHERE podcasts.id=items.id_podcasts and items.status=1"; | ||||||
|  | 
 | ||||||
|  | export default function handler( | ||||||
|  |     req: NextApiRequest, | ||||||
|  |     res: NextApiResponse | ||||||
|  |   )   { | ||||||
|  |     Select(sql, function(data){ | ||||||
|  |         res.status(200).json(data); | ||||||
|  |     }) | ||||||
|  | } | ||||||
| @ -0,0 +1,34 @@ | |||||||
|  | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
 | ||||||
|  | import type { NextApiRequest, NextApiResponse } from 'next' | ||||||
|  | import Select from "../../../../../server/db/select"; | ||||||
|  | import Insert from "../../../../../server/db/insert"; | ||||||
|  | import { getRssXml, Items } from '../../../../../сomponents/podcasts'; | ||||||
|  | 
 | ||||||
|  | const id = 1; | ||||||
|  | 
 | ||||||
|  | const sql_company = "SELECT * FROM podcasts, company WHERE podcasts.id="+id; | ||||||
|  | const sql_items = "SELECT * FROM `podcasts`, items, company WHERE podcasts.id=items.id_podcasts and podcasts.id="+id; | ||||||
|  | 
 | ||||||
|  | const sql_userAgent = "INSERT INTO views (id_podcasts, userAgent,ip) VALUES (?,?,?)"; | ||||||
|  | 
 | ||||||
|  | export default function handler( | ||||||
|  |   req: NextApiRequest, | ||||||
|  |   res: NextApiResponse | ||||||
|  | ) { | ||||||
|  |   const views = [id, req.headers['user-agent'], req.socket.remoteAddress] | ||||||
|  |   Select(sql_company, function(data_company : any){ | ||||||
|  |     Select(sql_items, function(data_items : any){ | ||||||
|  |       res.setHeader('Content-Type', 'text/xml'); | ||||||
|  |       res.status(200).send(getRssXml(data_company[0])+data_items.map((rows : any) => Items(rows))+'</channel> </rss>'); | ||||||
|  |     }) | ||||||
|  |     
 | ||||||
|  |   }) | ||||||
|  |   Insert(sql_userAgent, views as string[], function(message){ | ||||||
|  |     console.log(message); | ||||||
|  |   }) | ||||||
|  | } 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
 | ||||||
|  | import type { NextApiRequest, NextApiResponse } from 'next' | ||||||
|  | import Select from "../../../../../server/db/select"; | ||||||
|  | import Insert from "../../../../../server/db/insert"; | ||||||
|  | import { getRssXml, Items } from '../../../../../сomponents/podcasts'; | ||||||
|  | 
 | ||||||
|  | const id = 2; | ||||||
|  | 
 | ||||||
|  | const sql_company = "SELECT * FROM podcasts, company WHERE podcasts.id="+id; | ||||||
|  | const sql_items = "SELECT * FROM `podcasts`, items, company WHERE podcasts.id=items.id_podcasts and podcasts.id="+id; | ||||||
|  | 
 | ||||||
|  | const sql_userAgent = "INSERT INTO views (id_podcasts, userAgent,ip) VALUES (?,?,?)"; | ||||||
|  | 
 | ||||||
|  | export default function handler( | ||||||
|  |   req: NextApiRequest, | ||||||
|  |   res: NextApiResponse | ||||||
|  | ) { | ||||||
|  |   const views = [id, req.headers['user-agent'], req.socket.remoteAddress] | ||||||
|  |   Select(sql_company, function(data_company : any){ | ||||||
|  |     Select(sql_items, function(data_items : any){ | ||||||
|  |       res.setHeader('Content-Type', 'text/xml'); | ||||||
|  |       res.status(200).send(getRssXml(data_company[0])+data_items.map((rows : any) => Items(rows))+'</channel> </rss>'); | ||||||
|  |     }) | ||||||
|  |     
 | ||||||
|  |   }) | ||||||
|  |   Insert(sql_userAgent, views as string[], function(message){ | ||||||
|  |     console.log(message); | ||||||
|  |   }) | ||||||
|  | } 
 | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
 | ||||||
|  | import type { NextApiRequest, NextApiResponse } from 'next' | ||||||
|  | import Select from "../../../../../server/db/select"; | ||||||
|  | import Insert from "../../../../../server/db/insert"; | ||||||
|  | import { getRssXml, Items } from '../../../../../сomponents/podcasts'; | ||||||
|  | 
 | ||||||
|  | const id = 3; | ||||||
|  | 
 | ||||||
|  | const sql_company = "SELECT * FROM podcasts, company WHERE podcasts.id="+id; | ||||||
|  | const sql_items = "SELECT * FROM `podcasts`, items, company WHERE podcasts.id=items.id_podcasts and podcasts.id="+id; | ||||||
|  | 
 | ||||||
|  | const sql_userAgent = "INSERT INTO views (id_podcasts, userAgent,ip) VALUES (?,?,?)"; | ||||||
|  | 
 | ||||||
|  | export default function handler( | ||||||
|  |   req: NextApiRequest, | ||||||
|  |   res: NextApiResponse | ||||||
|  | ) { | ||||||
|  |   const views = [id, req.headers['user-agent'], req.socket.remoteAddress] | ||||||
|  |   Select(sql_company, function(data_company : any){ | ||||||
|  |     Select(sql_items, function(data_items : any){ | ||||||
|  |       res.setHeader('Content-Type', 'text/xml'); | ||||||
|  |       res.status(200).send(getRssXml(data_company[0])+data_items.map((rows : any) => Items(rows))+'</channel> </rss>'); | ||||||
|  |     }) | ||||||
|  |     
 | ||||||
|  |   }) | ||||||
|  |   Insert(sql_userAgent, views as string[], function(message){ | ||||||
|  |     console.log(message); | ||||||
|  |   }) | ||||||
|  | } 
 | ||||||
| @ -0,0 +1,18 @@ | |||||||
|  | import type { NextApiRequest, NextApiResponse } from 'next' | ||||||
|  | import Insert from "../../../server/db/insert"; | ||||||
|  | 
 | ||||||
|  | export default function handler( | ||||||
|  |     req: NextApiRequest, | ||||||
|  |     res: NextApiResponse | ||||||
|  |   ) { | ||||||
|  |     console.log('in') | ||||||
|  |     const parm = req.body; | ||||||
|  |     console.log(parm) | ||||||
|  |     const sql_userAgent = "INSERT INTO views (id_podcasts, userAgent,ip) VALUES (?,?,?)"; | ||||||
|  |     //const views = [parm, req.headers['user-agent'], req.socket.remoteAddress]
 | ||||||
|  |     res.status(200).json(12); | ||||||
|  |     //Insert(sql_userAgent, views as string[], function(message){
 | ||||||
|  |   //    console.log(message);
 | ||||||
|  |   //  })
 | ||||||
|  |   } 
 | ||||||
|  |   
 | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | import mysql from "mysql2"; | ||||||
|  | 
 | ||||||
|  | const pool = mysql.createPool({ | ||||||
|  |     host: process.env.HOST, | ||||||
|  |     user: process.env.DATABASE, | ||||||
|  |     database: process.env.DATABASE, | ||||||
|  |     password: process.env.PASSWORD, | ||||||
|  |     waitForConnections: true, | ||||||
|  |     connectionLimit: 10, | ||||||
|  |     queueLimit: 0 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | module.exports = pool; | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | const pool = require("./connect"); | ||||||
|  | import {QueryError} from 'mysql2'; | ||||||
|  | 
 | ||||||
|  | interface definitionInterface{ | ||||||
|  |     (message:string):void; | ||||||
|  | } | ||||||
|  | export default function Insert(sql: string, argument: string[], callback: definitionInterface) { | ||||||
|  |     pool.query(sql, argument, (err: QueryError, rows: string) => { | ||||||
|  |         if (err) { | ||||||
|  |             return console.error(err.message); | ||||||
|  |         } | ||||||
|  |         pool.releaseConnection(pool); | ||||||
|  |     }); | ||||||
|  | } | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | const pool = require("./connect"); | ||||||
|  | import {QueryError} from 'mysql2'; | ||||||
|  | 
 | ||||||
|  | interface definitionInterface{ | ||||||
|  |     (message:string):void; | ||||||
|  | } | ||||||
|  | export default function Select(sql: string, callback: definitionInterface) { | ||||||
|  |     pool.query(sql, (err: QueryError, rows: string) => { | ||||||
|  |         callback(rows); | ||||||
|  |         pool.releaseConnection(pool); | ||||||
|  | }); | ||||||
|  | } | ||||||
| @ -0,0 +1,42 @@ | |||||||
|  | interface Props { | ||||||
|  |     episode: number; | ||||||
|  |     title: string; | ||||||
|  |     title_items	: string; | ||||||
|  |     description: string; | ||||||
|  |     guid: string; | ||||||
|  |     pubDate: string; | ||||||
|  |     duration: number; | ||||||
|  |     urlImg: string; | ||||||
|  |     fileSize: number; | ||||||
|  |     audio: string; | ||||||
|  |     webSite: string; | ||||||
|  |     nameCompanies: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const Items = (data: Props) => { | ||||||
|  |         let item =` | ||||||
|  |         <item> | ||||||
|  |           <itunes:episodeType>full</itunes:episodeType> | ||||||
|  |           <itunes:episode>`+data.episode+`</itunes:episode> | ||||||
|  |           <itunes:season>1</itunes:season> | ||||||
|  |           <title><![CDATA[`+data.title+': '+data.title_items	+`]]></title> | ||||||
|  |           <description><![CDATA[`+data.description+`]]></description> | ||||||
|  |           <googleplay:description>`+data.description+`</googleplay:description> | ||||||
|  |           <itunes:summary>`+data.description+`</itunes:summary> | ||||||
|  |           <guid isPermaLink="false">`+data.guid+`</guid> | ||||||
|  |           <pubDate>`+data.pubDate+`</pubDate> | ||||||
|  |           <itunes:duration>`+data.duration+`</itunes:duration> | ||||||
|  |           <link>`+data.webSite+'/podcast/'+data.guid+`</link> | ||||||
|  |           <googleplay:image href="`+data.webSite+'/img/'+data.urlImg+`"/> | ||||||
|  |           <itunes:image href="`+data.webSite+'/img/'+data.urlImg+`"/> | ||||||
|  |           <googleplay:explicit>no</googleplay:explicit> | ||||||
|  |           <itunes:explicit>false</itunes:explicit> | ||||||
|  |           <enclosure url="`+data.webSite+'/audio/'+data.audio+`" length="`+data.fileSize+`" type="audio/mpeg"/> | ||||||
|  |           <media:title>`+data.title+': '+data.title_items	+`</media:title> | ||||||
|  |           <media:content url="`+data.webSite+'/audio/'+data.audio+`" fileSize="`+data.fileSize+`" type="audio/mpeg" medium="audio" isDefault="true" expression="full" bitrate="320" channels="2" duration="`+data.duration+`" lang="ru"/> | ||||||
|  |           <media:thumbnail url="`+data.webSite+'/img/'+data.urlImg+`" width="150" height="150"/> | ||||||
|  |           <media:copyright url="`+data.webSite+`">© 2022 `+data.nameCompanies+`</media:copyright> | ||||||
|  |           <creativeCommons:license>https://creativecommons.org/licenses/by/4.0/</creativeCommons:license>
 | ||||||
|  |         </item>`;
 | ||||||
|  |       return(item) | ||||||
|  | }; | ||||||
| @ -0,0 +1,61 @@ | |||||||
|  | import { Items } from './Item' | ||||||
|  | 
 | ||||||
|  | interface Props { | ||||||
|  |     map(arg0: (rows: any) => string): unknown; | ||||||
|  |     title: string, | ||||||
|  |     atom_link: string, | ||||||
|  |     email: string, | ||||||
|  |     nameCompanies: string, | ||||||
|  |     description: string, | ||||||
|  |     webSite: string, | ||||||
|  |     urlImg: string, | ||||||
|  |     lastBuildDate: string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const getRssXml = (data: Props) => { | ||||||
|  |         let item =` | ||||||
|  |         <rss version="2.0" | ||||||
|  |           xmlns:atom="http://www.w3.org/2005/Atom" | ||||||
|  |           xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0/play-podcasts.xsd" | ||||||
|  |           xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" | ||||||
|  |           xmlns:content="http://purl.org/rss/1.0/modules/content/" | ||||||
|  |           xmlns:media="http://search.yahoo.com/mrss/" | ||||||
|  |           xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" | ||||||
|  |         > | ||||||
|  |         <channel> | ||||||
|  |             <title>`+data.title+`</title> | ||||||
|  |             <atom:link href="`+data.atom_link+`" rel="self" type="application/rss+xml"/> | ||||||
|  |             <googleplay:owner>`+data.email+`</googleplay:owner> | ||||||
|  |             <itunes:owner> | ||||||
|  |                 <itunes:name>`+data.nameCompanies+`</itunes:name> | ||||||
|  |                 <itunes:email>`+data.email+`</itunes:email> | ||||||
|  |             </itunes:owner> | ||||||
|  |             <googleplay:author>`+data.nameCompanies+`</googleplay:author> | ||||||
|  |             <itunes:author>`+data.nameCompanies+`</itunes:author> | ||||||
|  |             <description>`+data.description+`</description> | ||||||
|  |             <googleplay:description>`+data.description+`</googleplay:description> | ||||||
|  |             <itunes:summary>`+data.description+`</itunes:summary> | ||||||
|  |             <image> | ||||||
|  |                 <link>`+data.webSite+`</link> | ||||||
|  |                 <title>`+data.nameCompanies+`</title> | ||||||
|  |                 <url>`+data.webSite+'/'+data.urlImg+`</url> | ||||||
|  |             </image> | ||||||
|  |             <googleplay:image href="`+data.webSite+'/'+data.urlImg+`"/> | ||||||
|  |             <itunes:image href="`+data.webSite+'/'+data.urlImg+`"/> | ||||||
|  |             <itunes:category text="Society & Culture"> | ||||||
|  |                 <itunes:category text="Places & Travel"/> | ||||||
|  |             </itunes:category> | ||||||
|  |             <itunes:category text="Science"> | ||||||
|  |                 <itunes:category text="Social Sciences"/> | ||||||
|  |             </itunes:category> | ||||||
|  |             <language>ru</language> | ||||||
|  |             <link>`+data.webSite+`</link> | ||||||
|  |             <copyright>© 2022 `+data.nameCompanies+`</copyright> | ||||||
|  |             <itunes:type>episodic</itunes:type> | ||||||
|  |             <googleplay:explicit>no</googleplay:explicit> | ||||||
|  |             <itunes:explicit>no</itunes:explicit> | ||||||
|  |             <lastBuildDate>`+data.lastBuildDate+`</lastBuildDate> | ||||||
|  |             <googleplay:block>yes</googleplay:block>`; | ||||||
|  |       return(item) | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | export * from './Item' | ||||||
|  | export * from './getRssXml' | ||||||
| @ -0,0 +1,29 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     "target": "es5", | ||||||
|  |     "lib": ["dom", "dom.iterable", "esnext"], | ||||||
|  |     "allowJs": true, | ||||||
|  |     "skipLibCheck": true, | ||||||
|  |     "strict": true, | ||||||
|  |     "forceConsistentCasingInFileNames": true, | ||||||
|  |     "noEmit": true, | ||||||
|  |     "esModuleInterop": true, | ||||||
|  |     "module": "esnext", | ||||||
|  |     "moduleResolution": "node", | ||||||
|  |     "resolveJsonModule": true, | ||||||
|  |     "isolatedModules": true, | ||||||
|  |     "jsx": "preserve", | ||||||
|  |     "incremental": true, | ||||||
|  |     "plugins": [ | ||||||
|  |       { | ||||||
|  |         "name": "next" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "baseUrl": ".", | ||||||
|  |     "paths": { | ||||||
|  |       "@/*": ["./src/*"] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], | ||||||
|  |   "exclude": ["node_modules"] | ||||||
|  | } | ||||||