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 (
+
+ )
+ })}
+
+ )
+
+ 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"
/>
-
+
{
paddingTop: ['4rem', null, '6rem'],
paddingBottom: '1rem',
textAlign: 'center',
- backgroundColor: 'black',
+ backgroundColor: cssDark,
color: 'white'
}}
>
{
+ document.getElementById('og-replit').style.opacity = '0'
+ document.getElementById('fire-replit').style.opacity = '1'
+ }}
+ onMouseOut={() => {
+ document.getElementById('og-replit').style.opacity = '1'
+ document.getElementById('fire-replit').style.opacity = '0'
}}
>
Export your{' '}
-
- Replit{' '}
+
+ Replit
+
{' '}
repls
- Replit has discontinued its free plan. Previously free features like
- unlimited & private repls now cost $10 per month. GitHub Education is
- offering free{' '}
- Codespaces{' '}
- to all students.
+ On 25th August, Replit cut down its free plan - it's now unusable.
+
+ Previously, you got unlimited repls for free, for as long as you
+ wanted.
+
+ Now you get three repls, for 600 minutes per month (20 mins/day).
- {JSON.stringify(userDetails)}
-
-
-
-
- Export your repls
-
-
-
- {responseText}
-
- {progressText ? (
+
+
+ {steps.map((step, idx) => (
+
-
-
-
- {progressText * 100}% of your repls have processed.
- {progressText <= 0 ? ' Please wait!' : null}
- {progressText <= 1 ? ' Check your email!' : null}
-
+ {idx + 1}
- ) : null}
-
+ {step}
+
+ ))}
+
+
+
-
- 3: Something about free stickers
-
-
+
+
+
+
How to get your Replit connect.sid token
@@ -215,8 +278,7 @@ const ReplitPage = () => {
@@ -236,7 +298,7 @@ const ReplitPage = () => {