diff --git a/client/src/components/ActionButtons.tsx b/client/src/components/ActionButtons.tsx index 2ad4aa5..f2d31b3 100644 --- a/client/src/components/ActionButtons.tsx +++ b/client/src/components/ActionButtons.tsx @@ -4,6 +4,7 @@ import { Heart, X, RotateCcw, Zap } from 'lucide-react'; interface ActionButtonsProps { onLike: () => void; onDislike: () => void; + onSuperLike?: () => void; onReset?: () => void; showReset?: boolean; disabled?: boolean; @@ -12,6 +13,7 @@ interface ActionButtonsProps { export default function ActionButtons({ onLike, onDislike, + onSuperLike, onReset, showReset = false, disabled = false, @@ -69,6 +71,8 @@ export default function ActionButtons({ ([]); + const [superLikedCards, setSuperLikedCards] = useState([]); const [dislikedCards, setDislikedCards] = useState([]); const visibleCards = cards.slice(currentIndex, currentIndex + 3); const isFinished = currentIndex >= cards.length; const handleSwipe = useCallback( - (direction: 'left' | 'right') => { + (direction: 'left' | 'right' | 'super') => { const currentCard = cards[currentIndex]; if (!currentCard) return; if (direction === 'right') { setLikedCards((prev) => [...prev, currentCard]); console.log('Liked:', currentCard.distroName); + } else if (direction === 'super') { + setSuperLikedCards((prev) => [...prev, currentCard]); + setLikedCards((prev) => [...prev, currentCard]); + console.log('Super Liked:', currentCard.distroName); } else { setDislikedCards((prev) => [...prev, currentCard]); console.log('Disliked:', currentCard.distroName); @@ -42,6 +47,23 @@ export default function CardStack({ cards, onBackgroundChange }: CardStackProps) [currentIndex, cards, onBackgroundChange] ); + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (currentIndex >= cards.length) return; + + if (e.key === 'ArrowLeft') { + handleSwipe('left'); + } else if (e.key === 'ArrowRight') { + handleSwipe('right'); + } else if (e.key === 'ArrowUp') { + handleSwipe('super'); + } + }; + + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [handleSwipe, currentIndex, cards.length]); + const handleReset = useCallback(() => { setCurrentIndex(0); setLikedCards([]); @@ -52,7 +74,7 @@ export default function CardStack({ cards, onBackgroundChange }: CardStackProps) }, [cards, onBackgroundChange]); if (isFinished) { - return ; + return ; } return ( @@ -89,6 +111,7 @@ export default function CardStack({ cards, onBackgroundChange }: CardStackProps) handleSwipe('right')} onDislike={() => handleSwipe('left')} + onSuperLike={() => handleSwipe('super')} onReset={handleReset} showReset={currentIndex > 0} disabled={isFinished} diff --git a/client/src/components/EndOfDeck.tsx b/client/src/components/EndOfDeck.tsx index f2b2f44..cb81353 100644 --- a/client/src/components/EndOfDeck.tsx +++ b/client/src/components/EndOfDeck.tsx @@ -1,13 +1,14 @@ import { motion } from 'framer-motion'; -import { PartyPopper, RotateCcw, Download, Trophy, Star, ExternalLink } from 'lucide-react'; +import { RotateCcw, Download, Trophy, Star, ExternalLink, Zap } from 'lucide-react'; import type { DistroCard } from '@/data/distros'; interface EndOfDeckProps { likedCards: DistroCard[]; + superLikedCards: DistroCard[]; onReset: () => void; } -export default function EndOfDeck({ likedCards, onReset }: EndOfDeckProps) { +export default function EndOfDeck({ likedCards, superLikedCards, onReset }: EndOfDeckProps) { return (
-
+
s.id === card.id) ? 'border-cyan-400/50' : 'border-white/10'}`} /> + + {superLikedCards.some(s => s.id === card.id) && ( +
+ + SUPER +
+ )}
-
diff --git a/client/src/components/examples/EndOfDeckExample.tsx b/client/src/components/examples/EndOfDeckExample.tsx index 87b7f90..c3ec8c4 100644 --- a/client/src/components/examples/EndOfDeckExample.tsx +++ b/client/src/components/examples/EndOfDeckExample.tsx @@ -3,11 +3,13 @@ import { distroCards } from '@/data/distros'; export default function EndOfDeckExample() { const likedCards = distroCards.slice(0, 3); + const superLikedCards = distroCards.slice(0, 1); return (
console.log('Reset!')} />
diff --git a/client/src/data/distros.ts b/client/src/data/distros.ts index a41cd48..7864c8e 100644 --- a/client/src/data/distros.ts +++ b/client/src/data/distros.ts @@ -13,6 +13,7 @@ export interface DistroCard { desktopEnvironment: string; tags: string[]; colorPalette: string[]; + downloadUrl: string; } export const distroCards: DistroCard[] = [ @@ -24,6 +25,7 @@ export const distroCards: DistroCard[] = [ desktopEnvironment: 'GNOME', tags: ['beginner-friendly', 'stable', 'popular'], colorPalette: ['#E95420', '#77216F', '#5E2750'], + downloadUrl: 'https://ubuntu.com/download', }, { id: '2', @@ -33,6 +35,7 @@ export const distroCards: DistroCard[] = [ desktopEnvironment: 'i3wm', tags: ['advanced', 'minimal', 'customizable'], colorPalette: ['#1793D1', '#333333', '#0D47A1'], + downloadUrl: 'https://archlinux.org/download/', }, { id: '3', @@ -42,6 +45,7 @@ export const distroCards: DistroCard[] = [ desktopEnvironment: 'Pantheon', tags: ['beautiful', 'simple', 'curated'], colorPalette: ['#64BAFF', '#3689E6', '#0D52BF'], + downloadUrl: 'https://elementary.io/', }, { id: '4', @@ -51,6 +55,7 @@ export const distroCards: DistroCard[] = [ desktopEnvironment: 'KDE Plasma', tags: ['cutting-edge', 'developer', 'reliable'], colorPalette: ['#51A2DA', '#294172', '#3C6EB4'], + downloadUrl: 'https://fedoraproject.org/workstation/download', }, { id: '5', @@ -60,6 +65,7 @@ export const distroCards: DistroCard[] = [ desktopEnvironment: 'Cinnamon', tags: ['familiar', 'stable', 'beginner-friendly'], colorPalette: ['#87CF3E', '#5FAD56', '#3E8E41'], + downloadUrl: 'https://linuxmint.com/download.php', }, { id: '6', @@ -69,5 +75,6 @@ export const distroCards: DistroCard[] = [ desktopEnvironment: 'COSMIC', tags: ['gaming', 'developer', 'modern'], colorPalette: ['#FAA41A', '#48B9C7', '#574F4A'], + downloadUrl: 'https://pop.system76.com/', }, ];