parent
d504cef8ff
commit
a230a26151
3 changed files with 137 additions and 1 deletions
|
@ -8,12 +8,13 @@ pub const routes = .{
|
||||||
controllers.apiEndpoint(about),
|
controllers.apiEndpoint(about),
|
||||||
controllers.apiEndpoint(login),
|
controllers.apiEndpoint(login),
|
||||||
controllers.apiEndpoint(global_timeline),
|
controllers.apiEndpoint(global_timeline),
|
||||||
controllers.apiEndpoint(cluster.overview),
|
controllers.apiEndpoint(user_details),
|
||||||
controllers.apiEndpoint(media),
|
controllers.apiEndpoint(media),
|
||||||
controllers.apiEndpoint(static),
|
controllers.apiEndpoint(static),
|
||||||
controllers.apiEndpoint(signup.page),
|
controllers.apiEndpoint(signup.page),
|
||||||
controllers.apiEndpoint(signup.with_invite),
|
controllers.apiEndpoint(signup.with_invite),
|
||||||
controllers.apiEndpoint(signup.submit),
|
controllers.apiEndpoint(signup.submit),
|
||||||
|
controllers.apiEndpoint(cluster.overview),
|
||||||
controllers.apiEndpoint(cluster.communities.create.page),
|
controllers.apiEndpoint(cluster.communities.create.page),
|
||||||
controllers.apiEndpoint(cluster.communities.create.submit),
|
controllers.apiEndpoint(cluster.communities.create.submit),
|
||||||
};
|
};
|
||||||
|
@ -210,6 +211,24 @@ const global_timeline = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const user_details = struct {
|
||||||
|
pub const path = "/users/:id";
|
||||||
|
pub const method = .GET;
|
||||||
|
|
||||||
|
pub const tmpl = @embedFile("./web/user.tmpl.html");
|
||||||
|
|
||||||
|
pub const Args = struct {
|
||||||
|
id: util.Uuid,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn handler(req: anytype, res: anytype, srv: anytype) !void {
|
||||||
|
const user = try srv.getUser(req.args.id);
|
||||||
|
defer util.deepFree(srv.allocator, user);
|
||||||
|
|
||||||
|
try res.template(.ok, srv, tmpl, user);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const cluster = struct {
|
const cluster = struct {
|
||||||
const overview = struct {
|
const overview = struct {
|
||||||
pub const path = "/cluster/overview";
|
pub const path = "/cluster/overview";
|
||||||
|
|
33
src/main/controllers/web/user.tmpl.html
Normal file
33
src/main/controllers/web/user.tmpl.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<div class="user-profile">
|
||||||
|
<header>
|
||||||
|
<img class="banner" src="{#if .header_url |$url|}{$url}{/if}" />
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="avatar">
|
||||||
|
<img src="{.avatar_url}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="names">
|
||||||
|
<div class="display-name">{#if .display_name |$n|}{$n}{#else}{.username}{/if}</div>
|
||||||
|
<div class="handle">@{.username}@{.host}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="bio">
|
||||||
|
{.bio}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="profile-fields">
|
||||||
|
{#for .profile_fields |$field| =}
|
||||||
|
<div class="field">
|
||||||
|
<div class="field-name">{$field.key}</div>
|
||||||
|
<div class="field-value">{$field.value}</div>
|
||||||
|
</div>
|
||||||
|
{/for =}
|
||||||
|
<div class="field">
|
||||||
|
<div class="field-name">Joined on</div>
|
||||||
|
<div class="field-value">{.created_at}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -134,3 +134,87 @@ button:hover, a.button:hover {
|
||||||
background-color: var(--theme-color-highlight);
|
background-color: var(--theme-color-highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-profile img.banner {
|
||||||
|
width: 100%;
|
||||||
|
height: 24em;
|
||||||
|
object-fit: cover;
|
||||||
|
/* TODO: Center this on the image focus */
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile {
|
||||||
|
--avatar-size: 12em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile .avatar {
|
||||||
|
margin-top: calc(var(--avatar-size) * -3/5);
|
||||||
|
margin-left: calc(var(--avatar-size) / 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile .avatar img {
|
||||||
|
width: var(--avatar-size);
|
||||||
|
height: var(--avatar-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile header > div {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile header .names {
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile > div {
|
||||||
|
margin-left: calc(var(--avatar-size) * 3/5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile .profile-fields .field {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 3fr;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-profile .profile-fields .field .field-name { grid-column: 1; }
|
||||||
|
.user-profile .profile-fields .field .field-value { grid-column: 2; }
|
||||||
|
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.user-profile img.banner {
|
||||||
|
height: 18em;
|
||||||
|
}
|
||||||
|
.user-profile {
|
||||||
|
--avatar-size: 10em;
|
||||||
|
}
|
||||||
|
.user-profile .profile-fields .field {
|
||||||
|
grid-template-columns: 1fr 2fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.user-profile img.banner {
|
||||||
|
height: 12em;
|
||||||
|
}
|
||||||
|
.user-profile header div {
|
||||||
|
}
|
||||||
|
.user-profile header div * {
|
||||||
|
flex-basis: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.user-profile {
|
||||||
|
--avatar-size: 8em;
|
||||||
|
}
|
||||||
|
.user-profile .avatar {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
.user-profile > div {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
.user-profile .bio {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.user-profile .profile-fields .field {
|
||||||
|
grid-template-columns: 2fr 3fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue