Skip to content

Commit

Permalink
Update landing page
Browse files Browse the repository at this point in the history
  • Loading branch information
nag5000 committed Nov 16, 2024
1 parent 0cde9d0 commit b47c7ab
Show file tree
Hide file tree
Showing 22 changed files with 187 additions and 106 deletions.
Binary file modified packages/jsrepl/public/assets/landing-demo-browserenv.mp4
Binary file not shown.
Binary file modified packages/jsrepl/public/assets/landing-demo-browserenv.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 modified packages/jsrepl/public/assets/landing-demo-npm.mp4
Binary file not shown.
Binary file modified packages/jsrepl/public/assets/landing-demo-npm.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 not shown.
Binary file not shown.
Binary file modified packages/jsrepl/public/assets/landing-demo-reactjsx.mp4
Binary file not shown.
Binary file modified packages/jsrepl/public/assets/landing-demo-reactjsx.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 modified packages/jsrepl/public/assets/landing-demo-repl.mp4
Binary file not shown.
Binary file modified packages/jsrepl/public/assets/landing-demo-repl.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 modified packages/jsrepl/public/assets/landing-demo-security.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 modified packages/jsrepl/public/assets/landing-demo-tailwindcss.mp4
Binary file not shown.
Binary file modified packages/jsrepl/public/assets/landing-demo-tailwindcss.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 modified packages/jsrepl/public/assets/landing-demo-typescript.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 removed packages/jsrepl/public/assets/landing-hero.kra
Binary file not shown.
13 changes: 13 additions & 0 deletions packages/jsrepl/src/app/(default)/components/faq-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { LucideChevronRight } from 'lucide-react'

export function FaqItem({ title, children }: { title: string; children: React.ReactNode }) {
return (
<details className="group">
<summary className="text-primary w-max cursor-pointer text-2xl font-semibold marker:content-none">
<LucideChevronRight className="mr-2 inline-block align-[-0.25rem] transition-transform group-open:rotate-90" />
{title}
</summary>
<div className="prose dark:prose-invert ml-1 mt-4 font-medium text-gray-300">{children}</div>
</details>
)
}
118 changes: 67 additions & 51 deletions packages/jsrepl/src/app/(default)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
'use client'

import { useEffect, useRef, useState } from 'react'
import { useState } from 'react'
import Image from 'next/image'
import Link from 'next/link'
import {
LucideArrowDown,
LucideArrowRight,
LucideHeart,
LucideMessageCircleQuestion,
LucidePackage,
LucidePiggyBank,
LucideSquareFunction,
} from 'lucide-react'
import Typed from 'typed.js'
import IconEmail from '~icons/mdi/email-outline.jsx'
import IconGithub from '~icons/mdi/github.jsx'
import IconEsbuild from '~icons/simple-icons/esbuild.jsx'
Expand All @@ -22,6 +22,7 @@ import { toQueryParams } from '@/lib/repl-stored-state'
import { demoRepls } from '@/lib/repl-stored-state-library'
import { ReplStoredState } from '@/types'
import Demo from './components/demo'
import { FaqItem } from './components/faq-item'
import FeatureBox from './components/feature-box'

