profileShare

rasmusjy / profileshare

Read-only snapshot

No repository description.

main default branch 54 files Expires Sep 13, 2026, 9:06 AM
dashboard.ejs 6,411 bytes
1 <%- include("partials/head", { title: "Owner workspace", bodyClass: "owner-page" }) %>
2 <header class="owner-header">
3 <a class="wordmark" href="/">profile<span>Share</span></a>
4 <% if (owner) { %>
5 <div class="owner-header-actions">
6 <a class="text-link" href="#shared-links">Your links</a>
7 <div class="owner-identity">
8 <img src="<%= owner.avatar_url %>" alt="">
9 <span><%= owner.name || owner.login %></span>
10 </div>
11 <form method="post" action="/auth/logout">
12 <button class="owner-signout" type="submit">Sign out</button>
13 </form>
14 </div>
15 <% } %>
16 </header>
17
18 <main class="owner-shell">
19 <% if (error) { %><p class="notice notice-error"><%= error %></p><% } %>
20 <% if (notice) { %><p class="notice notice-success"><%= notice %></p><% } %>
21 <% if (!owner) { %>
22 <section class="welcome-panel">
23 <p class="eyebrow">Private work, shared on your terms</p>
24 <h1>Open a window into your GitHub work.</h1>
25 <p class="lede">Choose specific repositories, freeze them into a read-only snapshot, and send one expiring link.</p>
26 <% if (appConfigured) { %>
27 <a class="button button-primary" href="/auth/github">Continue with GitHub</a>
28 <% } else { %>
29 <p class="notice">Add the GitHub App settings from <code>.env.example</code> to begin.</p>
30 <% } %>
31 <div class="privacy-note">
32 <strong>Repository access stays specific.</strong>
33 <span>You choose which repositories the GitHub App can read.</span>
34 </div>
35 </section>
36 <% } else if (!owner.installation_id) { %>
37 <section class="setup-panel">
38 <p class="step-label">One step left</p>
39 <h1>Choose repository access</h1>
40 <p>GitHub will ask which repositories profileShare can read. Select only the work you may want to share.</p>
41 <a class="button button-primary" href="/github/install">Choose repositories on GitHub</a>
42 </section>
43 <% } else { %>
44 <section class="workspace-heading">
45 <div>
46 <p class="eyebrow">New snapshot</p>
47 <h1>Select the work to share</h1>
48 </div>
49 <a class="text-link" href="/github/install">Change GitHub access</a>
50 </section>
51 <form method="post" action="/shares" class="share-form">
52 <fieldset>
53 <legend class="sr-only">Repositories</legend>
54 <div class="repo-selection">
55 <% repos.forEach((repo) => { %>
56 <label class="repo-choice">
57 <input type="checkbox" name="repositories" value="<%= repo.id %>">
58 <span class="choice-mark" aria-hidden="true"></span>
59 <span class="repo-choice-copy">
60 <span class="repo-choice-title">
61 <strong><%= repo.name %></strong>
62 <span class="visibility"><%= repo.private ? "Private" : "Public" %></span>
63 </span>
64 <span class="repo-description"><%= repo.description || "No description" %></span>
65 <span class="repo-meta"><%= repo.language || "Mixed" %> ยท Updated <%= formatDate(repo.updatedAt) %></span>
66 </span>
67 </label>
68 <% }) %>
69 <% if (!repos.length) { %>
70 <p class="empty-state">No repositories are available to this GitHub App installation.</p>
71 <% } %>
72 </div>
73 </fieldset>
74 <aside class="publish-panel">
75 <p class="step-label">Link settings</p>
76 <label for="days">Expires after</label>
77 <div class="duration-input">
78 <input id="days" name="days" type="number" min="1" max="365" value="7" required>
79 <span>days</span>
80 </div>
81 <p>The shared view is frozen when you create it. Later GitHub changes will not appear.</p>
82 <p id="selection-count" class="selection-count" aria-live="polite">0 repositories selected</p>
83 <p id="creation-status" class="sr-only" aria-live="polite"></p>
84 <button class="button button-primary" type="submit" <%= repos.length ? "" : "disabled" %>>Create snapshot link</button>
85 </aside>
86 </form>
87 <% } %>
88
89 <% if (owner) { %>
90 <section class="snapshot-list-section" id="shared-links">
91 <header class="snapshot-list-heading">
92 <div>
93 <p class="eyebrow">Your links</p>
94 <h2>Shared snapshots</h2>
95 </div>
96 <span><%= shares.length %> <%= shares.length === 1 ? "link" : "links" %></span>
97 </header>
98 <div class="snapshot-list">
99 <% shares.forEach((share) => { %>
100 <article class="snapshot-list-item">
101 <div class="snapshot-list-main">
102 <div class="snapshot-list-title">
103 <h3>
104 <%= share.repositories.length
105 ? share.repositories.map((repository) => repository.name).join(", ")
106 : "Snapshot content removed" %>
107 </h3>
108 <span class="snapshot-status snapshot-status-<%= share.status %>"><%= share.status %></span>
109 </div>
110 <p>
111 Created <%= formatDate(share.created_at) %>.
112 Expires <%= formatDate(share.expires_at) %>.
113 <% if (share.repositories.length) { %>
114 <%= share.repositories.length %> <%= share.repositories.length === 1 ? "repository" : "repositories" %>.
115 <% } %>
116 </p>
117 <% if (share.status === "active") { %><code><%= share.url %></code><% } %>
118 </div>
119 <% if (share.status === "active") { %>
120 <div class="snapshot-list-actions">
121 <a class="button button-secondary button-small" href="<%= share.url %>">Open</a>
122 <button class="button button-secondary button-small" type="button" data-copy-text="<%= share.url %>">Copy link</button>
123 <form method="post" action="/shares/<%= share.id %>/revoke" data-confirm="Revoke this snapshot link and remove its stored repository content?">
124 <button class="button button-danger button-small" type="submit">Revoke</button>
125 </form>
126 </div>
127 <% } %>
128 </article>
129 <% }) %>
130 <% if (!shares.length) { %>
131 <p class="empty-state">No snapshot links have been created yet.</p>
132 <% } %>
133 </div>
134 </section>
135 <% } %>
136 </main>
137 <script src="/assets/app.js" defer></script>
138 <%- include("partials/foot") %>
139