guild tab views

This commit is contained in:
Corban-Lee Jones 2025-04-22 15:56:58 +01:00
parent 042b0a5a07
commit a8f513973e
11 changed files with 185 additions and 0 deletions

View File

@ -0,0 +1,5 @@
<% layout("layout/base") -%>
<%- include("header") -%>
Content page placeholder

View File

@ -0,0 +1,5 @@
<% layout("layout/base") -%>
<%- include("header") -%>
Feeds page placeholder

View File

@ -0,0 +1,5 @@
<% layout("layout/base") -%>
<%- include("header") -%>
Filters page placeholder

View File

@ -0,0 +1,65 @@
<div>
<div class="relative pt-5 before:w-full before:h-[200px] before:-z-10 before:top-0 before:start-0 before:absolute">
<div class="flex sm:items-center gap-5 p-4 sm:p-6 pb-1!">
<div class="shrink-0">
<div class="relative">
<% if (guild.icon) { %>
<img src="<%= guild.iconURL() %>" class="rounded-md sm:rounded-lg size-16 sm:size-20" alt="">
<% } else { %>
<div class="size-16 sm:size-20 rounded-md sm:rounded-lg flex shrink-0 justify-center items-center bg-white dark:bg-neutral-800">
<span class="text-2xl"><%= guild.nameAcronym %></span>
</div>
<% } %>
</div>
</div>
<div class="grow">
<h1 class="text-2xl md:text-3xl font-semibold text-gray-800 dark:text-neutral-200">
<%= guild.name %>
</h1>
<ul class="flex flex-wrap items-center gap-3 mt-2">
<li class="relative">
<span class="text-sm">ID:</span>
<span class="text-sm inline-flex items-center gap-2 text-gray-800 dark:text-neutral-200"><%= guild.id %></span>
</li>
<li class="relative">
<span class="text-sm">Members:</span>
<span class="text-sm inline-flex items-center gap-2 text-gray-800 dark:text-neutral-200"><%= guild.memberCount %></span>
</li>
<li class="relative">
<span class="text-sm">Channels:</span>
<span class="text-sm inline-flex items-center gap-2 text-gray-800 dark:text-neutral-200"><%= guild.channels.channelCountWithoutThreads %></span>
</li>
</ul>
</div>
<div class="ms-auto flex flex-row flex-wrap gap-2">
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-xs hover:bg-gray-50 focus:outline-hidden focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700">
<svg class="shrink-0 size-4" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
Validate channels
</button>
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-xs hover:bg-gray-50 focus:outline-hidden focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700">
<svg class="shrink-0 size-4" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
Copy data
</button>
<button type="button" class="py-2 px-3 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-red-500 shadow-xs hover:bg-gray-50 focus:outline-hidden focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-900 dark:border-neutral-700 dark:hover:bg-neutral-800 dark:focus:bg-neutral-800">
<svg class="shrink-0 size-4" viewBox="0 0 24 24" width="24" height="24" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
Remove bot
</button>
</div>
</div>
</div>
<div class="flex flex-col justify-center items-center mx-auto p-4 sm:p-6">
<div class="flex flex-row w-full pb-1 whitespace-nowrap overflow-x-auto overflow-y-hidden">
<!-- <a href="/guild/<%= guild.id %>" class="inline-flex items-center gap-2 whitespace-nowrap rounded-lg px-3 py-2 text-sm text-gray-800 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400 <%= !isNaN(+guildPage) ? 'bg-white dark:bg-neutral-800 dark:border-neutral-700! border shadow-xs' : 'mx-[1px]' %>">Overview</a> -->
<a href="/guild/<%= guild.id %>/feeds" class="inline-flex items-center gap-2 whitespace-nowrap rounded-lg px-3 py-2 text-sm text-blue-500 dark:text-blue-400 dark:hover:text-blue-500 dark:focus:text-blue-500 <%= guildPage === 'feeds' ? 'text-gray-800 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400 bg-white dark:bg-neutral-800 dark:border-neutral-700! border shadow-xs' : 'mx-[1px]' %>">Feeds</a>
<a href="/guild/<%= guild.id %>/filters" class="inline-flex items-center gap-2 whitespace-nowrap rounded-lg px-3 py-2 text-sm text-blue-500 dark:text-blue-400 dark:hover:text-blue-500 dark:focus:text-blue-500 <%= guildPage === 'filters' ? 'text-gray-800 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400 bg-white dark:bg-neutral-800 dark:border-neutral-700! border shadow-xs' : 'mx-[1px]' %>">Filters</a>
<a href="/guild/<%= guild.id %>/styles" class="inline-flex items-center gap-2 whitespace-nowrap rounded-lg px-3 py-2 text-sm text-blue-500 dark:text-blue-400 dark:hover:text-blue-500 dark:focus:text-blue-500 <%= guildPage === 'styles' ? 'text-gray-800 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400 bg-white dark:bg-neutral-800 dark:border-neutral-700! border shadow-xs' : 'mx-[1px]' %>">Styles</a>
<a href="/guild/<%= guild.id %>/content" class="inline-flex items-center gap-2 whitespace-nowrap rounded-lg px-3 py-2 text-sm text-blue-500 dark:text-blue-400 dark:hover:text-blue-500 dark:focus:text-blue-500 <%= guildPage === 'content' ? 'text-gray-800 dark:text-neutral-200 dark:hover:text-neutral-400 dark:focus:text-neutral-400 bg-white dark:bg-neutral-800 dark:border-neutral-700! border shadow-xs' : 'mx-[1px]' %>">Content</a>
<!-- <a href="#" class="inline-flex items-center gap-2 whitespace-nowrap rounded-lg px-3 py-2 text-sm text-blue-500 dark:text-blue-400 dark:hover:text-blue-500 dark:focus:text-blue-500">Settings</a> -->
</div>
</div>
</div>

