source: Klonkt/src/views/pages/user.ejs@ 8f2f97c

main
Last change on this file since 8f2f97c was 8f2f97c, checked in by Robin Genis <roboburr@…>, 3 months ago

Prutter (DM feature) fully removed

Reason: redundant feature + unnecessary attack surface (real-time WebSocket +
storing private messages = privacy/abuse risk). Removed: routes/prutter.js,
PrutterService, the WebSocket server in server.js, both DM views, all nav links
(topnav/bottom-tab), the DM button on profiles, the per-site enable_prutter
toggle and column. Existing (empty) DM tables in old DBs remain untouched but
are no longer referenced anywhere. No WebSocket left in the app.

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 5.0 KB
Line 
1<div class="container user-page">
2 <header class="user-header">
3 <div class="user-avatar-large">
4 <% if (author.avatar_url) { %>
5 <img src="<%= author.avatar_url %>" alt="">
6 <% } else { %>
7 <span><%= author.username.charAt(0).toUpperCase() %></span>
8 <% } %>
9 </div>
10 <div class="user-meta">
11 <h1><%= author.username %></h1>
12 <% if (author.role === 'god') { %>
13 <span class="user-role-pill user-role-god">god</span>
14 <% } else if (author.role === 'admin') { %>
15 <span class="user-role-pill user-role-admin">admin</span>
16 <% } %>
17 <% if (author.bio) { %>
18 <p class="user-bio"><%= author.bio %></p>
19 <% } %>
20 <p class="user-stats">
21 <%= posts.length %> <%= posts.length === 1 ? t('pusr.post_one') : t('pusr.post_many') %> <%= t('pusr.on_this_site') %>
22 <% if (totalPosts > posts.length) { %>
23 &middot; <%= t('pusr.total', { n: totalPosts }) %>
24 <% } %>
25 <% if (author.created_at) { %>
26 &middot; <%= t('pusr.joined', { date: formatDate(author.created_at) }) %>
27 <% } %>
28 </p>
29 </div>
30 </header>
31
32 <% if (!posts.length) { %>
33 <p class="user-empty"><%= t('pusr.empty') %></p>
34 <% } else { %>
35 <h2 class="user-posts-heading"><%= t('pusr.posts_heading') %></h2>
36 <ol class="user-posts">
37 <% posts.forEach(function(p) { %>
38 <li class="user-post">
39 <% if (p.cover_image_url) { %>
40 <a href="/<%= p.slug %>" class="user-post-cover"
41 hx-get="/<%= p.slug %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
42 hx-push-url="/<%= p.slug %>" hx-indicator="#pcms-loading">
43 <img src="<%= p.cover_image_url %>" alt="">
44 </a>
45 <% } %>
46 <div class="user-post-body">
47 <h3 class="user-post-title">
48 <a href="/<%= p.slug %>"
49 hx-get="/<%= p.slug %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
50 hx-push-url="/<%= p.slug %>" hx-indicator="#pcms-loading">
51 <%= p.title || t('pusr.untitled') %>
52 </a>
53 </h3>
54 <p class="user-post-meta">
55 <% if (p.published_at) { %><%= formatDate(p.published_at) %><% } %>
56 </p>
57 <% if (p.excerpt) { %>
58 <p class="user-post-excerpt"><%= p.excerpt %></p>
59 <% } %>
60 </div>
61 </li>
62 <% }); %>
63 </ol>
64 <% } %>
65</div>
66
67<style>
68.user-page { max-width: 720px; margin: 3rem auto; padding: 0 1rem; }
69
70.user-header {
71 display: flex;
72 gap: 1.25rem;
73 align-items: center;
74 margin-bottom: 2rem;
75 padding-bottom: 1.5rem;
76 border-bottom: 1px solid var(--rule);
77}
78.user-avatar-large {
79 width: 96px;
80 height: 96px;
81 border-radius: 50%;
82 background: var(--paper-2);
83 border: 2px solid var(--rule);
84 overflow: hidden;
85 flex-shrink: 0;
86 display: inline-flex;
87 align-items: center;
88 justify-content: center;
89}
90.user-avatar-large img { width: 100%; height: 100%; object-fit: cover; }
91.user-avatar-large span {
92 font-family: var(--font-display, serif);
93 font-size: 2.5rem;
94 font-weight: 700;
95 color: var(--accent);
96}
97.user-meta { flex: 1; min-width: 0; }
98.user-meta h1 {
99 font-family: var(--font-display, serif);
100 margin: 0;
101 font-size: 2rem;
102}
103.user-role-pill {
104 display: inline-block;
105 padding: 0.1rem 0.5rem;
106 border-radius: 10px;
107 font-size: 0.7rem;
108 text-transform: uppercase;
109 letter-spacing: 0.05em;
110 vertical-align: middle;
111 margin-left: 0.4rem;
112}
113.user-role-pill.user-role-god { background: var(--accent); color: white; }
114.user-role-pill.user-role-admin { background: var(--paper); color: var(--accent); border: 1px solid var(--accent); }
115.user-bio { margin: 0.4rem 0; color: var(--ink-soft); }
116.user-stats { margin: 0; color: var(--ink-muted, var(--ink-soft)); font-size: 0.85rem; }
117
118.user-posts-heading {
119 font-family: var(--font-display, serif);
120 font-size: 1.4rem;
121 margin: 0 0 1rem;
122}
123.user-empty { color: var(--ink-muted, var(--ink-soft)); text-align: center; margin: 3rem 0; }
124
125.user-posts { list-style: none; padding: 0; margin: 0; }
126.user-post { display: flex; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid var(--rule); }
127.user-post:last-child { border-bottom: 0; }
128.user-post-cover { flex-shrink: 0; width: 96px; height: 96px; border-radius: 6px; overflow: hidden; background: var(--paper-2); }
129.user-post-cover img { width: 100%; height: 100%; object-fit: cover; }
130.user-post-body { flex: 1; min-width: 0; }
131.user-post-title { font-family: var(--font-display, serif); font-size: 1.15rem; margin: 0 0 0.2rem; }
132.user-post-title a { color: var(--ink); text-decoration: none; }
133.user-post-title a:hover { color: var(--accent); }
134.user-post-meta { color: var(--ink-muted, var(--ink-soft)); font-size: 0.85rem; margin: 0 0 0.4rem; }
135.user-post-excerpt { color: var(--ink-soft); margin: 0; line-height: 1.5; }
136
137@media (max-width: 500px) {
138 .user-header { flex-direction: column; text-align: center; }
139 .user-post-cover { width: 64px; height: 64px; }
140}
141</style>
Note: See TracBrowser for help on using the repository browser.