Skip to content

Commit

Permalink
ui improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
RodrigoLuglio committed Oct 12, 2024
1 parent 54246a5 commit dde450a
Show file tree
Hide file tree
Showing 16 changed files with 259 additions and 184 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 0 additions & 1 deletion src/app/discover/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { getPublicThemes } from '@/lib/db/themes'

export default async function DiscoverPage() {
const themes = await getPublicThemes()

return (
<div>
<main className="mx-auto container">
Expand Down
8 changes: 5 additions & 3 deletions src/components/Discover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ export default function Discover({ themes }: { themes: SavedTheme[] }) {
const [selectedTheme, setSelectedTheme] = useState(themes[0])
return (
<section className="flex flex-col gap-10 w-full">
<div className="relative py-20">
<div className="relative py-5">
<DotPattern cr={0.5} className="absolute inset-0" />
<div className="h-[350px] flex flex-col items-center justify-center w-full">
<div className="h-[500px] flex flex-col items-center justify-center w-full">
<h1 className="text-5xl font-bold mb-4">Discover new themes</h1>
<h2 className="text-3xl font-semibold text-muted-foreground">
made by the community
</h2>
</div>
</div>
<div className="-mt-36">
<ThemePreviewSmall theme={selectedTheme} />
</div>
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-10">
<div className="mt-10 grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-10">
{themes.map((theme) => (
<ThemeCardPublic
key={theme.id}
Expand Down
11 changes: 10 additions & 1 deletion src/components/SavedThemes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,21 @@ export function SavedThemesContent({
setSelectedTheme(theme)
}

const handleDelete = (themeId: number) => {
setThemes((themes) => themes.filter((theme) => theme.id !== themeId))
}

return (
<section className="flex flex-col gap-10">
<ThemePreviewSmall theme={selectedTheme} />
<div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-4 gap-6">
{themes.map((theme) => (
<ThemeCard key={theme.id} theme={theme} onPreview={handlePreview} />
<ThemeCard
key={theme.id}
theme={theme}
onPreview={handlePreview}
onDelete={handleDelete}
/>
))}
</div>
</section>
Expand Down
166 changes: 102 additions & 64 deletions src/components/ThemeCard.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,53 @@
// src/components/ThemeCard.tsx
'use client'

import React, { useState } from 'react'
import React, { useState, useTransition } from 'react'
import { SavedTheme } from '@/lib/types/colors'
import { Button } from '@/components/ui/button'
import { Switch } from '@/components/ui/switch'
import { Edit, Download, Eye, Share2, Trash2, Loader2 } from 'lucide-react'
import {
updateThemePublicity,
updateThemeType,
deleteTheme,
downloadThemeVSIX,
} from '@/lib/db/themes'
import { useTransition } from 'react'
import { useTheme } from '@/contexts/ThemeContext'

interface ThemeCardProps {
theme: SavedTheme
onPreview: (theme: SavedTheme) => void
onDelete: (themeId: number) => void
}

const ThemeCard: React.FC<ThemeCardProps> = ({ theme, onPreview }) => {
const ThemeCard: React.FC<ThemeCardProps> = ({
theme,
onPreview,
onDelete,
}) => {
const { updateSelectedThemeType, deleteSavedTheme } = useTheme()
const [isPublic, setIsPublic] = useState(theme.public)
const [isPending, startTransition] = useTransition()
const [isDelPending, startDelTransition] = useTransition()
const [isDownPending, startDownTransition] = useTransition()
const [isPublPending, startPublTransition] = useTransition()

const handleDelete = () => {
if (window.confirm('Are you sure you want to delete this theme?')) {
startTransition(async () => {
await deleteTheme(theme.id)
startDelTransition(async () => {
await deleteSavedTheme(theme.id)
onDelete(theme.id)
})
}
}

const handlePublicityToggle = (checked: boolean) => {
startTransition(async () => {
await updateThemePublicity(theme.id, checked)
startPublTransition(async () => {
await updateSelectedThemeType(theme.id, checked)
setIsPublic(checked)
})
}

const handleDownload = () => {
startTransition(async () => {
startDownTransition(async () => {
const vsixBuffer = await downloadThemeVSIX(theme.id)
if (vsixBuffer) {
const blob = new Blob([vsixBuffer], {
Expand All @@ -60,13 +69,38 @@ const ThemeCard: React.FC<ThemeCardProps> = ({ theme, onPreview }) => {
<div
style={{
backgroundColor: theme.uiColors.BG1,
opacity: isPending ? 0.7 : 1,
opacity: isDelPending || isDownPending || isPublPending ? 0.7 : 1,
transition: 'opacity 0.2s',
}}
className="rounded-lg shadow-md overflow-hidden"
onClick={() => onPreview(theme)}
aria-disabled={isPending}
aria-disabled={isDelPending || isDownPending || isPublPending}
>
<div className="h-1 flex">
<div
className="flex-1"
style={{ backgroundColor: theme.uiColors.AC1 }}
/>
<div
className="flex-1"
style={{ backgroundColor: theme.uiColors.AC2 }}
/>
<div
className="flex-1"
style={{ backgroundColor: theme.syntaxColors.variable }}
/>
<div
className="flex-1"
style={{ backgroundColor: theme.syntaxColors.storage }}
/>
<div
className="flex-1"
style={{ backgroundColor: theme.syntaxColors.control }}
/>
<div
className="flex-1"
style={{ backgroundColor: theme.syntaxColors.keyword }}
/>
</div>
<div className="p-4">
<div className="flex justify-between items-center mb-4">
<h3
Expand All @@ -79,62 +113,66 @@ const ThemeCard: React.FC<ThemeCardProps> = ({ theme, onPreview }) => {
<Switch
checked={isPublic}
onCheckedChange={(checked) => handlePublicityToggle(checked)}
disabled={isPending}
disabled={isPublPending}
/>
<span style={{ color: theme.uiColors.FG2 }}>
{theme.public ? 'Public' : 'Private'}
{isPublic ? 'Public' : 'Private'}
</span>
</div>
</div>
<div className="mt-4 flex space-x-2">
<Button
variant="default"
className="flex-1"
// onClick={handleEdit}
disabled={isPending}
>
<Edit className="h-4 w-4 mr-2" /> Edit
</Button>
<Button
variant="outline"
size="icon"
onClick={handleDownload}
disabled={isPending}
>
{isPending ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Download className="h-4 w-4" />
)}
</Button>
<Button
variant="outline"
size="icon"
onClick={() => onPreview(theme)}
disabled={isPending}
>
<Eye className="h-4 w-4" />
</Button>
<Button
variant="outline"
size="icon"
onClick={() => {}} // Implement share functionality here
disabled={isPending}
>
<Share2 className="h-4 w-4" />
</Button>
<Button
variant="destructive"
size="icon"
onClick={handleDelete}
disabled={isPending}
>
{isPending ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Trash2 className="h-4 w-4" />
)}
</Button>
<div className="flex justify-between">
<div className="flex items-center gap-2">
<Button
variant="outline"
size="icon"
onClick={handleDownload}
disabled={isDownPending}
>
{isDownPending ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Download className="h-4 w-4" />
)}
</Button>
<Button
variant="outline"
size="icon"
onClick={() => onPreview(theme)}
// disabled={isPending}
>
<Eye className="h-4 w-4" />
</Button>
<Button
variant="outline"
size="icon"
onClick={() => {}} // Implement share functionality here
// disabled={isPending}
>
<Share2 className="h-4 w-4" />
</Button>
</div>
<div className="flex items-center gap-2">
<Button
variant="default"
className="flex-1"
// onClick={handleEdit}
// disabled={}
>
<Edit className="h-4 w-4 mr-2" /> Edit
</Button>
<Button
variant="destructive"
size="icon"
onClick={handleDelete}
disabled={isDelPending}
>
{isDelPending ? (
<Loader2 className="h-4 w-4 animate-spin" />
) : (
<Trash2 className="h-4 w-4" />
)}
</Button>
</div>
</div>
</div>
</div>
Expand Down
8 changes: 6 additions & 2 deletions src/components/ThemeCardPublic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SavedTheme } from '@/lib/types/colors'
import { Download, Eye, Share2, Loader2 } from 'lucide-react'
import { downloadThemeVSIX } from '@/lib/db/themes'
import { useTransition } from 'react'
import { useUser } from '@clerk/nextjs'

type ThemeCardPublicProps = {
theme: SavedTheme
Expand All @@ -16,6 +17,7 @@ const ThemeCardPublic: React.FC<ThemeCardPublicProps> = ({
theme,
onClick,
}) => {
const { user } = useUser()
const [isPending, startTransition] = useTransition()

const handleDownload = () => {
Expand All @@ -41,7 +43,6 @@ const ThemeCardPublic: React.FC<ThemeCardPublicProps> = ({
<div
style={{ backgroundColor: theme.uiColors.BG1 }}
className="rounded-lg shadow-md overflow-hidden"
onClick={() => onClick(theme)}
>
<div className="h-1 flex">
<div
Expand Down Expand Up @@ -76,6 +77,9 @@ const ThemeCardPublic: React.FC<ThemeCardPublicProps> = ({
>
{theme.name}
</h3>
<h3 style={{ color: theme.uiColors.FG2 }} className="text-sm">
{theme.userName}
</h3>
<div className="mt-2 flex justify-end gap-2">
<Button
variant="outline"
Expand All @@ -89,7 +93,7 @@ const ThemeCardPublic: React.FC<ThemeCardPublicProps> = ({
<Download className="h-4 w-4" />
)}
</Button>
<Button variant="outline" size="icon" onClick={() => {}}>
<Button variant="outline" size="icon" onClick={() => onClick(theme)}>
<Eye className="h-4 w-4" />
</Button>
<Button variant="outline" size="icon" onClick={() => {}}>
Expand Down
12 changes: 9 additions & 3 deletions src/components/ThemeControls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,20 @@ import ThemeSaver from './ThemeSaver'

import { ColorScheme } from '@/lib/types/colors'
import { randomInteger } from '@/lib/utils/math'
import ThemeLoader from './ThemeLoader'
import { ThemeLoader } from './ThemeLoader'

const ThemeControls: React.FC = () => {
const [themeName, setThemeName] = useState<string>('')

const {
isDark,
isPublic,
baseHue,
scheme,
uiSaturation,
syntaxSaturation,
lockedColors,
setIsPublic,
setBaseHue,
setUiSaturation,
setSyntaxSaturation,
Expand Down Expand Up @@ -65,6 +69,8 @@ const ThemeControls: React.FC = () => {
setSyntaxSaturation(newSyntaxSaturation)
setScheme(newScheme)
setCurrentThemeId(null)
setThemeName('')
setIsPublic(false)

// Then generate colors with these new values
generateColors({
Expand Down Expand Up @@ -351,15 +357,15 @@ const ThemeControls: React.FC = () => {
<div className="flex flex-col justify-between gap-2">
<Tooltip>
<TooltipTrigger asChild>
<ThemeLoader />
<ThemeLoader setThemeName={setThemeName} />
</TooltipTrigger>
<TooltipContent>
<p>Load a theme from your saved themes</p>
</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<ThemeSaver />
<ThemeSaver themeName={themeName} setThemeName={setThemeName} />
</TooltipTrigger>
<TooltipContent>
<p>Save the current theme to your themes</p>
Expand Down
Loading

0 comments on commit dde450a

Please sign in to comment.