function getReplLink(state: ReplStoredState) {
Expand All @@ -32,29 +33,6 @@ function getReplLink(state: ReplStoredState) {

export default function Home() {
const [starterDialogOpen, setStarterDialogOpen] = useState(false)
const typedRef = useRef<HTMLElement>(null)

useEffect(() => {
let loopIndex = 0

const typed = new Typed(typedRef.current, {
strings: ['TypeScript, HTML, CSS', 'React JSX / TSX', 'Tailwind CSS'],
typeSpeed: 10,
backDelay: 2000,
smartBackspace: false,
loop: true,
// HACK: fix initial text flickering when loop is restarted
onBegin: (self) => {
if (loopIndex++ > 0) {
self.strPos = 0
}
},
})

return () => {
typed.destroy()
}
}, [])

return (
<>
Expand All @@ -65,7 +43,7 @@ export default function Home() {
</span>

<h1 className="text-primary whitespace-nowrap text-5xl font-bold leading-snug max-md:text-4xl [&>.typed-cursor]:inline-block [&>.typed-cursor]:-translate-y-0.5 [&>.typed-cursor]:font-normal">
<span ref={typedRef}>JavaScript, HTML, CSS</span>
<span className="text-[3.2rem]">JavaScript</span>
<br />
<span className="text-stone-200">REPL & Playground</span>
</h1>
Expand Down Expand Up @@ -435,7 +413,7 @@ export default function Home() {

<div className="container my-20 space-y-16 text-center font-medium text-gray-300">
<div>
<h2 className="text-primary text-2xl font-semibold">It is all free and open source</h2>
<h2 className="text-primary text-2xl font-semibold">This is all free and open source</h2>
<p>No login / registration required.</p>
</div>
<div>
Expand Down Expand Up @@ -572,7 +550,7 @@ export default function Home() {
/>

<Demo
replLink={getReplLink(demoRepls.jsx)}
replLink={getReplLink(demoRepls.react)}
title="React & JSX/TSX"
text={
<>
Expand All @@ -591,26 +569,6 @@ export default function Home() {
)}
/>

<Demo
replLink={getReplLink(demoRepls.prettier)}
title="Prettier"
text={
<>
<p>
Format your code with Prettier by pressing <kbd>⌘+S</kbd>.<br />
There&apos;s nothing more to say.
</p>
</>
}
media={({ videoProps }) => (
<video
{...videoProps}
src="/assets/landing-demo-prettier.mp4"
poster="/assets/landing-demo-prettier.png"
/>
)}
/>

<Demo
title="Themes"
text={
Expand Down Expand Up @@ -641,9 +599,66 @@ export default function Home() {
/>
</div>

<div className="container mt-32 text-white/85 max-md:mt-20">
<h2 className="mb-8 text-center text-2xl font-semibold">
FAQ{' '}
<LucideMessageCircleQuestion
className="mx-1 inline-block -translate-y-0.5 text-blue-400"
size={28}
/>
</h2>
<div className="mx-auto w-full max-w-prose space-y-8">
<FaqItem title="What">
<p>
JSREPL is a simple, easy-to-use, yet modern playground for JavaScript and TypeScript
code. It allows you to write, run, and share code snippets.
</p>
<p>
Although it allows you to use HTML, CSS, TailwindCSS, NPM packages, ESM modules, and
React JSX/TSX, the main feature is the Live Feedback, which lets you see the results
of JavaScript expressions in real time.
</p>
</FaqItem>
<FaqItem title="Why">
<p>
The essence of JSREPL is to offer a playground that allows you to test your frontend
code snippets quickly and without distractions, such as the need to set up a (complex)
development environment.
</p>
<p>
It&apos;s not a replacement for StackBlitz or your IDE. The main goal and key metric
is how simple and fast you can play with something, say copy-paste a code snippet from
MDN, StackOverflow, GitHub Issues, ChatGPT, or whatever, and check the result.
</p>
<p>
You don&apos;t need to log in or register. You don&apos;t need to install npm packages
you want to play with. The results of JavaScript expressions displayed in real time
allow you to go without <code>console.log</code>ing all the things. And you still have
all the power to keep browser devtools open and use <code>debugger</code> statements
to debug your code.
</p>
</FaqItem>
<FaqItem title="How">
<p>
First of all, (obviously), it is not a replacement for browser devtools & debugger.
<br />
JSREPL does not interpret your code by itself. Your code is executed in the real
browser environment within an iframe. The magic happens behind the AST transformations
at build time and logging stuff in runtime.
</p>
<p>
The playground powered by client-side JavaScript and WebAssembly, and literally works
right in your browser.
</p>
</FaqItem>
</div>
</div>

<div className="container mt-32 text-gray-300 max-md:mt-20">
<h2 className="mb-8 text-center text-2xl font-semibold text-white/85">
Made with <LucideHeart className="mx-1 inline-block text-red-500" size={28} /> by
Made with{' '}
<LucideHeart fill="currentColor" className="mx-1 inline-block text-red-500" size={28} />{' '}
by
</h2>

<div className="mx-auto flex w-full max-w-96 flex-col items-center gap-4 rounded-xl bg-zinc-800 p-6 text-center text-white/85">
Expand Down Expand Up @@ -736,10 +751,11 @@ export default function Home() {
https://buymeacoffee.com/nag5000
</Link>
<br />
to support the development and cover some of the costs of the domain.
to support the development and help cover some of the costs of the domain and running the
service.
<br />
<br />
JSREPL is a side project, and I do it in my free time.
JSREPL is a side project, and I work on it in my free time.
<br />
It is free for everyone, and will remain free.
<br />
Expand Down
14 changes: 12 additions & 2 deletions packages/jsrepl/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,18 @@ import { TooltipProvider } from '@/components/ui/tooltip'
import './globals.css'

export const metadata: Metadata = {
title: 'JSREPL',
description: 'JavaScript REPL & Playground',
title: 'JavaScript REPL & Playground',
description: 'Quickly test and share your code snippets. Ideal for learning and prototyping.',
openGraph: {
type: 'website',
images: {
url: '/assets/landing-hero.png',
type: 'image/png',
width: 1200,
height: 917,
},
},
keywords: ['JavaScript', 'TypeScript', 'REPL', 'Playground'],
}

export default function RootLayout({
Expand Down
2 changes: 1 addition & 1 deletion packages/jsrepl/src/app/repl/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function generateMetadata({ searchParams }: Props): Metadata {
return { title }
} catch (e) {
console.error('generateMetadata error', e)
return { title: 'JSREPL' }
return { title: 'JavaScript REPL & Playground' }
}
}

Expand Down
Loading

0 comments on commit b47c7ab

Please sign in to comment.