Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion devcon-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"sync:pretalx": "ts-node ./src/scripts/sync-pretalx.ts",
"db:generate:all": "prisma generate --schema src/db/schema.prisma && prisma generate --schema src/db/account.prisma && yarn copy:account",
"db:generate": "yarn db:generate:all && prisma db push --schema src/db/schema.prisma --force-reset --accept-data-loss && prisma db push --schema src/db/account.prisma && prisma db seed",
"copy:account": "mkdir -p dist/db && cp src/db/clients dist/db/clients -r",
"copy:account": "mkdir -p dist/db && cp -r src/db/clients dist/db/",
"db:seed:account": "prisma db push --force-reset --accept-data-loss --schema src/db/account.prisma && ts-node src/db/account-seed",
"db:studio": "prisma studio",
"db:studio:account": "prisma studio --schema src/db/account.prisma",
Expand Down
1 change: 1 addition & 0 deletions devconnect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@splinetool/react-spline": "^2.2.6",
"@splinetool/runtime": "^0.9.402",
"@supabase/supabase-js": "^2.49.4",
"@vercel/og": "^0.6.8",
"autoprefixer": "^10.4.16",
"cross-env": "^7.0.3",
"dat.gui": "^0.7.7",
Expand Down
Binary file added devconnect/public/NotoSansSC-Regular.ttf
Binary file not shown.
Binary file added devconnect/public/RobotoCondensed-Bold.ttf
Binary file not shown.
Binary file added devconnect/public/argentina/blue-ticket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added devconnect/public/argentina/pink-ticket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added devconnect/public/argentina/yellow-ticket.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
99 changes: 99 additions & 0 deletions devconnect/src/common/components/ticket/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/* eslint-disable jsx-a11y/alt-text */
/* eslint-disable @next/next/no-img-element */
import { SITE_URL } from 'common/constants'
import React from 'react'

export const colorMap = {
blue: { primary: '#74ACDF', secondary: '#417FB8' },
yellow: { primary: '#F6B40E', secondary: '#B2820A' },
pink: { primary: '#FF85A6', secondary: '#BF4465' },
}

export const colorKeys = Object.keys(colorMap)

const isLatinOnly = (text: string): boolean => {
return /^[\u0000-\u007F\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u1E00-\u1EFF\u2C60-\u2C7F\uA720-\uA7FF\uFB00-\uFB4F]+$/.test(
text
)
}

export const Ticket = ({
name = 'Anon',
color = 'blue',
social = 'false',
}: {
name?: string
color?: string
social?: string
}) => {
if (!colorMap[color as keyof typeof colorMap]) {
return (
<div
style={{
display: 'flex',
width: '100%',
height: '100%',
position: 'relative',
top: 0,
left: 0,
}}
>
Invalid color
</div>
)
}

return (
<div
style={{
display: 'flex',
width: '100%',
height: '100%',
position: 'relative',
top: 0,
left: 0,
backgroundColor: social === 'true' ? '#36364C' : 'transparent',
}}
>
<img
style={{
display: 'flex',
position: 'absolute',
top: 0,
left: 28.5,
width: '1143px',
height: '630px',
}}
src={`${SITE_URL}/argentina/${color}-ticket.png`}
width={1143}
height={630}
/>
<div
style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
height: '100%',
position: 'absolute',
top: 200,
left: 0,
overflow: 'hidden',
}}
>
<div
style={{
display: 'flex',
justifyContent: 'center',
fontSize: '48px',
color: '#8855CC',
fontFamily: isLatinOnly(name) ? 'Roboto Condensed' : 'Noto Sans SC',
}}
>
{name}
</div>
</div>
</div>
)
}

export default Ticket
6 changes: 5 additions & 1 deletion devconnect/src/common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export const TITLE = 'Devconnect Argentina'
export const DESCRIPTION = 'A collaborative Ethereum week, built by and for everyone.'
export const SITE_URL =
process.env.NODE_ENV === 'development' ? 'https://preview-repo.vercel.app/' : 'https://devconnect.org/'
process.env.IS_LOCAL_DEV === 'true'
? 'http://localhost:3000/'
: process.env.NODE_ENV === 'development'
? 'https://preview-repo.vercel.app/'
: 'https://devconnect.org/'
export const IMAGE_OG = `${SITE_URL}og-argentina.png?reset=1`
export const SOCIAL_HANDLE = '@EFDevconnect'
export const FARCASTE_HANDLE = '@efdevconnect'
58 changes: 58 additions & 0 deletions devconnect/src/pages/api/ticket.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { ImageResponse } from '@vercel/og'
import { Ticket } from 'common/components/ticket'
import { SITE_URL } from 'common/constants'

