profile.ejs
7,681 bytes
| 1 | <%- include("partials/head", { title: share.snapshot.profile.name || share.snapshot.profile.login, bodyClass: "viewer-page" }) %> |
|---|---|
| 2 | <header class="viewer-header"> |
| 3 | <a class="wordmark wordmark-light" href="/s/<%= share.id %>">profile<span>Share</span></a> |
| 4 | <form class="snapshot-search" action="/s/<%= share.id %>/search" method="get" role="search"> |
| 5 | <svg width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.5 3a7.5 7.5 0 1 1-4.7 13.34l-3.07 3.07-1.42-1.42 3.08-3.07A7.5 7.5 0 0 1 10.5 3Zm0 2a5.5 5.5 0 1 0 0 11 5.5 5.5 0 0 0 0-11Z"/></svg> |
| 6 | <input data-search-input name="q" aria-label="Search this snapshot" placeholder="Search this snapshot"> |
| 7 | <kbd>/</kbd> |
| 8 | <button class="sr-only" type="submit">Search</button> |
| 9 | </form> |
| 10 | <div class="snapshot-meta"> |
| 11 | <span class="status-dot"></span> |
| 12 | Snapshot from <%= formatDate(share.created_at) %> |
| 13 | <span class="meta-divider"></span> |
| 14 | Expires <%= formatDate(share.expires_at) %> |
| 15 | </div> |
| 16 | </header> |
| 17 | |
| 18 | <nav class="profile-tabs" aria-label="Profile sections"> |
| 19 | <div> |
| 20 | <a class="<%= tab === 'overview' ? 'active' : '' %>" href="/s/<%= share.id %>" <%- tab === "overview" ? 'aria-current="page"' : "" %>> |
| 21 | Overview |
| 22 | </a> |
| 23 | <a class="<%= tab === 'repositories' ? 'active' : '' %>" href="/s/<%= share.id %>?tab=repositories" <%- tab === "repositories" ? 'aria-current="page"' : "" %>> |
| 24 | Repositories |
| 25 | <span><%= share.snapshot.repositories.length %></span> |
| 26 | </a> |
| 27 | </div> |
| 28 | </nav> |
| 29 | |
| 30 | <main class="profile-shell"> |
| 31 | <aside class="profile-card"> |
| 32 | <img class="profile-avatar" src="<%= share.snapshot.profile.avatarUrl %>" alt="<%= share.snapshot.profile.name || share.snapshot.profile.login %>"> |
| 33 | <h1><%= share.snapshot.profile.name || share.snapshot.profile.login %></h1> |
| 34 | <p class="profile-login"><%= share.snapshot.profile.login %></p> |
| 35 | <p class="profile-bio"><%= share.snapshot.profile.bio || "GitHub work selected for private review." %></p> |
| 36 | <div class="profile-count"> |
| 37 | <strong><%= share.snapshot.repositories.length %></strong> |
| 38 | <span>shared <%= share.snapshot.repositories.length === 1 ? "repository" : "repositories" %></span> |
| 39 | </div> |
| 40 | </aside> |
| 41 | |
| 42 | <section class="profile-content"> |
| 43 | <% if (tab === "overview") { %> |
| 44 | <div class="section-heading"> |
| 45 | <h2>Selected repositories</h2> |
| 46 | <a class="profile-section-link" href="/s/<%= share.id %>?tab=repositories">View all repositories</a> |
| 47 | </div> |
| 48 | <div class="repo-grid"> |
| 49 | <% share.snapshot.repositories.forEach((repo) => { %> |
| 50 | <a class="repo-card" href="/s/<%= share.id %>/repositories/<%= repo.id %>"> |
| 51 | <div class="repo-card-top"> |
| 52 | <svg class="repo-icon repo-icon-file" width="16" height="16" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 4.75A2.75 2.75 0 0 1 6.75 2h10.5A2.75 2.75 0 0 1 20 4.75v14.5A2.75 2.75 0 0 1 17.25 22H6.75A2.75 2.75 0 0 1 4 19.25V4.75Zm3.5-.75A1.5 1.5 0 0 0 6 5.5v13A1.5 1.5 0 0 0 7.5 20H9V4H7.5Z"/></svg> |
| 53 | <span class="repo-visibility"><%= repo.private === true ? "Private" : repo.private === false ? "Public" : "Snapshot" %></span> |
| 54 | </div> |
| 55 | <h3><%= repo.name %></h3> |
| 56 | <p><%= repo.description || "No repository description." %></p> |
| 57 | <div class="repo-card-foot"> |
| 58 | <span class="language"><i></i><%= repo.language || "Mixed" %></span> |
| 59 | <span><%= repo.commits.length %> commits</span> |
| 60 | <span><%= repo.issues?.filter((item) => item.state === "open").length || 0 %> open issues</span> |
| 61 | </div> |
| 62 | </a> |
| 63 | <% }) %> |
| 64 | <% if (!share.snapshot.repositories.length) { %> |
| 65 | <p class="empty-state">No repositories are included in this snapshot.</p> |
| 66 | <% } %> |
| 67 | </div> |
| 68 | |
| 69 | <section class="activity-section"> |
| 70 | <div class="section-heading"> |
| 71 | <h2>Recent work across the snapshot</h2> |
| 72 | </div> |
| 73 | <ol class="activity-list"> |
| 74 | <% commits.slice(0, 12).forEach((commit) => { %> |
| 75 | <li> |
| 76 | <span class="activity-node"></span> |
| 77 | <a href="/s/<%= share.id %>/repositories/<%= commit.repositoryId %>?commit=<%= commit.sha %>"> |
| 78 | <strong><%= commit.message.split("\n")[0] %></strong> |
| 79 | <span><%= commit.repository %> ยท <%= formatDate(commit.date) %></span> |
| 80 | </a> |
| 81 | </li> |
| 82 | <% }) %> |
| 83 | <% if (!commits.length) { %> |
| 84 | <li class="empty-state">No commit activity is included in this snapshot.</li> |
| 85 | <% } %> |
| 86 | </ol> |
| 87 | </section> |
| 88 | <% } else { %> |
| 89 | <div class="section-heading repository-heading"> |
| 90 | <h2>Repositories</h2> |
| 91 | <span class="read-only-badge">Read only</span> |
| 92 | </div> |
| 93 | <form class="repository-filter" action="/s/<%= share.id %>" method="get"> |
| 94 | <input type="hidden" name="tab" value="repositories"> |
| 95 | <label class="sr-only" for="repository-query">Find a repository</label> |
| 96 | <input id="repository-query" name="q" type="search" value="<%= repositoryQuery %>" placeholder="Find a repository"> |
| 97 | <label class="sr-only" for="repository-language">Language</label> |
| 98 | <select id="repository-language" name="language"> |
| 99 | <option value="">All languages</option> |
| 100 | <% languages.forEach((language) => { %> |
| 101 | <option value="<%= language %>" <%= selectedLanguage === language ? "selected" : "" %>><%= language %></option> |
| 102 | <% }) %> |
| 103 | </select> |
| 104 | <label class="sr-only" for="repository-sort">Sort repositories</label> |
| 105 | <select id="repository-sort" name="sort"> |
| 106 | <option value="updated" <%= sort === "updated" ? "selected" : "" %>>Recently updated</option> |
| 107 | <option value="name" <%= sort === "name" ? "selected" : "" %>>Name</option> |
| 108 | <option value="commits" <%= sort === "commits" ? "selected" : "" %>>Most commits</option> |
| 109 | </select> |
| 110 | <button class="quiet-button" type="submit">Apply</button> |
| 111 | </form> |
| 112 | <div class="repository-list"> |
| 113 | <% repositories.forEach((repo) => { %> |
| 114 | <article> |
| 115 | <div class="repository-list-main"> |
| 116 | <div class="repository-list-title"> |
| 117 | <a href="/s/<%= share.id %>/repositories/<%= repo.id %>"><%= repo.name %></a> |
| 118 | <span class="repo-visibility"><%= repo.private === true ? "Private" : repo.private === false ? "Public" : "Snapshot" %></span> |
| 119 | </div> |
| 120 | <p><%= repo.description || "No repository description." %></p> |
| 121 | <div class="repository-list-meta"> |
| 122 | <span class="language"><i></i><%= repo.language || "Mixed" %></span> |
| 123 | <span><%= repo.files.length %> files</span> |
| 124 | <span><%= repo.commits.length %> commits</span> |
| 125 | <span><%= repo.issues?.length || 0 %> issues</span> |
| 126 | <span><%= repo.pullRequests?.length || 0 %> pull requests</span> |
| 127 | <span><%= repo.releases?.length || 0 %> releases</span> |
| 128 | <% if (repo.updatedAt) { %><span>Updated <%= formatDate(repo.updatedAt) %></span><% } %> |
| 129 | </div> |
| 130 | </div> |
| 131 | <a class="quiet-button" href="/s/<%= share.id %>/repositories/<%= repo.id %>">Open repository</a> |
| 132 | </article> |
| 133 | <% }) %> |
| 134 | <% if (!repositories.length) { %> |
| 135 | <div class="empty-state"> |
| 136 | No repositories match these filters. |
| 137 | <a href="/s/<%= share.id %>?tab=repositories">Clear filters</a> |
| 138 | </div> |
| 139 | <% } %> |
| 140 | </div> |
| 141 | <% } %> |
| 142 | </section> |
| 143 | </main> |
| 144 | <script src="/assets/app.js" defer></script> |
| 145 | <%- include("partials/foot") %> |
| 146 | |