a tool for shared writing and social publishing
at feature/reader 148 lines 7.7 kB view raw
1"use client"; 2import Link from "next/link"; 3import { useState } from "react"; 4import { theme } from "tailwind.config"; 5import { PublicationsList } from "./page"; 6import { PubListing } from "./PubListing"; 7 8export function SortedPublicationList(props: { 9 publications: PublicationsList; 10 order: string; 11}) { 12 let [order, setOrder] = useState(props.order); 13 return ( 14 <div className="discoverHeader flex flex-col items-center "> 15 <SortButtons 16 order={order} 17 setOrder={(o) => { 18 const url = new URL(window.location.href); 19 url.searchParams.set("order", o); 20 window.history.pushState({}, "", url); 21 setOrder(o); 22 }} 23 /> 24 <div className="discoverPubList flex flex-col gap-3 pt-6 w-full"> 25 {props.publications 26 ?.filter((pub) => pub.documents_in_publications.length > 0) 27 ?.sort((a, b) => { 28 if (order === "popular") { 29 return ( 30 b.publication_subscriptions[0].count - 31 a.publication_subscriptions[0].count 32 ); 33 } 34 const aDate = new Date( 35 a.documents_in_publications[0]?.indexed_at || 0, 36 ); 37 const bDate = new Date( 38 b.documents_in_publications[0]?.indexed_at || 0, 39 ); 40 return bDate.getTime() - aDate.getTime(); 41 }) 42 .map((pub) => <PubListing resizeHeight key={pub.uri} {...pub} />)} 43 </div> 44 </div> 45 ); 46} 47 48export default function SortButtons(props: { 49 order: string; 50 setOrder: (order: string) => void; 51}) { 52 const [selected, setSelected] = useState<"recentlyUpdated" | "popular">( 53 "recentlyUpdated", 54 ); 55 56 return ( 57 <div className="flex gap-2 pt-1"> 58 <SortButton 59 selected={props.order === "recentlyUpdated"} 60 onClick={() => props.setOrder("recentlyUpdated")} 61 > 62 Recently Updated 63 </SortButton> 64 65 <SortButton 66 selected={props.order === "popular"} 67 onClick={() => props.setOrder("popular")} 68 > 69 Popular 70 </SortButton> 71 </div> 72 ); 73} 74 75const SortButton = (props: { 76 children: React.ReactNode; 77 onClick: () => void; 78 selected: boolean; 79}) => { 80 return ( 81 <div className="relative"> 82 <button 83 onClick={props.onClick} 84 style={ 85 props.selected 86 ? { backgroundColor: `rgba(var(--accent-1), 0.2)` } 87 : {} 88 } 89 className={`text-sm rounded-md px-[8px] py-0.5 border ${props.selected ? "border-accent-contrast text-accent-1 font-bold" : "text-tertiary border-border-light"}`} 90 > 91 {props.children} 92 </button> 93 {props.selected && ( 94 <> 95 <div className="absolute top-0 -left-2"> 96 <GlitterBig /> 97 </div> 98 <div className="absolute top-4 left-0"> 99 <GlitterSmall /> 100 </div> 101 <div className="absolute -top-2 -right-1"> 102 <GlitterSmall /> 103 </div> 104 </> 105 )} 106 </div> 107 ); 108}; 109 110const GlitterBig = () => { 111 return ( 112 <svg 113 width="16" 114 height="17" 115 viewBox="0 0 16 17" 116 fill="none" 117 xmlns="http://www.w3.org/2000/svg" 118 > 119 <path 120 d="M8.16553 0.804321C8.5961 0.804329 8.97528 1.03925 9.22803 1.40393C9.47845 1.76546 9.6128 2.25816 9.61279 2.84338C9.61279 2.98187 9.6178 3.11647 9.62646 3.2467C9.65365 3.65499 9.72104 4.02319 9.81006 4.35022C10.0833 5.35388 10.5641 5.96726 10.7349 6.14221C10.7443 6.15184 10.7543 6.16234 10.7642 6.17249C10.9808 6.39533 11.3925 6.8162 12.0142 7.09338C12.206 7.17892 12.4177 7.2502 12.6489 7.29749C12.8402 7.3366 13.0466 7.35993 13.2681 7.35999H13.269C14.2688 7.36032 14.9747 7.96603 14.9771 8.77014C14.9793 9.57755 14.272 10.1833 13.2681 10.1832C13.0278 10.1832 12.8137 10.2034 12.6226 10.2369C12.3793 10.2796 12.1697 10.3455 11.9858 10.4254C11.4714 10.6492 11.1325 10.9918 10.7935 11.3405C10.7739 11.3605 10.7544 11.381 10.7349 11.401C10.3936 11.7507 10.0271 12.1792 9.81006 12.9352C9.72175 13.2428 9.65679 13.6119 9.63135 14.0592C9.62378 14.1924 9.61963 14.3325 9.61963 14.4801C9.61963 15.5836 9.06909 16.4876 8.17822 16.4996C7.74928 16.5053 7.36767 16.2783 7.11182 15.9147C6.85918 15.5556 6.72412 15.065 6.72412 14.4801C6.72412 14.3385 6.71808 14.2015 6.70654 14.069C6.6724 13.6774 6.59177 13.324 6.48779 13.0123C6.16402 12.0419 5.61395 11.4722 5.54443 11.401C5.54371 11.4003 5.54043 11.3977 5.53467 11.3922C5.52778 11.3857 5.51839 11.3767 5.50635 11.3658C5.4823 11.3442 5.44954 11.3158 5.40869 11.2819C5.3268 11.2139 5.21473 11.1255 5.07764 11.0289C4.80173 10.8346 4.43374 10.6113 4.01611 10.443C3.82579 10.3663 3.62728 10.3019 3.42432 10.2565C3.21687 10.21 3.00599 10.1832 2.79541 10.1832C1.79834 10.1832 1.11533 9.56575 1.11865 8.76917C1.12219 7.9773 1.80451 7.36002 2.79541 7.35999C3.01821 7.35999 3.22798 7.33422 3.42432 7.29065C3.62557 7.24597 3.81426 7.18216 3.98877 7.10608C4.6567 6.81484 5.10772 6.35442 5.3042 6.15295C5.30777 6.1493 5.31147 6.14577 5.31494 6.14221C5.51076 5.94157 6.14024 5.28964 6.48584 4.26233C6.59001 3.95264 6.66793 3.60887 6.70068 3.23303C6.71166 3.10697 6.71826 2.977 6.71826 2.84338L6.72412 2.62854C6.75331 2.13723 6.88387 1.72031 7.10303 1.40393C7.35578 1.03923 7.73495 0.804326 8.16553 0.804321Z" 121 fill={theme.colors["accent-1"]} 122 stroke={theme.colors["bg-leaflet"]} 123 strokeLinecap="round" 124 strokeLinejoin="round" 125 /> 126 </svg> 127 ); 128}; 129 130const GlitterSmall = () => { 131 return ( 132 <svg 133 width="13" 134 height="14" 135 viewBox="0 0 13 14" 136 fill="none" 137 xmlns="http://www.w3.org/2000/svg" 138 > 139 <path 140 d="M6.37585 1.23596C6.7489 1.23598 7.07064 1.44034 7.28015 1.7428C7.48716 2.04187 7.59266 2.4408 7.59265 2.901C7.59266 3.00294 7.59605 3.10213 7.60242 3.19788C7.62244 3.49844 7.67183 3.76938 7.73718 4.0094C7.93813 4.74731 8.29123 5.1934 8.4071 5.31213L8.57703 5.48206C8.75042 5.64731 9.00188 5.85577 9.33777 6.00549C9.47565 6.06695 9.62723 6.11812 9.79285 6.15198C9.92991 6.18 10.0779 6.1959 10.2372 6.19592C11.0418 6.19604 11.6503 6.69195 11.6522 7.38538C11.654 8.08176 11.0444 8.57683 10.2372 8.57678C10.0618 8.57678 9.90679 8.59077 9.76941 8.61487C9.59484 8.6455 9.4456 8.69297 9.31531 8.74963C8.95055 8.9083 8.70884 9.15057 8.45203 9.41467C8.43719 9.42993 8.42207 9.44621 8.4071 9.46155C8.15582 9.71904 7.89358 10.0262 7.73718 10.5709C7.67315 10.7941 7.62512 11.064 7.60632 11.3942C7.60073 11.4925 7.59754 11.5963 7.59753 11.7057C7.59753 12.5657 7.16303 13.3455 6.38757 13.3561C6.01608 13.3611 5.6911 13.1642 5.47839 12.8619C5.26902 12.5643 5.16394 12.1657 5.16394 11.7057C5.16393 11.6022 5.15871 11.5017 5.15027 11.4049C5.1253 11.1189 5.06701 10.861 4.99109 10.6334C4.75475 9.92518 4.35324 9.51044 4.30554 9.46155C4.30554 9.46155 4.27494 9.43195 4.21179 9.37952C4.15207 9.32993 4.06961 9.26511 3.96863 9.19397C3.76515 9.05064 3.49524 8.88718 3.19031 8.76428C3.05151 8.70835 2.90782 8.66129 2.7616 8.62854C2.61218 8.59509 2.4616 8.57679 2.31238 8.57678C1.50706 8.57678 0.918891 8.07006 0.921753 7.3844C0.924612 6.70329 1.51125 6.19594 2.31238 6.19592C2.47154 6.19591 2.6213 6.17821 2.7616 6.14709C2.90554 6.11514 3.04128 6.06904 3.16687 6.01428C3.64904 5.80395 3.97684 5.47074 4.1239 5.31995C4.12648 5.3173 4.12918 5.31473 4.13171 5.31213C4.27635 5.16393 4.73656 4.68608 4.98914 3.93518C5.06511 3.70931 5.12247 3.45905 5.14636 3.18518C5.15436 3.09338 5.15905 2.99838 5.15906 2.901C5.15906 2.44078 5.26453 2.04187 5.47156 1.7428C5.68108 1.44033 6.00279 1.23595 6.37585 1.23596Z" 141 fill={theme.colors["accent-1"]} 142 stroke={theme.colors["bg-leaflet"]} 143 strokeLinecap="round" 144 strokeLinejoin="round" 145 /> 146 </svg> 147 ); 148};