forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
1{{ define "title" }}{{ or .Card.UserHandle .Card.UserDid }}{{ end }} 2 3{{ define "extrameta" }} 4 <meta property="og:title" content="{{ or .Card.UserHandle .Card.UserDid }}" /> 5 <meta property="og:type" content="profile" /> 6 <meta property="og:url" content="https://tangled.sh/{{ or .Card.UserHandle .Card.UserDid }}" /> 7 <meta property="og:description" content="{{ or .Card.Profile.Description .Card.UserHandle .Card.UserDid }}" /> 8{{ end }} 9 10{{ define "content" }} 11<div class="grid grid-cols-1 md:grid-cols-11 gap-4"> 12 <div class="md:col-span-3 order-1 md:order-1"> 13 <div class="grid grid-cols-1 gap-4"> 14 {{ template "user/fragments/profileCard" .Card }} 15 {{ block "punchcard" .Punchcard }} {{ end }} 16 </div> 17 </div> 18 <div id="all-repos" class="md:col-span-4 order-2 md:order-2"> 19 <div class="grid grid-cols-1 gap-4"> 20 {{ block "ownRepos" . }}{{ end }} 21 {{ block "collaboratingRepos" . }}{{ end }} 22 </div> 23 </div> 24 <div class="md:col-span-4 order-3 md:order-3"> 25 {{ block "profileTimeline" . }}{{ end }} 26 </div> 27</div> 28{{ end }} 29 30{{ define "profileTimeline" }} 31 <p class="text-sm font-bold p-2 dark:text-white">ACTIVITY</p> 32 <div class="flex flex-col gap-4 relative"> 33 {{ with .ProfileTimeline }} 34 {{ range $idx, $byMonth := .ByMonth }} 35 {{ with $byMonth }} 36 <div class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm"> 37 {{ if eq $idx 0 }} 38 39 {{ else }} 40 {{ $s := "s" }} 41 {{ if eq $idx 1 }} 42 {{ $s = "" }} 43 {{ end }} 44 <p class="text-sm font-bold dark:text-white mb-2">{{$idx}} month{{$s}} ago</p> 45 {{ end }} 46 47 {{ if .IsEmpty }} 48 <div class="text-gray-500 dark:text-gray-400"> 49 No activity for this month 50 </div> 51 {{ else }} 52 <div class="flex flex-col gap-1"> 53 {{ block "repoEvents" .RepoEvents }} {{ end }} 54 {{ block "issueEvents" .IssueEvents }} {{ end }} 55 {{ block "pullEvents" .PullEvents }} {{ end }} 56 </div> 57 {{ end }} 58 </div> 59 60 {{ end }} 61 {{ else }} 62 <p class="dark:text-white">This user does not have any activity yet.</p> 63 {{ end }} 64 {{ end }} 65 </div> 66{{ end }} 67 68{{ define "repoEvents" }} 69 {{ if gt (len .) 0 }} 70 <details> 71 <summary class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 72 <div class="flex flex-wrap items-center gap-2"> 73 {{ i "book-plus" "w-4 h-4" }} 74 created {{ len . }} {{if eq (len .) 1 }}repository{{else}}repositories{{end}} 75 </div> 76 </summary> 77 <div class="py-2 text-sm flex flex-col gap-3 mb-2"> 78 {{ range . }} 79 <div class="flex flex-wrap items-center gap-2"> 80 <span class="text-gray-500 dark:text-gray-400"> 81 {{ if .Source }} 82 {{ i "git-fork" "w-4 h-4" }} 83 {{ else }} 84 {{ i "book-plus" "w-4 h-4" }} 85 {{ end }} 86 </span> 87 <a href="/{{ resolve .Repo.Did }}/{{ .Repo.Name }}" class="no-underline hover:underline"> 88 {{- .Repo.Name -}} 89 </a> 90 </div> 91 {{ end }} 92 </div> 93 </details> 94 {{ end }} 95{{ end }} 96 97{{ define "issueEvents" }} 98 {{ $items := .Items }} 99 {{ $stats := .Stats }} 100 101 {{ if gt (len $items) 0 }} 102 <details> 103 <summary class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 104 <div class="flex flex-wrap items-center gap-2"> 105 {{ i "circle-dot" "w-4 h-4" }} 106 107 <div> 108 created {{ len $items }} {{if eq (len $items) 1 }}issue{{else}}issues{{end}} 109 </div> 110 111 {{ if gt $stats.Open 0 }} 112 <span class="px-2 py-1/2 text-sm rounded text-white bg-green-600 dark:bg-green-700"> 113 {{$stats.Open}} open 114 </span> 115 {{ end }} 116 117 {{ if gt $stats.Closed 0 }} 118 <span class="px-2 py-1/2 text-sm rounded text-white bg-gray-800 dark:bg-gray-700"> 119 {{$stats.Closed}} closed 120 </span> 121 {{ end }} 122 123 </div> 124 </summary> 125 <div class="py-2 text-sm flex flex-col gap-3 mb-2"> 126 {{ range $items }} 127 {{ $repoOwner := resolve .Metadata.Repo.Did }} 128 {{ $repoName := .Metadata.Repo.Name }} 129 {{ $repoUrl := printf "%s/%s" $repoOwner $repoName }} 130 131 <div class="flex gap-2 text-gray-600 dark:text-gray-300"> 132 {{ if .Open }} 133 <span class="text-green-600 dark:text-green-500"> 134 {{ i "circle-dot" "w-4 h-4" }} 135 </span> 136 {{ else }} 137 <span class="text-gray-500 dark:text-gray-400"> 138 {{ i "ban" "w-4 h-4" }} 139 </span> 140 {{ end }} 141 <div class="flex-none min-w-8 text-right"> 142 <span class="text-gray-500 dark:text-gray-400">#{{ .IssueId }}</span> 143 </div> 144 <div class="break-words max-w-full"> 145 <a href="/{{$repoUrl}}/issues/{{ .IssueId }}" class="no-underline hover:underline"> 146 {{ .Title -}} 147 </a> 148 on 149 <a href="/{{$repoUrl}}" class="no-underline hover:underline whitespace-nowrap"> 150 {{$repoUrl}} 151 </a> 152 </div> 153 </div> 154 {{ end }} 155 </div> 156 </details> 157 {{ end }} 158{{ end }} 159 160{{ define "pullEvents" }} 161 {{ $items := .Items }} 162 {{ $stats := .Stats }} 163 {{ if gt (len $items) 0 }} 164 <details> 165 <summary class="list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400"> 166 <div class="flex flex-wrap items-center gap-2"> 167 {{ i "git-pull-request" "w-4 h-4" }} 168 169 <div> 170 created {{ len $items }} {{if eq (len $items) 1 }}pull request{{else}}pull requests{{end}} 171 </div> 172 173 {{ if gt $stats.Open 0 }} 174 <span class="px-2 py-1/2 text-sm rounded text-white bg-green-600 dark:bg-green-700"> 175 {{$stats.Open}} open 176 </span> 177 {{ end }} 178 179 {{ if gt $stats.Merged 0 }} 180 <span class="px-2 py-1/2 text-sm rounded text-white bg-purple-600 dark:bg-purple-700"> 181 {{$stats.Merged}} merged 182 </span> 183 {{ end }} 184 185 186 {{ if gt $stats.Closed 0 }} 187 <span class="px-2 py-1/2 text-sm rounded text-white bg-gray-800 dark:bg-gray-700"> 188 {{$stats.Closed}} closed 189 </span> 190 {{ end }} 191 192 </div> 193 </summary> 194 <div class="py-2 text-sm flex flex-col gap-3 mb-2"> 195 {{ range $items }} 196 {{ $repoOwner := resolve .Repo.Did }} 197 {{ $repoName := .Repo.Name }} 198 {{ $repoUrl := printf "%s/%s" $repoOwner $repoName }} 199 200 <div class="flex gap-2 text-gray-600 dark:text-gray-300"> 201 {{ if .State.IsOpen }} 202 <span class="text-green-600 dark:text-green-500"> 203 {{ i "git-pull-request" "w-4 h-4" }} 204 </span> 205 {{ else if .State.IsMerged }} 206 <span class="text-purple-600 dark:text-purple-500"> 207 {{ i "git-merge" "w-4 h-4" }} 208 </span> 209 {{ else }} 210 <span class="text-gray-600 dark:text-gray-300"> 211 {{ i "git-pull-request-closed" "w-4 h-4" }} 212 </span> 213 {{ end }} 214 <div class="flex-none min-w-8 text-right"> 215 <span class="text-gray-500 dark:text-gray-400">#{{ .PullId }}</span> 216 </div> 217 <div class="break-words max-w-full"> 218 <a href="/{{$repoUrl}}/pulls/{{ .PullId }}" class="no-underline hover:underline"> 219 {{ .Title -}} 220 </a> 221 on 222 <a href="/{{$repoUrl}}" class="no-underline hover:underline whitespace-nowrap"> 223 {{$repoUrl}} 224 </a> 225 </div> 226 </div> 227 {{ end }} 228 </div> 229 </details> 230 {{ end }} 231{{ end }} 232 233{{ define "ownRepos" }} 234 <div> 235 <div class="text-sm font-bold p-2 pr-0 dark:text-white flex items-center justify-between gap-2"> 236 <a href="/@{{ or $.Card.UserHandle $.Card.UserDid }}?tab=repos" 237 class="flex text-black dark:text-white items-center gap-2 no-underline hover:no-underline group"> 238 <span>PINNED REPOS</span> 239 <span class="flex gap-1 items-center font-normal text-sm text-gray-500 dark:text-gray-400 "> 240 view all {{ i "chevron-right" "w-4 h-4" }} 241 </span> 242 </a> 243 {{ if and .LoggedInUser (eq .LoggedInUser.Did .Card.UserDid) }} 244 <button 245 hx-get="profile/edit-pins" 246 hx-target="#all-repos" 247 class="btn py-0 font-normal text-sm flex gap-2 items-center group"> 248 {{ i "pencil" "w-3 h-3" }} 249 edit 250 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 251 </button> 252 {{ end }} 253 </div> 254 <div id="repos" class="grid grid-cols-1 gap-4 items-stretch"> 255 {{ range .Repos }} 256 {{ template "user/fragments/repoCard" (list $ . false) }} 257 {{ else }} 258 <p class="px-6 dark:text-white">This user does not have any repos yet.</p> 259 {{ end }} 260 </div> 261 </div> 262{{ end }} 263 264{{ define "collaboratingRepos" }} 265 {{ if gt (len .CollaboratingRepos) 0 }} 266 <div> 267 <p class="text-sm font-bold p-2 dark:text-white">COLLABORATING ON</p> 268 <div id="collaborating" class="grid grid-cols-1 gap-4"> 269 {{ range .CollaboratingRepos }} 270 {{ template "user/fragments/repoCard" (list $ . true) }} 271 {{ else }} 272 <p class="px-6 dark:text-white">This user is not collaborating.</p> 273 {{ end }} 274 </div> 275 </div> 276 {{ end }} 277{{ end }} 278 279{{ define "punchcard" }} 280 {{ $now := now }} 281 <div> 282 <p class="p-2 flex gap-2 text-sm font-bold dark:text-white"> 283 PUNCHCARD 284 <span class="font-normal text-sm text-gray-500 dark:text-gray-400 "> 285 {{ .Total | int64 | commaFmt }} commits 286 </span> 287 </p> 288 <div class="bg-white dark:bg-gray-800 px-6 py-4 rounded drop-shadow-sm"> 289 <div class="grid grid-cols-28 md:grid-cols-14 gap-y-2 w-full h-full"> 290 {{ range .Punches }} 291 {{ $count := .Count }} 292 {{ $theme := "bg-gray-200 dark:bg-gray-700 size-[4px]" }} 293 {{ if lt $count 1 }} 294 {{ $theme = "bg-gray-200 dark:bg-gray-700 size-[4px]" }} 295 {{ else if lt $count 2 }} 296 {{ $theme = "bg-green-200 dark:bg-green-900 size-[5px]" }} 297 {{ else if lt $count 4 }} 298 {{ $theme = "bg-green-300 dark:bg-green-800 size-[5px]" }} 299 {{ else if lt $count 8 }} 300 {{ $theme = "bg-green-400 dark:bg-green-700 size-[6px]" }} 301 {{ else }} 302 {{ $theme = "bg-green-500 dark:bg-green-600 size-[7px]" }} 303 {{ end }} 304 305 {{ if .Date.After $now }} 306 {{ $theme = "border border-gray-200 dark:border-gray-700 size-[4px]" }} 307 {{ end }} 308 <div class="w-full h-full flex justify-center items-center"> 309 <div 310 class="aspect-square rounded-full transition-all duration-300 {{ $theme }} max-w-full max-h-full" 311 title="{{ .Date.Format "2006-01-02" }}: {{ .Count }} commits"> 312 </div> 313 </div> 314 {{ end }} 315 </div> 316 </div> 317 </div> 318{{ end }}