Sample Cluster admin page
This commit is contained in:
parent
1b379513f7
commit
4e85c0225b
4 changed files with 66 additions and 1 deletions
|
@ -14,6 +14,12 @@ const services = struct {
|
||||||
const follows = @import("./services/follows.zig");
|
const follows = @import("./services/follows.zig");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const ClusterMeta = struct {
|
||||||
|
community_count: usize,
|
||||||
|
user_count: usize,
|
||||||
|
note_count: usize,
|
||||||
|
};
|
||||||
|
|
||||||
pub const RegistrationOptions = struct {
|
pub const RegistrationOptions = struct {
|
||||||
invite_code: ?[]const u8 = null,
|
invite_code: ?[]const u8 = null,
|
||||||
email: ?[]const u8 = null,
|
email: ?[]const u8 = null,
|
||||||
|
@ -485,5 +491,22 @@ fn ApiConn(comptime DbConn: type) type {
|
||||||
const result = try services.follows.create(self.db, self.user_id orelse return error.NoToken, followee, self.arena.allocator());
|
const result = try services.follows.create(self.db, self.user_id orelse return error.NoToken, followee, self.arena.allocator());
|
||||||
defer util.deepFree(self.arena.allocator(), result);
|
defer util.deepFree(self.arena.allocator(), result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getClusterMeta(self: *Self) !ClusterMeta {
|
||||||
|
return try self.db.queryRow(
|
||||||
|
ClusterMeta,
|
||||||
|
\\SELECT
|
||||||
|
\\ COUNT(DISTINCT note.id) AS note_count,
|
||||||
|
\\ COUNT(DISTINCT actor.id) AS user_count,
|
||||||
|
\\ COUNT(DISTINCT community.id) AS community_count
|
||||||
|
\\FROM note, actor, community
|
||||||
|
\\WHERE
|
||||||
|
\\ actor.community_id = community.id AND
|
||||||
|
\\ community.kind != 'admin'
|
||||||
|
,
|
||||||
|
.{},
|
||||||
|
self.arena.allocator(),
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ pub const routes = .{
|
||||||
about,
|
about,
|
||||||
login,
|
login,
|
||||||
global_timeline,
|
global_timeline,
|
||||||
|
cluster.overview,
|
||||||
};
|
};
|
||||||
|
|
||||||
const index = struct {
|
const index = struct {
|
||||||
|
@ -70,3 +71,18 @@ const global_timeline = struct {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const cluster = struct {
|
||||||
|
const overview = struct {
|
||||||
|
pub const path = "/cluster/overview";
|
||||||
|
pub const method = .GET;
|
||||||
|
|
||||||
|
pub fn handler(_: anytype, res: anytype, srv: anytype) !void {
|
||||||
|
const meta = try srv.getClusterMeta();
|
||||||
|
try res.template(.ok, @embedFile("./web/cluster/overview.tmpl.html"), .{
|
||||||
|
.community = srv.community,
|
||||||
|
.meta = meta,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
24
src/main/controllers/web/cluster/overview.tmpl.html
Normal file
24
src/main/controllers/web/cluster/overview.tmpl.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>{ .community.name }</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<h1>{ .community.name }</h1>
|
||||||
|
</header>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
<li><a href="communities">Communities</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<main>
|
||||||
|
<h2>Cluster Overview</h2>
|
||||||
|
<div>
|
||||||
|
Home to <span>{ .meta.community_count }</span> communities
|
||||||
|
hosting <span>{ .meta.user_count }</span> users.
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -59,7 +59,9 @@ fn executeStatement(writer: anytype, comptime stmt: Statement, args: anytype, ca
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print(writer: anytype, arg: anytype) !void {
|
fn print(writer: anytype, arg: anytype) !void {
|
||||||
if (comptime std.meta.trait.isZigString(@TypeOf(arg))) return writer.writeAll(arg);
|
const T = @TypeOf(arg);
|
||||||
|
if (comptime std.meta.trait.isZigString(T)) return writer.writeAll(arg);
|
||||||
|
if (comptime std.meta.trait.isNumber(T)) return std.fmt.format(writer, "{}", .{arg});
|
||||||
@compileLog(@TypeOf(arg));
|
@compileLog(@TypeOf(arg));
|
||||||
|
|
||||||
@compileError("TODO");
|
@compileError("TODO");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue