Skip to content

Commit

Permalink
docs: adjust mobile website (#82)
Browse files Browse the repository at this point in the history
* docs: adjust mobile website

* docs: adjust padding

* build: remove unnecessary scripts

* fix: clipboard
  • Loading branch information
Kikobeats authored Dec 18, 2024
1 parent 86350c5 commit 0cfa969
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 85 deletions.
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,12 @@
"scripts": {
"clean": "rm -rf node_modules",
"contributors": "(npx git-authors-cli && npx finepack && git add package.json && git commit -m 'build: contributors' --no-verify) || true",
"dev": "nodemon --exec \"npm start\" -e \"js\"",
"lint": "standard-markdown README.md && standard",
"postrelease": "npm run release:tags && npm run release:github && (ci-publish || npm publish --access=public)",
"pretest": "npm run lint",
"release": "standard-version -a",
"release:github": "conventional-github-releaser -p angular",
"release:tags": "git push --follow-tags origin HEAD:master",
"start": "node index.js",
"test": "c8 ava"
},
"license": "MIT",
Expand Down
94 changes: 46 additions & 48 deletions website/src/components/color-extractor.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* eslint-disable @next/next/no-img-element */
'use client'

import { creatCopyToClipboard } from '@/lib/copy-to-clipboard'
import { Loader2, RefreshCcw } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { useCallback, useState } from 'react'
import { useDropzone } from 'react-dropzone'
import { useToast } from '@/hooks/use-toast'
import { creatCopyToClipboard } from '@/lib/copy-to-clipboard'
import { useState } from 'react'

interface ColorFormat {
rgb: string
Expand Down Expand Up @@ -45,41 +45,38 @@ export function ColorExtractor () {
const { toast } = useToast()
const copyToClipboard = creatCopyToClipboard(toast)

const [imageUrl, setImageUrl] = useState('')
const [imageUrl, setImageUrl] = useState<string | undefined>(undefined)
const [colors, setColors] = useState<ColorFormat[]>([])
const [isLoading, setIsLoading] = useState(false)

const onDrop = useCallback(async (acceptedFiles: File[]) => {
const onDrop = async (acceptedFiles: File[]) => {
const formData = new FormData()
const base64data = await getBase64(acceptedFiles[0])
formData.append('file', acceptedFiles[0])
await processFiles(formData)
await setImageUrl(base64data)
}, [])
}

const { getRootProps, getInputProps } = useDropzone({ onDrop })

const handleUrlSubmit = async (e: React.FormEvent) => {
console.log('ola puto')
e.preventDefault()
if (imageUrl) {
console.log('TODO')
// await processFiles(imageUrl)
const res = await fetch(imageUrl)
const buffer = Buffer.from(await res.arrayBuffer())
const formData = new FormData()
formData.append('file', new Blob([buffer]))
await processFiles(formData)
}
}

const processFiles = async (formData: FormData) => {
setIsLoading(true)
const res = await fetch('/api/', {
method: 'POST',
body: formData
})

const palette = await res.json()
console.log(palette)
setColors(palette)
setColors(await res.json())
if (!imageUrl) setImageUrl(await getBase64(formData.get('file') as File))
setIsLoading(false)
setImageUrl('') // Clear the input field after processing
}

const resetState = () => {
Expand All @@ -93,40 +90,45 @@ export function ColorExtractor () {
}

return (
<div className=''>
<div className='lg:w-full w-[90%] mx-auto'>
{colors.length === 0 ? (
<div>
<div
{...getRootProps()}
className='border-2 rounded-2xl h-[400px] flex flex-col items-center justify-center cursor-pointer border-primary bg-primary/5'
className='border-2 rounded-2xl lg:h-[400px] h-[200px] flex flex-col items-center justify-center cursor-pointer border-primary bg-primary/5'
>
<input {...getInputProps()} />
<p className='text-2xl lg:text-4xl font-bold text-primary'>DRAG AN IMAGE HERE</p>
<p className='text-2xl lg:text-4xl font-bold text-primary'>
{isLoading && <Loader2 className='animate-spin h-10 w-10' />}
{!isLoading && 'DRAG AN IMAGE HERE'}
</p>
</div>
<form
onSubmit={handleUrlSubmit}
onClick={handleFormClick}
className='flex pt-4 space-x-3 items-center'
>
<input
type='url'
value={imageUrl}
onChange={e => setImageUrl(e.target.value)}
onClick={handleFormClick}
placeholder='or paste an image URL'
className='flex-grow px-4 py-2 border-2 border-zinc-400 hover:border-primary focus:border-primary hover:outline-none focus:outline-none rounded-lg h-10'
/>
<Button
type='submit'
variant='outline'
className='border-2 hover:border-primary hover:text-primary font-bold h-10 border-zinc-400 text-zinc-400'
disabled={isLoading}
{!isLoading && (
<form
onSubmit={handleUrlSubmit}
onClick={handleFormClick}
className='flex flex-col lg:flex-row pt-4 lg:space-x-3 items-center'
>
{isLoading && <Loader2 className='animate-spin' />}
{isLoading ? 'HOLD ON...' : 'DO IT'}
</Button>
</form>
<input
type='url'
value={undefined}
onChange={e => setImageUrl(e.target.value)}
onClick={handleFormClick}
placeholder='or paste an image URL'
className='flex-grow px-4 py-2 border-2 border-zinc-400 hover:border-primary focus:border-primary hover:outline-none focus:outline-none rounded-lg h-10 w-full'
/>
<Button
type='submit'
variant='outline'
className='border-2 hover:border-primary hover:text-primary font-bold h-10 border-zinc-400 text-zinc-400 w-full lg:w-[inherit] lg:mt-0 mt-2'
disabled={isLoading}
onClick={handleFormClick}
>
{isLoading && <Loader2 className='animate-spin' />}
{isLoading ? 'HOLD ON...' : 'DO IT'}
</Button>
</form>
)}
</div>
) : (
<div className='flex justify-center items-center flex-col space-y-4'>
Expand All @@ -143,12 +145,8 @@ export function ColorExtractor () {
<div
onClick={() => copyToClipboard(color.hex, `Color ${color.hex}`)}
key={index}
className='cursor-pointer rounded-lg shadow-md'
style={{
height: '6rem',
width: '6rem',
backgroundColor: color.hex
}}
className='cursor-pointer rounded-lg shadow-md lg:h-24 lg:w-24 h-20 w-20'
style={{ backgroundColor: color.hex }}
>
<div className='w-full h-full flex items-end justify-center p-1 bg-gradient-to-t from-black/50 to-transparent rounded-lg pb-2'>
<span className='text-xs text-white font-medium'>
Expand All @@ -161,14 +159,14 @@ export function ColorExtractor () {
</div>
<div className='space-x-2 flex items-center justify-center'>
<Button
onClick={() => copyToClipboard(generateCSSVariables(colors))}
onClick={() => copyToClipboard(generateCSSVariables(colors), 'CSS Variables')}
className='w-auto'
variant='default'
>
Copy as CSS
</Button>
<Button
onClick={() => copyToClipboard(generateJSONObject(colors))}
onClick={() => copyToClipboard(generateJSONObject(colors), 'JSON')}
className='w-auto'
variant='secondary'
>
Expand Down
6 changes: 0 additions & 6 deletions website/src/components/debugger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ export function Debugger () {
<Button onClick={handleVisualize}>Visualize</Button>
</div>
</div>
<div className='mt-8 text-center text-gray-600 dark:text-gray-400'>
<p>Adjust the colors above or click &apos;Randomize&apos; for a surprise palette.</p>
<p>
When you&apos;re ready, click &apos;Visualize&apos; to see your palette in full screen!
</p>
</div>
</main>
</div>
)
Expand Down
11 changes: 8 additions & 3 deletions website/src/components/faq.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function FAQ () {
const copyToClipboard = creatCopyToClipboard(toast)

return (
<section id='faq' className='space-y-8 pb-24'>
<section id='faq' className='space-y-8'>
<div className='space-y-6'>
<div>
<h3 className='text-xl font-semibold mb-6'>What is Splashy?</h3>
Expand All @@ -46,7 +46,7 @@ export function FAQ () {
</p>
<Code
className='pt-6 cursor-pointer'
onClick={() => copyToClipboard(microlinkSnippet, 'npm install')}
onClick={() => copyToClipboard('npm install splashy --save', 'npm install')}
>
npm install splashy --save
</Code>
Expand All @@ -65,7 +65,12 @@ export function FAQ () {
<Link href='https://microlink.io/docs/api/getting-started/overview'>Microlink API</Link>{' '}
is already provisioned and ready to be used passing `palette` query parameter:
</p>
<Code className='pt-6'>{microlinkSnippet}</Code>
<Code
className='pt-6 cursor-pointer'
onClick={() => copyToClipboard(microlinkSnippet, 'microlink snippet')}
>
{microlinkSnippet}
</Code>
<p className='pt-6'>We recommend to consume splashy from Microlink API.</p>
</div>
<div>
Expand Down
2 changes: 1 addition & 1 deletion website/src/components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { cn } from '@/lib/utils'
export const Footer = () => {
const pathname = usePathname()
return (
<footer className='py-4 w-full text-neutral-600 fixed bottom-0 bg-slate-50 bg-opacity-10 backdrop-blur'>
<footer className='py-6 w-full text-neutral-600 fixed bottom-0 bg-slate-50 bg-opacity-10 backdrop-blur'>
<nav>
<ul className='flex justify-center space-x-4'>
{[
Expand Down
12 changes: 6 additions & 6 deletions website/src/components/layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,27 +42,27 @@ export const ContainerLayout = ({ children }: { children: React.ReactNode }) =>
<div className={`${inter.className} bg-slate-50`}>
<div
aria-hidden='true'
className='-z-10 absolute inset-0 grid grid-cols-2 -space-x-52 opacity-40 dark:opacity-20'
className='pointer-events-none absolute inset-0 grid grid-cols-2 -space-x-52 opacity-40 dark:opacity-20'
>
<div className='blur-[106px] h-32 bg-gradient-to-br from-primary to-purple-400 dark:from-blue-700' />
<div className='blur-[106px] h-24 bg-gradient-to-r from-cyan-400 to-sky-300 dark:to-indigo-600' />
</div>
<header className='container pt-8 max-w-xl mx-auto px-4 text-center'>
<header className='container pt-8 max-w-xl mx-auto px-4 text-center z-10 relative'>
<NextLink href='/'>
<h1 className='text-5xl lg:text-8xl font-extrabold mb-3 tracking-tight bg-clip-text text-transparent text-center bg-gradient-to-b from-neutral-900 to-neutral-700'>
SPLASHY
</h1>
</NextLink>

<p className='text-xl'>Get predominant colors for any image.</p>
<p className='text-neutral-600 pt-2'>
<p className='lg:text-xl'>Get predominant colors for any image.</p>
<p className='text-neutral-600 pt-2 flex items-center justify-center'>
Powered by{' '}
<Link href='https://microlink.io'>
<MicrolinkLogo className='inline h-4 mr-2' /> Microlink.io
<MicrolinkLogo className='inline h-4 mx-2' /> Microlink.io
</Link>
</p>
</header>
<main className='pt-8 max-w-xl mx-auto px-4'>{children}</main>
<main className='pt-8 max-w-xl mx-auto px-4 pb-24'>{children}</main>
<Toaster />
<Footer />
</div>
Expand Down
51 changes: 32 additions & 19 deletions website/src/lib/copy-to-clipboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,35 @@ type ToastProps = {

type Toast = (props: ToastProps) => void

export const creatCopyToClipboard =
(toast: Toast) => (text: string, type?: string) => {
navigator.clipboard.writeText(text).then(
() => {
toast({
title: 'Copied to clipboard',
description: `${type} has been copied to your clipboard.`
})
},
err => {
console.error('Could not copy text: ', err)
toast({
title: 'Error',
description: 'Failed to copy to clipboard.',
variant: 'destructive'
})
}
)
}
const toClipboard = async (text: string) => {
if (navigator.clipboard) return navigator.clipboard.writeText(text)
const textArea = document.createElement('textarea')
textArea.value = text
textArea.style.top = '0'
textArea.style.left = '0'
textArea.style.position = 'fixed'
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
document.execCommand('copy')
document.body.removeChild(textArea)
}

export const creatCopyToClipboard = (toast: Toast) => (text: string, type?: string) => {
toClipboard(text).then(
() => {
toast({
title: 'Copied to clipboard',
description: `${type} has been copied to your clipboard.`
})
},
err => {
console.error('Could not copy text: ', err)
toast({
title: 'Error',
description: 'Failed to copy to clipboard.',
variant: 'destructive'
})
}
)
}

0 comments on commit 0cfa969

Please sign in to comment.