Coves frontend - a photon fork
at main 171 lines 5.1 kB view raw
1<script lang="ts"> 2 // @ts-nocheck TODO(coves-migration): Needs Coves instance/site info API 3 import type { PersonView, SiteView, Tagline } from '$lib/api/types' 4 import { t } from '$lib/app/i18n' 5 import Markdown from '$lib/app/markdown/Markdown.svelte' 6 import { settings } from '$lib/app/settings.svelte' 7 import { userLink } from '$lib/app/util.svelte' 8 import EntityHeader from '$lib/ui/generic/EntityHeader.svelte' 9 import ItemList from '$lib/ui/generic/ItemList.svelte' 10 import LabelStat from '$lib/ui/info/LabelStat.svelte' 11 import EndPlaceholder from '$lib/ui/layout/EndPlaceholder.svelte' 12 import SidebarButton from '$lib/ui/sidebar/SidebarButton.svelte' 13 import { Badge, Expandable, Popover } from 'mono-svelte' 14 import { 15 BuildingOffice, 16 Icon, 17 Newspaper, 18 ServerStack, 19 } from 'svelte-hero-icons/dist' 20 import type { ClassValue, HTMLAttributes } from 'svelte/elements' 21 22 interface Props extends HTMLAttributes<HTMLDivElement> { 23 site: SiteView 24 taglines?: Tagline[] 25 admins?: PersonView[] 26 version?: string 27 class?: ClassValue 28 } 29 30 let { site, taglines, admins, version, class: clazz = '' }: Props = $props() 31</script> 32 33<aside 34 class={[ 35 'w-full text-slate-600 dark:text-zinc-400 flex flex-col gap-4 text-sm', 36 clazz, 37 ]} 38> 39 <EntityHeader 40 name={site.site.name} 41 avatar={site.site.icon} 42 banner={site.site.banner || null} 43 compact="always" 44 avatarCircle={false} 45 /> 46 <div class="flex flex-col gap-1"> 47 {#if taglines && taglines.length > 0} 48 <Markdown 49 class="px-3" 50 source={taglines[Math.floor(Math.random() * taglines.length)].content} 51 /> 52 {/if} 53 54 <EndPlaceholder size="xs" margin="sm"> 55 {$t('nav.menu.instance')} 56 </EndPlaceholder> 57 <SidebarButton 58 href="/modlog" 59 label={$t('routes.modlog.title')} 60 icon={Newspaper} 61 /> 62 <SidebarButton 63 href="/legal" 64 label={$t('routes.legal.title')} 65 icon={BuildingOffice} 66 /> 67 <SidebarButton 68 href="/instances" 69 label={$t('routes.instances')} 70 icon={ServerStack} 71 /> 72 73 <EndPlaceholder size="xs" margin="sm"> 74 {$t('cards.site.stats')} 75 </EndPlaceholder> 76 <div class="flex flex-row gap-4 flex-wrap px-3"> 77 <LabelStat 78 label={$t('content.users')} 79 content={site.counts.users.toString()} 80 formatted 81 /> 82 <LabelStat 83 label={$t('content.posts')} 84 content={site.counts.posts.toString()} 85 formatted 86 /> 87 <LabelStat 88 label={$t('content.comments')} 89 content={site.counts.comments.toString()} 90 formatted 91 /> 92 <Popover openOnHover placement="bottom-end"> 93 {#snippet target(attachment)} 94 <button class="text-left cursor-pointer" {@attach attachment}> 95 <LabelStat 96 label={$t('cards.community.activeDay')} 97 content={site.counts.users_active_day.toString()} 98 formatted 99 /> 100 </button> 101 {/snippet} 102 <div class="flex flex-row gap-4 flex-wrap px-3"> 103 <LabelStat 104 label={$t('filter.sort.top.time.week')} 105 content={site.counts.users_active_week.toString()} 106 formatted 107 /> 108 <LabelStat 109 label={$t('filter.sort.top.time.month')} 110 content={site.counts.users_active_month.toString()} 111 formatted 112 /> 113 <LabelStat 114 label={$t('filter.sort.top.time.6months')} 115 content={site.counts.users_active_half_year.toString()} 116 formatted 117 /> 118 </div> 119 </Popover> 120 <LabelStat 121 label={$t('content.communities')} 122 content={site.counts.communities.toString()} 123 formatted 124 /> 125 </div> 126 127 <EndPlaceholder size="xs" margin="sm"> 128 {$t('common.info')} 129 </EndPlaceholder> 130 <div class="space-y-3 px-1.5 text-sm"> 131 <Expandable bind:open={settings.expand.about}> 132 {#snippet title()} 133 <span class="flex items-center gap-1 py-1 px-2 w-full"> 134 {$t('cards.site.about')} 135 </span> 136 {/snippet} 137 <Markdown source={site.site.description} /> 138 <div class="my-4"></div> 139 <Markdown source={site.site.sidebar} /> 140 141 {#if version} 142 <div class="w-max"> 143 <Badge label="Lemmy version"> 144 <Icon src={ServerStack} micro size="14" /> 145 {version} 146 </Badge> 147 </div> 148 {/if} 149 </Expandable> 150 151 {#if admins} 152 <Expandable bind:open={settings.expand.team}> 153 {#snippet title()} 154 <span class="flex items-center gap-1 py-1 px-2 w-full"> 155 {$t('cards.site.admins')} 156 </span> 157 {/snippet} 158 <ItemList 159 items={admins.map((i) => ({ 160 id: i.person.id, 161 name: i.person.display_name || i.person.name, 162 url: userLink(i.person), 163 avatar: i.person.avatar, 164 instance: new URL(i.person.actor_id).hostname, 165 }))} 166 /> 167 </Expandable> 168 {/if} 169 </div> 170 </div> 171</aside>