View File

@ -0,0 +1,5 @@
<% layout("layout/base") -%>
<%- include("header") -%>
Styles page placeholder

View File

@ -0,0 +1,19 @@
import { Request, Response } from "express";
import { client as bot } from "@bot/bot";
export const get = async (request: Request, response: Response) => {
const guildId = request.params.guildId;
const guild = bot.guilds.cache.get(guildId);
if (!guild) {
response.status(404).send("404: guild not found");
return;
}
response.render("guild/content", {
title: `${guild.name} - Relay`,
guild: guild
});
};
export default { get }

View File

@ -0,0 +1,19 @@
import { Request, Response } from "express";
import { client as bot } from "@bot/bot";
export const get = async (request: Request, response: Response) => {
const guildId = request.params.guildId;
const guild = bot.guilds.cache.get(guildId);
if (!guild) {
response.status(404).send("404: guild not found");
return;
}
response.render("guild/feeds", {
title: `${guild.name} - Relay`,
guild: guild
});
};
export default { get }

View File

@ -0,0 +1,19 @@
import { Request, Response } from "express";
import { client as bot } from "@bot/bot";
export const get = async (request: Request, response: Response) => {
const guildId = request.params.guildId;
const guild = bot.guilds.cache.get(guildId);
if (!guild) {
response.status(404).send("404: guild not found");
return;
}
response.render("guild/filters", {
title: `${guild.name} - Relay`,
guild: guild
});
};
export default { get }

View File

@ -0,0 +1,19 @@
import { Request, Response } from "express";
import { client as bot } from "@bot/bot";
export const get = async (request: Request, response: Response) => {
const guildId = request.params.guildId;
const guild = bot.guilds.cache.get(guildId);
if (!guild) {
response.status(404).send("404: guild not found");
return;
}
response.render("guild/styles", {
title: `${guild.name} - Relay`,
guild: guild
});
};
export default { get }

View File

@ -1,6 +1,9 @@
import { Request, Response, NextFunction } from "express";
import { client as bot } from "@bot/bot";
// The purpose of this middleware is to attach an object containing cached
// Discord servers to the response, which is accessible in the DOM.
// This is primarily used for rendering servers on the sidebar.
export const attachGuilds = (_request: Request, response: Response, next: NextFunction) => {
response.locals.guilds = bot.guilds.cache.map(guild => guild);
next();

View File

@ -0,0 +1,21 @@
import { Request, Response, Router } from "express";
import feedController from "@server/controllers/guild/feed.controller";
import filterController from "@server/controllers/guild/filter.controller";
import styleController from "@server/controllers/guild/style.controller";
import contentController from "@server/controllers/guild/content.controller";
const router = Router();
router.get("/:guildId", (request: Request, response: Response) => {
const guildId = request.params.guildId;
response.redirect(`/guild/${guildId}/feeds`);
return;
});
router.get("/:guildId/feeds", feedController.get);
router.get("/:guildId/filters", filterController.get);
router.get("/:guildId/styles", styleController.get);
router.get("/:guildId/content", contentController.get);
export default router;