aboutsummaryrefslogtreecommitdiff
path: root/pages
diff options
context:
space:
mode:
authorBobby <[email protected]>2022-11-30 23:16:07 -0500
committerBobby <[email protected]>2022-11-30 23:16:07 -0500
commitdaaa789068cebb5fdfcea6197ade6e663be46e0f (patch)
tree1cd315851b779ac28fe622da332c3c16fe1c433c /pages
downloadtcssocialify-daaa789068cebb5fdfcea6197ade6e663be46e0f.tar.xz
tcssocialify-daaa789068cebb5fdfcea6197ade6e663be46e0f.zip
socialify update
Diffstat (limited to 'pages')
-rw-r--r--pages/404.tsx13
-rw-r--r--pages/[_owner]/[_name].tsx7
-rw-r--r--pages/_app.tsx85
-rw-r--r--pages/api/graphql.ts49
-rw-r--r--pages/api/image.ts18
-rw-r--r--pages/api/png.ts35
-rw-r--r--pages/api/stats.svg.ts45
-rw-r--r--pages/api/stats.ts42
-rw-r--r--pages/api/svg.ts39
-rw-r--r--pages/index.tsx7
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