a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere. drydown.social

making cards editable when they should be

+51 -10
+5
src/app.tsx
··· 96 96 <ReviewDashboard 97 97 session={session} 98 98 onCreateNew={handleCreateNew} 99 + onEditReview={(uri, stage) => { 100 + setEditReviewUri(uri) 101 + setEditReviewStage(stage) 102 + setView('edit-review') 103 + }} 99 104 /> 100 105 <button onClick={handleLogout} style={{ marginTop: '2rem' }}>Sign Out</button> 101 106 </>
+20 -7
src/components/ReviewCard.tsx
··· 4 4 review: { uri: string; value: any } 5 5 fragranceName: string 6 6 status: 'ready' | 'inProgress' | 'completed' 7 + onClick?: () => void 7 8 } 8 9 9 - export function ReviewCard({ review, fragranceName, status }: ReviewCardProps) { 10 + export function ReviewCard({ review, fragranceName, status, onClick }: ReviewCardProps) { 10 11 const { value } = review 11 12 12 13 return ( 13 - <div style={{ 14 - border: '1px solid #ddd', 15 - borderRadius: '8px', 16 - padding: '1rem', 17 - marginBottom: '1rem' 18 - }}> 14 + <div 15 + onClick={onClick} 16 + style={{ 17 + border: '1px solid #ddd', 18 + borderRadius: '8px', 19 + padding: '1rem', 20 + marginBottom: '1rem', 21 + cursor: onClick ? 'pointer' : 'default', 22 + backgroundColor: onClick ? '#fff' : '#f9f9f9', // subtle hint 23 + transition: 'background-color 0.2s', 24 + }} 25 + onMouseEnter={(e) => { 26 + if (onClick) e.currentTarget.style.backgroundColor = '#f0f8ff' 27 + }} 28 + onMouseLeave={(e) => { 29 + if (onClick) e.currentTarget.style.backgroundColor = '#fff' 30 + }} 31 + > 19 32 <h4 style={{ margin: '0 0 0.5rem 0', fontSize: '1.1rem' }}> 20 33 {fragranceName} 21 34 </h4>
+22 -2
src/components/ReviewDashboard.tsx
··· 3 3 import { ReviewList } from './ReviewList' 4 4 import type { OAuthSession } from '@atproto/oauth-client-browser' 5 5 6 + import { getAvailableStage } from '../utils/reviewUtils' 7 + 6 8 interface ReviewDashboardProps { 7 9 session: OAuthSession 8 10 onCreateNew: () => void 11 + onEditReview: (uri: string, stage: 'stage2' | 'stage3') => void 9 12 } 10 13 11 - export function ReviewDashboard({ session, onCreateNew }: ReviewDashboardProps) { 14 + export function ReviewDashboard({ session, onCreateNew, onEditReview }: ReviewDashboardProps) { 12 15 const [reviews, setReviews] = useState<Array<{ uri: string; value: any }>>([]) 13 16 const [fragrances, setFragrances] = useState<Map<string, { name: string }>>(new Map()) 14 17 const [isLoading, setIsLoading] = useState(true) ··· 59 62 {isLoading ? ( 60 63 <div>Loading reviews...</div> 61 64 ) : ( 62 - <ReviewList reviews={reviews} fragrances={fragrances} /> 65 + <ReviewList 66 + reviews={reviews} 67 + fragrances={fragrances} 68 + onReviewClick={(review) => { 69 + // Determine the stage to open 70 + let stage = getAvailableStage(review.value) 71 + 72 + // If getAvailableStage returns null (e.g. because it's too early/late or completed), 73 + // we default to the next logical stage based on data presence. 74 + if (!stage) { 75 + if (!review.value.drydownRating) stage = 'stage2' 76 + else if (!review.value.endRating) stage = 'stage3' 77 + else stage = 'stage3' // Fallback for completed reviews if we want to view them 78 + } 79 + 80 + onEditReview(review.uri, stage!) 81 + }} 82 + /> 63 83 )} 64 84 </div> 65 85 )
+4 -1
src/components/ReviewList.tsx
··· 4 4 interface ReviewListProps { 5 5 reviews: Array<{ uri: string; value: any }> 6 6 fragrances: Map<string, { name: string }> 7 + onReviewClick: (review: { uri: string; value: any }) => void 7 8 } 8 9 9 - export function ReviewList({ reviews, fragrances }: ReviewListProps) { 10 + export function ReviewList({ reviews, fragrances, onReviewClick }: ReviewListProps) { 10 11 const { readyToUpdate, inProgress, completed } = categorizeReviews(reviews) 11 12 12 13 const getFragranceName = (fragranceUri: string) => { ··· 26 27 review={review} 27 28 fragranceName={getFragranceName(review.value.fragrance)} 28 29 status="ready" 30 + onClick={() => onReviewClick(review)} 29 31 /> 30 32 ))} 31 33 </section> ··· 42 44 review={review} 43 45 fragranceName={getFragranceName(review.value.fragrance)} 44 46 status="inProgress" 47 + onClick={() => onReviewClick(review)} 45 48 /> 46 49 ))} 47 50 </section>