diff options
| author | Bobby <[email protected]> | 2022-11-30 23:16:07 -0500 |
|---|---|---|
| committer | Bobby <[email protected]> | 2022-11-30 23:16:07 -0500 |
| commit | daaa789068cebb5fdfcea6197ade6e663be46e0f (patch) | |
| tree | 1cd315851b779ac28fe622da332c3c16fe1c433c /pages | |
| download | tcssocialify-daaa789068cebb5fdfcea6197ade6e663be46e0f.tar.xz tcssocialify-daaa789068cebb5fdfcea6197ade6e663be46e0f.zip | |
socialify update
Diffstat (limited to 'pages')
| -rw-r--r-- | pages/404.tsx | 13 | ||||
| -rw-r--r-- | pages/[_owner]/[_name].tsx | 7 | ||||
| -rw-r--r-- | pages/_app.tsx | 85 | ||||
| -rw-r--r-- | pages/api/graphql.ts | 49 | ||||
| -rw-r--r-- | pages/api/image.ts | 18 | ||||
| -rw-r--r-- | pages/api/png.ts | 35 | ||||
| -rw-r--r-- | pages/api/stats.svg.ts | 45 | ||||
| -rw-r--r-- | pages/api/stats.ts | 42 | ||||
| -rw-r--r-- | pages/api/svg.ts | 39 | ||||
| -rw-r--r-- | pages/index.tsx | 7 |
10 files changed, 340 insertions, 0 deletions
diff --git a/pages/404.tsx b/pages/404.tsx new file mode 100644 index 0000000..f1ccaab --- /dev/null +++ b/pages/404.tsx @@ -0,0 +1,13 @@ +import Error from '../src/components/error/error' + +const HomePage = () => { + return ( + <Error + code="404" + title="Page not found." + description="Sorry, we couldn't find the page you're looking for." + /> + ) +} + +export default HomePage diff --git a/pages/[_owner]/[_name].tsx b/pages/[_owner]/[_name].tsx new file mode 100644 index 0000000..6ea6e06 --- /dev/null +++ b/pages/[_owner]/[_name].tsx @@ -0,0 +1,7 @@ +import MainRenderer from '../../src/components/mainRenderer' + +const RepoPage = () => { + return <MainRenderer /> +} + +export default RepoPage diff --git a/pages/_app.tsx b/pages/_app.tsx new file mode 100644 index 0000000..30997d3 --- /dev/null +++ b/pages/_app.tsx @@ -0,0 +1,85 @@ +import App from 'next/app' +import Head from 'next/head' +import Script from 'next/script' +import { Toaster } from 'react-hot-toast' +import { Analytics } from '@vercel/analytics/react' + +import { HOST_PREFIX } from '../common/helpers' + +import '../styles/global.css' + +import HeaderElement from '../src/components/header/header' +import FooterElement from '../src/components/footer/footer' + +const GoogleTagManager = () => { + if (process.env.GTM_ID) { + return ( + <> + <Script + src={`https://www.googletagmanager.com/gtag/js?id=${process.env.GTM_ID}`} + strategy="afterInteractive" + /> + <Script id="google-analytics"> + {` + window.dataLayer = window.dataLayer || []; + function gtag(){window.dataLayer.push(arguments);} + gtag('js', new Date()); + + gtag('config', '${process.env.GTM_ID}'); + `} + </Script> + </> + ) + } + + return ( + <Script id="google-analytics"> + {` + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + `} + </Script> + ) +} + +export default class MyApp extends App { + public render() { + const { Component, pageProps } = this.props + + return ( + <> + <Head> + <meta + name="viewport" + content="width=device-width,initial-scale=1,minimal-ui,maximum-scale=1,user-scalable=no" + /> + <meta name="theme-color" content="#000000" /> + <meta + name="description" + content="💞 Socialify your project. 🌐 Share with the world!" + /> + <meta + property="og:image" + content={`${HOST_PREFIX}/assets/socialify.png`} + /> + <meta property="og:image:type" content="image/png" /> + <meta property="og:image:width" content="1280" /> + <meta property="og:image:height" content="640" /> + <link rel="apple-touch-icon" href="/assets/logo192.png" /> + <link rel="manifest" href="/manifest.json" /> + <title>Socialify - That Computer Scientist Fork</title> + {GoogleTagManager()} + </Head> + <div className="flex flex-col min-h-screen bg-gradient-to-r from-[#231e43] via-[#191630] to-[#15103e]"> + <HeaderElement /> + <div className="flex-1 flex"> + <Component {...pageProps} /> + </div> + <FooterElement /> + <Toaster /> + <Analytics /> + </div> + </> + ) + } +} diff --git a/pages/api/graphql.ts b/pages/api/graphql.ts new file mode 100644 index 0000000..92c3eff --- /dev/null +++ b/pages/api/graphql.ts @@ -0,0 +1,49 @@ +import type { NextRequest } from 'next/server' + +const API_ENDPOINT = 'https://api.github.com/graphql' + +const graphQLEndpoint = async (req: NextRequest) => { + if (req.method !== 'POST') { + return new Response('Method Not Allowed', { + status: 405, + headers: { + 'cache-control': 'max-age=0, public' + } + }) + } + + const response = await fetch(API_ENDPOINT, { + method: 'POST', + headers: { + Accept: 'application/json', + Authorization: `bearer ${process.env.GITHUB_TOKEN}`, + 'content-type': 'application/json' + }, + body: req.body + }) + + if (!response.ok) { + return new Response(await response.text(), { + status: response.status, + headers: { + 'cache-control': 'public, max-age=0' + } + }) + } + + const text = await response.text() + return new Response(text, { + status: 200, + headers: { + 'content-type': 'application/json', + 'cache-control': + 'public, immutable, no-transform, max-age=60, s-maxage=600' + } + }) +} + +export const config = { + runtime: 'experimental-edge' +} + +export default graphQLEndpoint diff --git a/pages/api/image.ts b/pages/api/image.ts new file mode 100644 index 0000000..122599e --- /dev/null +++ b/pages/api/image.ts @@ -0,0 +1,18 @@ +import { isBot } from 'next/dist/server/web/spec-extension/user-agent' +import type { NextRequest } from 'next/server' +import pngEndpoint from './png' +import svgEndpoint from './svg' + +const imageEndpoint = async (req: NextRequest) => { + if (isBot(req.headers.get('user-agent') ?? '')) { + return pngEndpoint(req) + } else { + return svgEndpoint(req) + } +} + +export const config = { + runtime: 'experimental-edge' +} + +export default imageEndpoint diff --git a/pages/api/png.ts b/pages/api/png.ts new file mode 100644 index 0000000..dc9883b --- /dev/null +++ b/pages/api/png.ts @@ -0,0 +1,35 @@ +import type { NextRequest } from 'next/server' + +import QueryType from '../../common/types/queryType' +import renderCardPNG from '../../common/renderPNG' + +const pngEndpoint = async (req: NextRequest) => { + const { searchParams } = new URL(req.url) + const query = Object.fromEntries(searchParams) as QueryType + + try { + return renderCardPNG(query, { + headers: { + 'cache-control': `public, immutable, no-transform, max-age=0, s-maxage=${ + searchParams.has('cache') ? searchParams.get('cache') : 3600 + }` + } + }) + } catch (ex) { + console.error(ex) + + return new Response(JSON.stringify({ error: ex }), { + status: 400, + headers: { + 'content-type': 'application/json', + 'cache-control': 'public, max-age=0' + } + }) + } +} + +export const config = { + runtime: 'experimental-edge' +} + +export default pngEndpoint diff --git a/pages/api/stats.svg.ts b/pages/api/stats.svg.ts new file mode 100644 index 0000000..df95a89 --- /dev/null +++ b/pages/api/stats.svg.ts @@ -0,0 +1,45 @@ +import type { NextRequest } from 'next/server' +import { badgen } from 'badgen' +import statsEndpoint from './stats' + +const statsSvgEndpoint = async (req: NextRequest) => { + let totalCount = 0 + + try { + const apiResponse = await (await statsEndpoint(req)).json() + if (apiResponse.total_count) { + totalCount = apiResponse.total_count + } + } catch (ex) { + console.error(ex) + } + + const svg = totalCount + ? badgen({ + subject: '', + status: `${totalCount} repositories`, + color: 'black', + style: 'flat' + }) + : badgen({ + subject: '', + status: `thousands of repositories`, + color: 'black', + style: 'flat' + }) + + return new Response(svg, { + status: 200, + headers: { + 'content-type': 'image/svg+xml', + 'cache-control': + 'public, immutable, no-transform, max-age=60, s-maxage=86400' + } + }) +} + +export const config = { + runtime: 'experimental-edge' +} + +export default statsSvgEndpoint diff --git a/pages/api/stats.ts b/pages/api/stats.ts new file mode 100644 index 0000000..d557939 --- /dev/null +++ b/pages/api/stats.ts @@ -0,0 +1,42 @@ +import type { NextRequest } from 'next/server' + +const statsEndpoint = async (req: NextRequest) => { + const response = await fetch( + `https://api.github.com/search/code?per_page=1&q=${encodeURIComponent( + 'socialify.git.ci' + )}`, + { + method: 'GET', + headers: { + Accept: 'application/vnd.github.v3+json', + Authorization: `bearer ${process.env.GITHUB_TOKEN}`, + 'content-type': 'application/json' + } + } + ) + + if (!response.ok) { + return new Response(await response.text(), { + status: response.status, + headers: { + 'cache-control': 'public, max-age=0' + } + }) + } + + const json = await response.json() + return new Response(JSON.stringify({ total_count: json.total_count }), { + status: 200, + headers: { + 'content-type': 'application/json', + 'cache-control': + 'public, immutable, no-transform, max-age=60, s-maxage=86400' + } + }) +} + +export const config = { + runtime: 'experimental-edge' +} + +export default statsEndpoint diff --git a/pages/api/svg.ts b/pages/api/svg.ts new file mode 100644 index 0000000..a803e9b --- /dev/null +++ b/pages/api/svg.ts @@ -0,0 +1,39 @@ +import type { NextRequest } from 'next/server' + +import QueryType from '../../common/types/queryType' +import renderCardSVG from '../../common/renderSVG' + +const svgEndpoint = async (req: NextRequest) => { + const { searchParams } = new URL(req.url) + const query = Object.fromEntries(searchParams) as QueryType + + try { + const svg = await renderCardSVG(query) + + return new Response(svg, { + status: 200, + headers: { + 'content-type': 'image/svg+xml', + 'cache-control': `public, immutable, no-transform, max-age=0, s-maxage=${ + searchParams.has('cache') ? searchParams.get('cache') : 3600 + }` + } + }) + } catch (ex) { + console.error(ex) + + return new Response(JSON.stringify({ error: ex }), { + status: 400, + headers: { + 'content-type': 'application/json', + 'cache-control': 'public, max-age=0' + } + }) + } +} + +export const config = { + runtime: 'experimental-edge' +} + +export default svgEndpoint diff --git a/pages/index.tsx b/pages/index.tsx new file mode 100644 index 0000000..dce81a1 --- /dev/null +++ b/pages/index.tsx @@ -0,0 +1,7 @@ +import Repo from '../src/components/repo/repo' + +const HomePage = () => { + return <Repo /> +} + +export default HomePage |
