mirror of
https://github.com/System-End/site.git
synced 2026-04-19 20:55:09 +00:00
Merge pull request #1255 from SkyfallWasTaken/main
Add signed-out view to Arcade Shop
This commit is contained in:
commit
d85f3f19b6
3 changed files with 181 additions and 82 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useRef, useEffect } from 'react'
|
||||
import { Box, Button, Text, Flex, Grid, Card, Link, Close, Divider } from 'theme-ui'
|
||||
import React from 'react'
|
||||
import { Button, Text, Flex, Close, Divider } from 'theme-ui'
|
||||
import Balancer from 'react-wrap-balancer'
|
||||
import Quantity from './quantity'
|
||||
/** @jsxImportSource theme-ui */
|
||||
|
|
@ -14,11 +14,11 @@ const Prizes = ({
|
|||
cost,
|
||||
polaroidRotation,
|
||||
ticketRotation,
|
||||
link,
|
||||
link = null,
|
||||
quantity,
|
||||
onQuantityChange,
|
||||
index,
|
||||
hoursBalance,
|
||||
hoursBalance = null,
|
||||
stock,
|
||||
...props
|
||||
}) => {
|
||||
|
|
@ -26,11 +26,13 @@ const Prizes = ({
|
|||
/\[(.*?)\]\((.*?)\)/g,
|
||||
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
||||
)
|
||||
const parsedSubText = subtext?.replace(/\[(.*?)\]\((.*?)\)/g,
|
||||
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>')
|
||||
|
||||
const parsedFullName = fullName?.replace(" ", "-")
|
||||
|
||||
const parsedSubText = subtext?.replace(
|
||||
/\[(.*?)\]\((.*?)\)/g,
|
||||
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
||||
)
|
||||
|
||||
const parsedFullName = fullName?.replace(' ', '-')
|
||||
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
|
|
@ -48,23 +50,22 @@ const Prizes = ({
|
|||
}}
|
||||
{...props}
|
||||
>
|
||||
<Flex sx={{flexDirection: 'column'}}>
|
||||
|
||||
<Flex
|
||||
sx={{
|
||||
background: '#FFEEC6',
|
||||
height: '250px',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={img}
|
||||
sx={{ height: 'auto', maxWidth: '280px', maxHeight: '250px' }}
|
||||
alt={text}
|
||||
/>
|
||||
</Flex>
|
||||
{stock && stock != null && stock > 0 && stock <= 100 && (
|
||||
<Flex sx={{ flexDirection: 'column' }}>
|
||||
<Flex
|
||||
sx={{
|
||||
background: '#FFEEC6',
|
||||
height: '250px',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={img}
|
||||
sx={{ height: 'auto', maxWidth: '280px', maxHeight: '250px' }}
|
||||
alt={text}
|
||||
/>
|
||||
</Flex>
|
||||
{stock && stock != null && stock > 0 && stock <= 100 && (
|
||||
<Text
|
||||
sx={{
|
||||
background: '#CC6CE7',
|
||||
|
|
@ -82,61 +83,71 @@ const Prizes = ({
|
|||
Only {stock} left!
|
||||
</Text>
|
||||
)}
|
||||
<Text
|
||||
className="slackey"
|
||||
variant="headline"
|
||||
sx={{ color: '#FFEEC6', mb: 0 }}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
<Text variant="subtitle" sx={{ color: '#FFEEC6' }}>
|
||||
{smallName}
|
||||
</Text>
|
||||
<Balancer>
|
||||
<Text
|
||||
as="p"
|
||||
variant="caption"
|
||||
sx={{ color: '#FFEEC6', mb: 2, overflowWrap: 'break-word' }}
|
||||
dangerouslySetInnerHTML={{ __html: parsedSubText }}
|
||||
/>
|
||||
</Balancer>
|
||||
|
||||
className="slackey"
|
||||
variant="headline"
|
||||
sx={{ color: '#FFEEC6', mb: 0 }}
|
||||
>
|
||||
{name}
|
||||
</Text>
|
||||
<Text variant="subtitle" sx={{ color: '#FFEEC6' }}>
|
||||
{smallName}
|
||||
</Text>
|
||||
<Balancer>
|
||||
<Text
|
||||
as="p"
|
||||
variant="caption"
|
||||
sx={{ color: '#FFEEC6', mb: 2, overflowWrap: 'break-word' }}
|
||||
dangerouslySetInnerHTML={{ __html: parsedSubText }}
|
||||
/>
|
||||
</Balancer>
|
||||
</Flex>
|
||||
{link && (
|
||||
<Flex sx={{flexDirection: 'column'}}>
|
||||
<Balancer>
|
||||
<Text
|
||||
as="p"
|
||||
variant="caption"
|
||||
sx={{ color: '#FFEEC6', mt: 0, mb: 2 }}
|
||||
>
|
||||
<em>You can order up to {quantity} of these</em>
|
||||
</Text>
|
||||
</Balancer>
|
||||
<Flex>
|
||||
{// only show the quantity dropdown if you have enough hours to buy at least 2 of the item
|
||||
hoursBalance / cost < 2 ? (null) : <Quantity numOptions={Math.min(quantity, Math.floor(hoursBalance / cost))} label={text} onQuantityChange={onQuantityChange} index={index} />
|
||||
}
|
||||
{
|
||||
// only show the buy button if you have enough hours to buy at least 1 of the item
|
||||
hoursBalance / cost < 1 ? (null) :
|
||||
<Button
|
||||
sx={{
|
||||
borderRadius: '5px',
|
||||
color: '#FFEEC6',
|
||||
backgroundColor: '#09878b',
|
||||
width: 'fit-content'
|
||||
}}
|
||||
as="a"
|
||||
href={link}
|
||||
className="gaegu"
|
||||
>
|
||||
Buy
|
||||
</Button>
|
||||
}
|
||||
</Flex>
|
||||
|
||||
<Flex sx={{ flexDirection: 'column' }}>
|
||||
<Balancer>
|
||||
<Text
|
||||
as="p"
|
||||
variant="caption"
|
||||
sx={{ color: '#FFEEC6', mt: 0, mb: 2 }}
|
||||
>
|
||||
<em>You can order up to {quantity} of these</em>
|
||||
</Text>
|
||||
</Balancer>
|
||||
|
||||
{link && (<Flex>
|
||||
{
|
||||
// only show the quantity dropdown if you have enough hours to buy at least 2 of the item
|
||||
(hoursBalance ? hoursBalance / cost < 2 : null) ? null : (
|
||||
<Quantity
|
||||
numOptions={Math.min(quantity, Math.floor(hoursBalance / cost))}
|
||||
label={text}
|
||||
onQuantityChange={onQuantityChange}
|
||||
index={index}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{
|
||||
// only show the buy button if you have enough hours to buy at least 1 of the item
|
||||
(hoursBalance ? hoursBalance / cost < 1 : null) ? null : (
|
||||
<Button
|
||||
sx={{
|
||||
borderRadius: '5px',
|
||||
color: '#FFEEC6',
|
||||
backgroundColor: '#09878b',
|
||||
width: 'fit-content'
|
||||
}}
|
||||
as="a"
|
||||
href={link}
|
||||
className="gaegu"
|
||||
>
|
||||
Buy
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</Flex>
|
||||
)}
|
||||
)}
|
||||
</Flex>
|
||||
|
||||
<Text
|
||||
sx={{
|
||||
background: '#FF8C37',
|
||||
|
|
@ -231,10 +242,10 @@ const Prizes = ({
|
|||
/>
|
||||
<Balancer>
|
||||
<Text
|
||||
variant="subtitle" sx={{ color: '#FFEEC6' }}
|
||||
variant="subtitle"
|
||||
sx={{ color: '#FFEEC6' }}
|
||||
dangerouslySetInnerHTML={{ __html: parsedSubText }}
|
||||
/>
|
||||
|
||||
</Balancer>
|
||||
<Text
|
||||
variant="subtitle"
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export default function ShopComponent({
|
|||
return `https://forms.hackclub.com/arcade-order?user_id=${userAirtableID}&item_id=${itemID}&quantity=${quantity}`;
|
||||
}
|
||||
|
||||
const includeBuyLink = userAirtableID !== null;
|
||||
const canPurchaseItems = userAirtableID !== null;
|
||||
useEffect(() => {
|
||||
setPRotate(2 + Math.random() * 4) * (Math.random() > 0.5 ? 1 : -1)
|
||||
setTRotate(5 + Math.random() * 14) * (Math.random() > 0.5 ? 1 : -1)
|
||||
|
|
@ -93,7 +93,7 @@ export default function ShopComponent({
|
|||
fullName={item['Full Name']}
|
||||
polaroidRotation={pRotate}
|
||||
ticketRotation={tRotate}
|
||||
link={buyLink(item.id)}
|
||||
link={canPurchaseItems ? buyLink(item.id) : null}
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
onQuantityChange={(id, q) => handleQuantityChange(item.id, q)} // Pass handler to update quantity
|
||||
|
|
|
|||
88
pages/arcade/shop.js
Normal file
88
pages/arcade/shop.js
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import ShopComponent from "../../components/arcade/shop-component"
|
||||
import { shopParts } from "../api/arcade/shop"
|
||||
import { Link, Text } from 'theme-ui'
|
||||
import { Balancer } from "react-wrap-balancer"
|
||||
import Meta from '@hackclub/meta'
|
||||
import Head from 'next/head'
|
||||
|
||||
/** @jsxImportSource theme-ui */
|
||||
|
||||
const styled = `
|
||||
@import url('https://fonts.googleapis.com/css2?family=Slackey&family=Emblema+One&family=Gaegu&display=swap');
|
||||
|
||||
.slackey {
|
||||
font-family: "Slackey", sans-serif;
|
||||
}
|
||||
|
||||
.gaegu {
|
||||
font-family: "Gaegu", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #FAEFD6;
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
export default function Shop({ availableItems, userAirtableID = null, hoursBalance = 0 }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Meta
|
||||
as={Head}
|
||||
title="Arcade Shop"
|
||||
description="Check out the prizes at the Arcade Shop!"
|
||||
image="https://cloud-luaw423i2-hack-club-bot.vercel.app/0frame_33__1_.png"
|
||||
/>
|
||||
<style>
|
||||
{`
|
||||
._title-container {
|
||||
width: 100%;
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<Balancer className="_title-container">
|
||||
<h1
|
||||
sx={{
|
||||
textAlign: 'center',
|
||||
fontSize: 5,
|
||||
color: '#FF8C37',
|
||||
my: 0,
|
||||
pt: 5,
|
||||
display: 'block',
|
||||
width: '100%'
|
||||
}}
|
||||
className="slackey"
|
||||
>
|
||||
Welcome to the shop
|
||||
</h1>
|
||||
</Balancer>
|
||||
|
||||
<Text sx={{ display: 'block', textAlign: 'center', color: '#35290F' }} className='gaegu' variant='subtitle' >Like what you see? Check out <Link href="/arcade">the Hack Club Arcade!</Link></Text>
|
||||
<ShopComponent availableItems={availableItems} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps() {
|
||||
const props = {};
|
||||
|
||||
await Promise.all([
|
||||
shopParts().then(items => {
|
||||
const availableItems = items.filter((item) => item['Enabled']).map(item => ({
|
||||
'Name': item['Name'] || null,
|
||||
'Small Name': item['Small Name'] || null,
|
||||
'Full Name': item['Full Name'] || null,
|
||||
'Description': item['Description'] || null,
|
||||
'Fulfillment Description': item['Fulfillment Description'] || null,
|
||||
'Cost Hours': item['Cost Hours'] || 0,
|
||||
id: item.id,
|
||||
'Image URL': item['Image URL'] || null,
|
||||
'Max Order Quantity': item['Max Order Quantity'] || 1
|
||||
}))
|
||||
props.availableItems = availableItems
|
||||
}),
|
||||
])
|
||||
|
||||
return { props, revalidate: 10 }
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue