a tool for shared writing and social publishing

added filters for archive on home, filtered archive out of default leaflet list

+96 -48
+30 -20
app/(home-pages)/home/HomeLayout.tsx
··· 71 71 let hasPubs = !identity || identity.publications.length === 0 ? false : true; 72 72 let hasTemplates = 73 73 useTemplateState((s) => s.templates).length === 0 ? false : true; 74 + let hasArchived = 75 + identity && 76 + identity.permission_token_on_homepage.filter( 77 + (leaflet) => leaflet.archived === true, 78 + ).length > 0; 74 79 75 80 return ( 76 81 <DashboardLayout ··· 89 94 hasBackgroundImage={hasBackgroundImage} 90 95 hasPubs={hasPubs} 91 96 hasTemplates={hasTemplates} 97 + hasArchived={!!hasArchived} 92 98 /> 93 99 ), 94 100 content: ( ··· 287 293 }); 288 294 289 295 let allTemplates = useTemplateState((s) => s.templates); 290 - let filteredLeaflets = sortedLeaflets.filter(({ token: leaflet }) => { 291 - let published = !!leaflet.leaflets_in_publications?.find((l) => l.doc); 292 - let drafts = !!leaflet.leaflets_in_publications?.length && !published; 293 - let docs = !leaflet.leaflets_in_publications?.length; 294 - let templates = !!allTemplates.find((t) => t.id === leaflet.id); 295 - // If no filters are active, show all 296 - if ( 297 - !filter.drafts && 298 - !filter.published && 299 - !filter.docs && 300 - !filter.templates 301 - ) 302 - return true; 296 + let filteredLeaflets = sortedLeaflets.filter( 297 + ({ token: leaflet, archived: archived }) => { 298 + let published = !!leaflet.leaflets_in_publications?.find((l) => l.doc); 299 + let drafts = !!leaflet.leaflets_in_publications?.length && !published; 300 + let docs = !leaflet.leaflets_in_publications?.length; 301 + let templates = !!allTemplates.find((t) => t.id === leaflet.id); 302 + // If no filters are active, show all 303 + if ( 304 + !filter.drafts && 305 + !filter.published && 306 + !filter.docs && 307 + !filter.templates && 308 + !filter.archived 309 + ) 310 + return archived === false || archived === null; 303 311 304 - return ( 305 - (filter.drafts && drafts) || 306 - (filter.published && published) || 307 - (filter.docs && docs) || 308 - (filter.templates && templates) 309 - ); 310 - }); 312 + return ( 313 + (filter.drafts && drafts) || 314 + (filter.published && published) || 315 + (filter.docs && docs) || 316 + (filter.templates && templates) || 317 + (filter.archived && archived) 318 + ); 319 + }, 320 + ); 311 321 if (searchValue === "") return filteredLeaflets; 312 322 let searchedLeaflets = filteredLeaflets.filter(({ token: leaflet }) => { 313 323 return titles[leaflet.root_entity]
+18 -12
app/(home-pages)/home/LeafletList/LeafletInfo.tsx
··· 7 7 import { TemplateSmall } from "components/Icons/TemplateSmall"; 8 8 import { timeAgo } from "src/utils/timeAgo"; 9 9 import { usePublishLink } from "components/ShareOptions"; 10 + import { Separator } from "components/Layout"; 10 11 11 12 export const LeafletInfo = (props: { 12 13 title?: string; ··· 52 53 /> 53 54 </div> 54 55 </div> 55 - {props.draft || props.published ? ( 56 - <div 57 - className={`text-xs ${props.published ? "font-bold text-tertiary" : "text-tertiary"}`} 58 - > 59 - {props.published 60 - ? `Published ${prettyPublishedAt}` 61 - : `Draft ${prettyCreatedAt}`} 62 - </div> 63 - ) : ( 64 - <div className="text-xs text-tertiary">{prettyCreatedAt}</div> 65 - )} 66 - {props.archived && <div className="text-xs text-tertiary">archived</div>} 56 + <div className="flex gap-2 items-center"> 57 + {props.archived ? ( 58 + <div className="text-xs text-tertiary truncate">Archived</div> 59 + ) : props.draft || props.published ? ( 60 + <div 61 + className={`text-xs w-max grow truncate ${props.published ? "font-bold text-tertiary" : "text-tertiary"}`} 62 + > 63 + {props.published 64 + ? `Published ${prettyPublishedAt}` 65 + : `Draft ${prettyCreatedAt}`} 66 + </div> 67 + ) : ( 68 + <div className="text-xs text-tertiary grow w-max truncate"> 69 + {prettyCreatedAt} 70 + </div> 71 + )} 72 + </div> 67 73 {props.isTemplate && props.display === "grid" ? ( 68 74 <div className="absolute -top-2 right-1"> 69 75 <TemplateSmall
+17 -11
app/(home-pages)/home/LeafletList/LeafletListItem.tsx
··· 51 51 if (props.display === "list") 52 52 return ( 53 53 <> 54 - <LeafletLink id={props.token.id}> 54 + <LeafletLink 55 + id={props.token.id} 56 + className={`w-full ${props.isHidden ? "hidden" : "block"}`} 57 + > 55 58 <div 56 59 ref={previewRef} 57 - className={`gap-3 w-full ${props.cardBorderHidden ? "" : "px-2 py-1 block-border hover:outline-border relative"}`} 60 + className={`flex gap-3 w-full ${props.cardBorderHidden ? "" : "px-2 py-1 block-border hover:outline-border relative"}`} 58 61 style={{ 59 62 backgroundColor: props.cardBorderHidden 60 63 ? "transparent" 61 64 : "rgba(var(--bg-page), var(--bg-page-alpha))", 62 - 63 - display: props.isHidden ? "none" : "flex", 64 65 }} 65 66 > 66 67 {props.showPreview && ( ··· 80 81 </> 81 82 ); 82 83 return ( 83 - <LeafletLink id={props.token.id}> 84 + <LeafletLink 85 + id={props.token.id} 86 + className={`leafletGridListItem relative w-full ${props.isHidden ? "hidden" : "flex"}`} 87 + > 84 88 <div 85 89 ref={previewRef} 86 - className={`leafletGridListItem relative 87 - flex flex-col gap-1 p-1 h-52 90 + className={` 91 + flex flex-col gap-1 p-1 h-52 w-full 88 92 block-border border-border! hover:outline-border 89 93 `} 90 94 style={{ 91 95 backgroundColor: props.cardBorderHidden 92 96 ? "transparent" 93 97 : "rgba(var(--bg-page), var(--bg-page-alpha))", 94 - 95 - display: props.isHidden ? "none" : "flex", 96 98 }} 97 99 > 98 100 <div className="grow"> ··· 108 110 ); 109 111 }; 110 112 111 - const LeafletLink = (props: { id: string; children: React.ReactNode }) => { 113 + const LeafletLink = (props: { 114 + id: string; 115 + children: React.ReactNode; 116 + className: string; 117 + }) => { 112 118 return ( 113 119 <SpeedyLink 114 120 href={`/${props.id}`} 115 - className={`no-underline hover:no-underline! text-primary`} 121 + className={`no-underline hover:no-underline! text-primary ${props.className}`} 116 122 > 117 123 {props.children} 118 124 </SpeedyLink>
+1 -3
components/Layout.tsx
··· 6 6 import { useState } from "react"; 7 7 8 8 export const Separator = (props: { classname?: string }) => { 9 - return ( 10 - <div className={`min-h-full border-r border-border ${props.classname}`} /> 11 - ); 9 + return <div className={`h-full border-r border-border ${props.classname}`} />; 12 10 }; 13 11 14 12 export const Menu = (props: {
+30 -2
components/PageLayouts/DashboardLayout.tsx
··· 34 34 published: boolean; 35 35 docs: boolean; 36 36 templates: boolean; 37 + archived: boolean; 37 38 }; 38 39 }; 39 40 ··· 45 46 const defaultDashboardState: DashboardState = { 46 47 display: undefined, 47 48 sort: undefined, 48 - filter: { drafts: false, published: false, docs: false, templates: false }, 49 + filter: { 50 + drafts: false, 51 + published: false, 52 + docs: false, 53 + templates: false, 54 + archived: false, 55 + }, 49 56 }; 50 57 51 58 export const useDashboardStore = create<DashboardStore>((set, get) => ({ ··· 256 263 defaultDisplay: Exclude<DashboardState["display"], undefined>; 257 264 hasPubs: boolean; 258 265 hasTemplates: boolean; 266 + hasArchived: boolean; 259 267 }) => { 260 268 let { display, sort } = useDashboardState(); 261 269 display = display || props.defaultDisplay; ··· 283 291 <FilterOptions 284 292 hasPubs={props.hasPubs} 285 293 hasTemplates={props.hasTemplates} 294 + hasArchived={props.hasArchived} 286 295 /> 287 296 <Separator classname="h-4 min-h-4!" />{" "} 288 297 </> ··· 369 378 ); 370 379 } 371 380 372 - const FilterOptions = (props: { hasPubs: boolean; hasTemplates: boolean }) => { 381 + const FilterOptions = (props: { 382 + hasPubs: boolean; 383 + hasTemplates: boolean; 384 + hasArchived: boolean; 385 + }) => { 373 386 let { filter } = useDashboardState(); 374 387 let setState = useSetDashboardState(); 375 388 let filterCount = Object.values(filter).filter(Boolean).length; ··· 421 434 </Checkbox> 422 435 </> 423 436 )} 437 + 438 + {props.hasArchived && ( 439 + <Checkbox 440 + small 441 + checked={filter.archived} 442 + onChange={(e) => 443 + setState({ 444 + filter: { ...filter, archived: !!e.target.checked }, 445 + }) 446 + } 447 + > 448 + Archived 449 + </Checkbox> 450 + )} 424 451 <Checkbox 425 452 small 426 453 checked={filter.docs} ··· 442 469 published: false, 443 470 drafts: false, 444 471 templates: false, 472 + archived: false, 445 473 }, 446 474 }); 447 475 }}