// Route segment config
export const runtime = 'edge'

// Image metadata
export const alt = 'Devconnect ARG Tickets'
export const size = { width: 1200, height: 630 }
export const contentType = 'image/png'

// Fonts
const condensedFontUrl = new URL(`${SITE_URL}/RobotoCondensed-Bold.ttf`, import.meta.url)
const notoSansUrl = new URL(`${SITE_URL}/NotoSansSC-Regular.ttf`, import.meta.url)
let condensedFontData: ArrayBuffer | null = null
let notoSansData: ArrayBuffer | null = null

async function loadFonts() {
if (!condensedFontData) {
const res = await fetch(condensedFontUrl)
condensedFontData = await res.arrayBuffer()
}
if (!notoSansData) {
const res = await fetch(notoSansUrl)
notoSansData = await res.arrayBuffer()
}
return { condensedFontData, notoSansData }
}

export default async function GET(req: Request) {
const { searchParams } = new URL(req.url)
const name = searchParams.get('name') || 'Anon'
const color = searchParams.get('color') || 'blue'
const social = searchParams.get('social') || 'false'
const { condensedFontData, notoSansData } = await loadFonts()

console.log('name', name)
console.log('color', color)

return new ImageResponse(<Ticket name={name} color={color} social={social} />, {
...size,
fonts: [
{
name: 'Roboto Condensed',
data: condensedFontData,
style: 'normal',
weight: 700,
},
{
name: 'Noto Sans SC',
data: notoSansData,
style: 'normal',
weight: 400,
},
],
})
}
26 changes: 26 additions & 0 deletions devconnect/src/pages/argentina/ticket/[name].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'

import { ShareTicket } from './index'

const TicketPage = (props: any) => {
if (!props.params) return null

return <ShareTicket name={props.params.name} />
}

export async function getStaticPaths() {
return {
paths: [],
fallback: 'blocking',
}
}

export async function getStaticProps(context: any) {
return {
props: {
params: context.params,
},
}
}

export default TicketPage
71 changes: 71 additions & 0 deletions devconnect/src/pages/argentina/ticket/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* eslint-disable @next/next/no-img-element */
import { useState } from 'react'

import { colorKeys, colorMap } from 'common/components/ticket'
import { SEO } from 'common/components/SEO'
import { SITE_URL } from 'common/constants'

export const ShareTicket = ({ name }: { name?: string }) => {
const [color, setColor] = useState('blue')

const ticketLink = `/api/ticket?name=${name}&color=${color}`

return (
<div
style={{
backgroundImage: `url(/argentina/social-bg-img-${color}.jpg)`,
backgroundBlendMode: 'difference',
backgroundColor: '#74ACDF47',
backgroundSize: 'cover',
backgroundPosition: 'center',
padding: '20px',
minHeight: '100vh',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
}}
>
<SEO
title="Devconnect ARG Tickets"
description="Share your ticket with the world!"
imageUrl={`${SITE_URL}${ticketLink}&social=true`}
/>
<div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
Choose your vibe:{' '}
{colorKeys.map(colorKey => {
const isSelected = color === colorKey
const primaryColor = colorMap[colorKey as keyof typeof colorMap].primary
return (
<button
key={colorKey}
onClick={() => setColor(colorKey)}
style={{
backgroundColor: primaryColor,
border: isSelected ? `2px solid white` : '0px',
padding: '10px 20px',
borderRadius: '5px',
margin: '10px',
}}
></button>
)
})}
</div>
<div style={{ width: '630px', maxWidth: '100%' }}>
<img src={ticketLink} alt={`${name} - Devconnect ARG Ticket`} width={1200} height={630} />
</div>
</div>
)
}

const TicketPage = () => {
return <ShareTicket />
}

export async function getStaticProps(context: any) {
return {
props: {},
}
}

export default TicketPage
Loading