Skip to content

Commit

Permalink
feat: add cuid generator and validator
Browse files Browse the repository at this point in the history
  • Loading branch information
martinbacon committed May 7, 2024
1 parent cf957a8 commit ed219c8
Show file tree
Hide file tree
Showing 9 changed files with 409 additions and 74 deletions.
47 changes: 47 additions & 0 deletions .github/workflows/pages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages

on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true

jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 22
- name: Setup Pages
uses: actions/configure-pages@v2
- run: npm ci
- run: npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload entire repository
path: 'build'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
62 changes: 59 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"preview": "vite preview"
},
"dependencies": {
"@paralleldrive/cuid2": "^2.2.2",
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"lucide-react": "^0.378.0",
Expand Down
46 changes: 5 additions & 41 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,42 +1,6 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}
display: flex;
align-items: center;
justify-content: center;
flex-flow: column;
}
113 changes: 83 additions & 30 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,88 @@
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import {useState} from 'react'
import './App.css'

import {Button} from "@/components/ui/button"
import {Input} from "@/components/ui/input"
import {Alert, AlertDescription, AlertTitle} from "@/components/ui/alert"
import {ThemeProvider} from "@/components/theme-provider.tsx";

import {createId, isCuid} from '@paralleldrive/cuid2';
import {AlertCircle, Terminal} from "lucide-react";

function App() {
const [count, setCount] = useState(0)

return (
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
const [cuid, setCuid] = useState("")
const [generatedCuid, setGeneratedCuid] = useState("")
const [validCuid, setValidCuid] = useState(false)
const [firstTime, setFirstTime] = useState(false)

const onClick = () => {
setFirstTime(true);
setValidCuid(isCuid(cuid));
}

const generateCuid = () => {
const newCuid = createId();
setGeneratedCuid(newCuid);
}

const copyToClipboard = () => {
navigator.clipboard.writeText(generatedCuid);
}

const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
onClick();
}
}

const AlertSuccess = () => {
return (
<Alert>
<Terminal className="h-4 w-4"/>
<AlertTitle>Valid</AlertTitle>
<AlertDescription>
Your CUID2 is valid.
</AlertDescription>
</Alert>
);
}

const AlertDestructive = () => {
return (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4"/>
<AlertTitle>Error</AlertTitle>
<AlertDescription>
Your CUID2 is invalid.
</AlertDescription>
</Alert>
);
}

return (
<ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
<div className="w-full text-center mt-32">
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
CUID2 Generator and Checker
</h1>
</div>
<div className="w-full max-w-md mt-16">
<div className="flex justify-center space-x-2 my-4">
<Input type="text" value={generatedCuid} readOnly placeholder="Generated CUID2"/>
<Button onClick={generateCuid} type="button">Generate</Button>
<Button onClick={copyToClipboard} type="button">Copy</Button>
</div>
<div className="flex justify-center space-x-2">
<Input type="text" onChange={e => setCuid(e.target.value)} onKeyDown={handleKeyDown}
placeholder="CUID2"/>
<Button onClick={onClick} type="submit">Check</Button>
</div>
{firstTime ?
<div className="flex justify-center my-4">{validCuid ? AlertSuccess() : AlertDestructive()}
</div> : null}
</div>
</ThemeProvider>
)
}

export default App
export default App
Loading

0 comments on commit ed219c8

Please sign in to comment.