diff --git a/components/replit/form.js b/components/replit/form.js new file mode 100644 index 00000000..ec2df910 --- /dev/null +++ b/components/replit/form.js @@ -0,0 +1,237 @@ +import { useState } from 'react' +import { Box, Button, Card, Link, Input, Text, Flex, Image } from 'theme-ui' +import Icon from '@hackclub/icons' + +const ReplitForm = ({ cssDark }) => { + const [currentStep, setCurrentStep] = useState(1) + const [isSubmitted, setIsSubmitted] = useState(false) + const [formData, setFormData] = useState({}) + + const handleInputChange = e => { + const { name, value } = e.target + setFormData(prev => ({ ...prev, [name]: value })) + } + + const submitForm = () => { + console.log('submitting') + } + + const stickers = [ + '/stickers/orpheus-having-boba.png', + '/stickers/find out.png', + '/stickers/hackers,_assemble!.png', + '/stickers/mo’ parts mo’ problems.png', + '/stickers/orphmoji_peefest.png', + '/stickers/skullpup_boba.png', + '/stickers/hackers,_assemble!.png', + '/stickers/orphmoji_yippee.png', + '/replit/replit-fire.png' + ] + + const fieldStyle = ({ disabled }) => ({ + border: '1.5px solid #0002', + cursor: disabled ? 'not-allowed' : 'auto', + opacity: disabled ? 0.5 : 1 + }) + + const buttonStyle = ({ disabled }) => ({ + backgroundColor: cssDark, + cursor: disabled ? 'not-allowed' : 'auto', + opacity: disabled ? 0.5 : 1 + }) + + const boxStyle = { + display: 'flex', + flexDirection: 'column', + gap: '.5em', + alignItems: 'flex-start', + position: 'relative' + } + + const step1 = () => { + const fieldDisabled = currentStep !== 1 || isSubmitted + const buttonDisabled = fieldDisabled || !formData.email + + return ( + + + Email + + {' '} + + + ) + } + + const step2 = () => { + const fieldDisabled = currentStep !== 2 || isSubmitted + const backButtonDisabled = fieldDisabled + const submitButtonDisabled = + fieldDisabled || !formData.email || !formData.token + + return ( + + + + Replit connect.sid token{' '} + + + How do I find this? + + + {' '} + + + + + + ) + } + + const step3 = () => ( + + Stickers + + Get free stickers Get free stickers Get free stickers Get free stickers + Get free stickers Get free stickers Get free stickers Get free stickers + Get free stickers Get free stickers{' '} + + + + {stickers.map((sticker, idx) => { + const pos = getRandomPointOnUnitSquare() + return ( + orpheus dinosaur labelled 'hackers assemble' + ) + })} + + ) + + function getRandomPointOnUnitSquare() { + const side = Math.floor(Math.random() * 4) + const position = Math.random() + const margin = 0.1 + + switch (side) { + case 0: + return [-margin, position] + case 1: + return [position, 1 + margin] + case 2: + return [1 + margin, 1 - position] + case 3: + return [1 - position, -margin] + } + } + + return ( + + {formData.email || 'no email'} + {formData.token || 'no token'} + + + {step1()} + {step2()} + {step3()} + + ) +} + +export default ReplitForm diff --git a/pages/replit.js b/pages/replit.js index a813f923..d11263bd 100644 --- a/pages/replit.js +++ b/pages/replit.js @@ -16,38 +16,52 @@ import Head from 'next/head' import Meta from '@hackclub/meta' import Footer from '../components/footer' import Nav from '../components/nav' -import { useState, useEffect } from 'react' -import useForm from '../lib/use-form' +import { useState, useEffect, useRef } from 'react' import Submit from '../components/submit' import ForceTheme from '../components/force-theme' +import ReplitForm from '../components/replit/form' const ReplitPage = () => { - const [userDetails, setUserDetails] = useState({ token: null, email: null }) + const [token, setToken] = useState('') + const [email, setEmail] = useState('') + const [submitStatus, setSubmitStatus] = useState('default') const [responseText, setResponseText] = useState('') const [progressText, setProgressText] = useState(0) + const intervalRef = useRef(null) + useEffect(() => { const token = localStorage.getItem('token') const email = localStorage.getItem('email') - setUserDetails({ token, email }) - setInterval(() => { - try { - fetch(`/api/replit/progress?token=${localStorage.getItem('token')}`) - .then(res => res.text()) - .then(data => { - const split = data.split('/') - console.log(data, split) - setProgressText(split[0] / split[1]) - }) - } catch (e) { - console.warn(e) - } - }, 5_000) + if (token) setToken(token) + if (email) setEmail(email) }, []) + useEffect(() => { + if (token) { + intervalRef.current = setInterval(() => { + try { + fetch(`/api/replit/progress?token=${token}`) + .then(res => res.text()) + .then(data => { + const split = data.split('/') + setProgressText(split[0] / split[1]) + }) + } catch (e) { + console.warn(e) + } + }, 5000) + } + + return () => { + clearInterval(intervalRef.current) + } + }, [token]) + const handleSubmit = async event => { + setSubmitStatus('submitting') event.preventDefault() const formData = new FormData(event.target) const data = { @@ -59,22 +73,31 @@ const ReplitPage = () => { const response = await fetch('/api/replit/signup', { method: 'POST', headers: { - 'Content-Type': 'application/json' + 'Content-Type': 'application/x-www-form-urlencoded' }, - body: JSON.stringify(data) + body: new URLSearchParams(data).toString() }) - const result = await response.json() - localStorage.setItem('token', result.token) - localStorage.setItem('email', result.email) - setUserDetails({ token: result.token, email: result.email }) - setResponseText('Success!') + const result = await response.text() + setResponseText(result) + + // Store the email and token in localStorage + localStorage.setItem('token', data.token) + localStorage.setItem('email', data.email) + setSubmitStatus('success') } catch (error) { + setSubmitStatus('error') setResponseText('Error submitting form') console.error('Error:', error) } } + const steps = [ + 'Enter your email', + 'Enter your replit token', + 'Get free stickers' + ] + const tokenSteps = [ { image: '/replit/aarc1.gif', @@ -90,6 +113,8 @@ const ReplitPage = () => { } ] + const cssDark = 'hsl(23, 94%, 32%)' + return ( <> { title="Export your Repls" description="Replit free has shut down. Export with Hack Club to GitHub Education's new free codespaces offering" /> - +