From 2d26d5d4f9373680adbd99045d32646997ae86b0 Mon Sep 17 00:00:00 2001 From: yusufipk <50673822-yusufipk@users.noreply.replit.com> Date: Wed, 17 Dec 2025 13:42:47 +0000 Subject: [PATCH] Add a super like button and download links for Linux distros Implement a "super like" functionality with a dedicated button and associated UI elements. Add download URLs to distro data and display them on the results screen with download links and visual indicators for super liked items. Add keyboard support for left, right, and up arrow keys to control swiping. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e522d728-b28a-437f-b576-83935afe7ea0 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 393186dc-5528-4239-9955-fe74ab3cb710 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/55e426a8-5a2b-421b-8bd4-30481ae0063b/e522d728-b28a-437f-b576-83935afe7ea0/LaBrqqz Replit-Helium-Checkpoint-Created: true --- client/src/components/ActionButtons.tsx | 4 +++ client/src/components/CardStack.tsx | 29 +++++++++++++++++-- client/src/components/EndOfDeck.tsx | 27 +++++++++++++---- .../components/examples/EndOfDeckExample.tsx | 2 ++ client/src/data/distros.ts | 7 +++++ 5 files changed, 60 insertions(+), 9 deletions(-) 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/', }, ];