mirror of
https://github.com/System-End/site.git
synced 2026-04-19 16:28:21 +00:00
Update Replit copy
This commit is contained in:
parent
68f848d7ef
commit
bf1a6aab2a
5 changed files with 750 additions and 547 deletions
39
components/replit/scale-up.js
Normal file
39
components/replit/scale-up.js
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import React, { useState, useEffect } from 'react'
|
||||
|
||||
const easeInOutExpo = x =>
|
||||
x === 0
|
||||
? 0
|
||||
: x === 1
|
||||
? 1
|
||||
: x < 0.5
|
||||
? Math.pow(2, 20 * x - 10) / 2
|
||||
: (2 - Math.pow(2, -20 * x + 10)) / 2
|
||||
|
||||
const ScaleUp = ({ number }) => {
|
||||
const [displayNumber, setDisplayNumber] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const duration = 2000
|
||||
const startTime = performance.now()
|
||||
|
||||
const animate = () => {
|
||||
const time = performance.now() - startTime
|
||||
const progress = time / duration
|
||||
const easedProgress = easeInOutExpo(progress)
|
||||
|
||||
setDisplayNumber(Math.round(number * easedProgress))
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(animate)
|
||||
} else {
|
||||
setDisplayNumber(number)
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(animate)
|
||||
}, [number])
|
||||
|
||||
return <span>{displayNumber}</span>
|
||||
}
|
||||
|
||||
export default ScaleUp
|
||||
|
|
@ -95,6 +95,7 @@
|
|||
"remark": "^15.0.1",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-html": "^16.0.1",
|
||||
"socket.io": "^4.7.5",
|
||||
"styled-components": "^6.1.8",
|
||||
"swr": "^2.2.4",
|
||||
"theme-ui": "^0.14",
|
||||
|
|
|
|||
24
pages/api/replit/stats.js
Normal file
24
pages/api/replit/stats.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
export default async function handler(req, res) {
|
||||
if (req.method === 'GET') {
|
||||
try {
|
||||
const response = await fetch('http://takeout.hackclub.com/stats')
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
res.status(200).json(data)
|
||||
} catch (error) {
|
||||
console.error('Error processing signup:', error)
|
||||
res
|
||||
.status(500)
|
||||
.json({ message: 'Error processing signup', error: error.message })
|
||||
}
|
||||
} else {
|
||||
// Handle any non-POST requests
|
||||
res.setHeader('Allow', ['POST'])
|
||||
res.status(405).end(`Method ${req.method} Not Allowed`)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { Box, Link, Image, Button, Heading, Text, Card } from 'theme-ui'
|
||||
import { Box, Link, Image, Button, Heading, Text, Card, Flex } from 'theme-ui'
|
||||
import Head from 'next/head'
|
||||
import Meta from '@hackclub/meta'
|
||||
import Footer from '../components/footer'
|
||||
|
|
@ -8,11 +8,24 @@ import ReplitForm from '../components/replit/form'
|
|||
import Progress from '../components/replit/progress'
|
||||
import TokenInstructions from '../components/replit/token-instructions'
|
||||
import { useEffect, useState } from 'react'
|
||||
import ScaleUp from '../components/replit/scale-up'
|
||||
import Icon from '@hackclub/icons'
|
||||
|
||||
const ReplitPage = () => {
|
||||
const [progress, setProgress] = useState(null)
|
||||
const [stats, setStats] = useState(null)
|
||||
|
||||
const fetchStats = async () => {
|
||||
const statResponse = await fetch('/api/replit/stats')
|
||||
if (!statResponse.ok) throw new Error('Failed to fetch stats')
|
||||
const statData = await statResponse.json()
|
||||
console.info(statData)
|
||||
setStats(statData)
|
||||
}
|
||||
|
||||
useEffect(async () => {
|
||||
await fetchStats()
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(async () => {
|
||||
const token = localStorage.getItem('token')
|
||||
if (!token) return
|
||||
|
|
@ -23,6 +36,8 @@ const ReplitPage = () => {
|
|||
const data = await response.json()
|
||||
console.info(data)
|
||||
setProgress(data)
|
||||
|
||||
await fetchStats()
|
||||
} catch (err) {
|
||||
console.error("Couldn't get progress:", err)
|
||||
}
|
||||
|
|
@ -187,19 +202,36 @@ const ReplitPage = () => {
|
|||
|
||||
<Text
|
||||
sx={{
|
||||
maxWidth: '80ch',
|
||||
maxWidth: '100ch',
|
||||
fontSize: '1.2em',
|
||||
marginY: '1em',
|
||||
marginTop: '1em',
|
||||
textWrap: 'pretty'
|
||||
}}
|
||||
>
|
||||
On 25th August, Replit cut down its free plan - many students won't be
|
||||
able to afford to keep using it.
|
||||
Replit cut down its free plan - many students can't afford to keep
|
||||
using it.
|
||||
<br />
|
||||
We quickly built this tool in response - plug in your email and Replit
|
||||
token and get a zip file containing all your Repls, with full Git
|
||||
history constructed from Replit's files' history.
|
||||
We quickly built this project exporter. It's the only way to download
|
||||
your repls with <i>edit history intact</i> (as a git repo).
|
||||
<br />
|
||||
Written in Rust &{' '}
|
||||
<Link
|
||||
className="gh-link"
|
||||
href="https://github.com/hackclub/replit-lifeboat"
|
||||
sx={{
|
||||
color: 'inherit'
|
||||
}}
|
||||
>
|
||||
open source
|
||||
</Link>
|
||||
.{' '}
|
||||
{stats ? (
|
||||
<Text>
|
||||
<ScaleUp number={stats.file_count} /> files &{' '}
|
||||
<ScaleUp number={stats.repl_count} /> repls exported.
|
||||
</Text>
|
||||
) : null}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue