Scrapboard.org client

fix: make boards grid

TurtlePaw 8ac448ab 9f4500e4

+39 -24
+23 -15
src/app/boards/page.tsx
··· 7 7 import Image, { ImageProps } from "next/image"; 8 8 import Link from "next/link"; 9 9 import { motion } from "motion/react"; 10 + import Masonry from "react-masonry-css"; 11 + import { breakpointColumnsObj } from "@/components/Feed"; 10 12 11 13 export const runtime = "edge"; 12 14 ··· 36 38 {/* Container that adapts to image width */} 37 39 <div className="w-full max-w-4xl flex justify-center"> 38 40 <div className="inline-block"> 39 - {Array.from(boards.entries()).map(([key, it]) => ( 40 - <Link href={`/board/${agent?.did ?? "unknown"}/${key}`} key={key}> 41 - <motion.div 42 - initial={{ opacity: 0, y: 2 }} 43 - animate={{ opacity: 1, y: 0 }} 44 - transition={{ duration: 0.5, ease: "easeOut" }} 45 - whileTap={{ scale: 0.95 }} 46 - className="bg-black/10 dark:bg-white/3 p-4 rounded-lg m-2 hover:bg-black/15 dark:hover:bg-white/5 min-w-lg min-h-2/5 transition-colors" 41 + <div className="grid grid-cols-1 md:grid-cols-4 gap-3"> 42 + {Array.from(boards.entries()).map(([key, it]) => ( 43 + <Link 44 + href={`/board/${agent?.did ?? "unknown"}/${key}`} 45 + key={key} 46 + className="h-full" 47 47 > 48 - <h2 className="font-medium text-lg">{it.name}</h2> 49 - <p className="text-sm text-black/80 dark:text-white/80"> 50 - {truncateString(it.description, 50)} 51 - </p> 52 - </motion.div> 53 - </Link> 54 - ))} 48 + <motion.div 49 + initial={{ opacity: 0, y: 2 }} 50 + animate={{ opacity: 1, y: 0 }} 51 + transition={{ duration: 0.3, ease: "easeOut" }} 52 + whileTap={{ scale: 0.95 }} 53 + className="flex flex-col h-full bg-black/10 dark:bg-white/3 p-4 rounded-lg hover:bg-black/15 dark:hover:bg-white/5 transition-colors" 54 + > 55 + <h2 className="font-medium text-lg">{it.name}</h2> 56 + <p className="text-sm text-black/80 dark:text-white/80 mt-1 line-clamp-2"> 57 + {it.description} 58 + </p> 59 + </motion.div> 60 + </Link> 61 + ))} 62 + </div> 55 63 </div> 56 64 </div> 57 65 </div>
+5 -1
src/components/BoardPicker.tsx
··· 19 19 PopoverTrigger, 20 20 } from "@/components/ui/popover"; 21 21 import { Board } from "@/lib/stores/boards"; 22 + import clsx from "clsx"; 22 23 23 24 export function BoardsPicker({ 24 25 boards, ··· 47 48 variant="outline" 48 49 role="combobox" 49 50 aria-expanded={open} 50 - className="w-full justify-between" 51 + className={clsx( 52 + "w-full justify-between", 53 + selectedBoard ? "dark:text-white text-black" : "" 54 + )} 51 55 > 52 56 {selectedBoard ? selectedBoard.name : "Select board..."} 53 57 <ChevronsUpDownIcon className="ml-2 h-4 w-4 shrink-0 opacity-50" />
+8 -8
src/components/Feed.tsx
··· 174 174 return map; 175 175 } 176 176 177 + export const breakpointColumnsObj = { 178 + default: 5, 179 + 1536: 4, 180 + 1280: 3, 181 + 1024: 2, 182 + 768: 1, 183 + }; 184 + 177 185 export function Feed({ 178 186 feed, 179 187 isLoading = false, 180 188 showUnsaveButton = false, 181 189 onUnsave, 182 190 }: FeedProps) { 183 - const breakpointColumnsObj = { 184 - default: 5, 185 - 1536: 4, 186 - 1280: 3, 187 - 1024: 2, 188 - 768: 1, 189 - }; 190 - 191 191 return ( 192 192 <> 193 193 <Masonry
+3
src/nav/footer.tsx
··· 1 + export function Footer() { 2 + return <footer className=""></footer>; 3 + }