Overhaul design

This commit is contained in:
rxdn 2024-08-30 00:09:42 +01:00
parent 3fd7539d7f
commit 5eb26c3b53
20 changed files with 627 additions and 407 deletions

View File

@ -0,0 +1,29 @@
package api
import (
"github.com/TicketsBot/GoPanel/botcontext"
"github.com/TicketsBot/GoPanel/utils"
"github.com/gin-gonic/gin"
)
func GuildHandler(ctx *gin.Context) {
guildId := ctx.Keys["guildid"].(uint64)
botContext, err := botcontext.ContextForGuild(guildId)
if err != nil {
ctx.JSON(500, utils.ErrorJson(err))
return
}
guild, err := botContext.GetGuild(ctx, guildId)
if err != nil {
ctx.JSON(500, utils.ErrorJson(err))
return
}
ctx.JSON(200, gin.H{
"id": guild.Id,
"name": guild.Name,
"icon": guild.Icon,
})
}

View File

@ -94,6 +94,7 @@ func StartServer(sm *livechat.SocketManager) {
guildAuthApiSupport := apiGroup.Group("/:id", middleware.AuthenticateGuild(permission.Support)) guildAuthApiSupport := apiGroup.Group("/:id", middleware.AuthenticateGuild(permission.Support))
guildApiNoAuth := apiGroup.Group("/:id", middleware.ParseGuildId) guildApiNoAuth := apiGroup.Group("/:id", middleware.ParseGuildId)
{ {
guildAuthApiSupport.GET("/guild", api.GuildHandler)
guildAuthApiSupport.GET("/channels", api.ChannelsHandler) guildAuthApiSupport.GET("/channels", api.ChannelsHandler)
guildAuthApiSupport.GET("/premium", api.PremiumHandler) guildAuthApiSupport.GET("/premium", api.PremiumHandler)
guildAuthApiSupport.GET("/user/:user", api.UserHandler) guildAuthApiSupport.GET("/user/:user", api.UserHandler)

View File

@ -1,4 +1,10 @@
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
:root {
--primary: #995DF3;
--primary-gradient: linear-gradient(71.3deg, #873ef5 0%, #995DF3 100%);
--blue: #3472f7;
}
html, body { html, body {
position: relative; position: relative;
@ -7,7 +13,7 @@ html, body {
} }
body, h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6, p, .navbar, .brand, .btn-simple, .alert, a, .td-name, td, button.close { body, h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6, p, .navbar, .brand, .btn-simple, .alert, a, .td-name, td, button.close {
font-family: 'Noto Sans', sans-serif !important; font-family: 'Poppins', sans-serif !important;
font-weight: 400 !important; font-weight: 400 !important;
} }

View File

@ -3,7 +3,7 @@
</div> </div>
<script> <script>
export let colour = '#3472f7'; export let colour = '';
</script> </script>
<style> <style>
@ -11,7 +11,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
background-color: var(--badge-background-color, #3472f7); background: var(--badge-background-color, var(--primary));
border-radius: 2px; border-radius: 2px;
font-size: 14px; font-size: 14px;
padding: 0 4px; padding: 0 4px;

View File

@ -28,9 +28,10 @@
text-align: center; text-align: center;
color: white; color: white;
background-color: #3472f7; background: var(--primary-gradient);
border-color: #3472f7; border: none;
border-width: 2px; /*border-color: var(--primary);*/
/*border-width: 2px;*/
border-radius: .25rem; border-radius: .25rem;
margin: 0; margin: 0;
@ -39,14 +40,14 @@
box-shadow: 0 4px 4px rgb(0 0 0 / 25%); box-shadow: 0 4px 4px rgb(0 0 0 / 25%);
} }
button:active, button:hover:enabled { /*button:active, button:hover:enabled {*/
background-color: #0062cc; /* background-color: #0062cc;*/
border-color: #0062cc; /* border-color: #0062cc;*/
} /*}*/
button:disabled { button:disabled {
background-color: #6c757d; background: #6c757d;
border-color: #6c757d; border: #6c757d;
cursor: default; cursor: default;
} }
@ -60,12 +61,12 @@
} }
.danger { .danger {
background-color: #dc3545 !important; background: #dc3545 !important;
border-color: #dc3545 !important; border-color: #dc3545 !important;
} }
.danger:hover:enabled, .danger:active { .danger:hover:enabled, .danger:active {
background-color: #c32232 !important; background: #c32232 !important;
border-color: #c32232 !important; border-color: #c32232 !important;
} }

View File

@ -0,0 +1,136 @@
<section class="sidebar">
<header>
<img src="{getIconUrl()}" class="guild-icon" alt="Guild icon" width="50" height="50"/>
{guild.name}
</header>
<nav>
<ul class="nav-list">
<ManageSidebarLink {currentRoute} title="← Back to servers" href="/" />
{#if isAdmin}
<ManageSidebarLink {currentRoute} title="Settings" icon="fa-cogs" href="/manage/{guildId}/settings" />
{/if}
<ManageSidebarLink {currentRoute} title="Transcripts" icon="fa-copy" href="/manage/{guildId}/transcripts" />
{#if isAdmin}
<ManageSidebarLink {currentRoute} routePrefix="/manage/{guildId}/panels" title="Ticket Panels" icon="fa-mouse-pointer" href="/manage/{guildId}/panels" />
<ManageSidebarLink {currentRoute} title="Forms" icon="fa-poll-h" href="/manage/{guildId}/forms" />
<ManageSidebarLink {currentRoute} title="Staff Teams" icon="fa-users" href="/manage/{guildId}/teams" />
<ManageSidebarLink {currentRoute} title="Integrations" icon="fa-robot" href="/manage/{guildId}/integrations" />
{/if}
<ManageSidebarLink {currentRoute} title="Tickets" icon="fa-ticket-alt" href="/manage/{guildId}/tickets" />
<ManageSidebarLink {currentRoute} title="Blacklist" icon="fa-ban" href="/manage/{guildId}/blacklist" />
<ManageSidebarLink {currentRoute} title="Tags" icon="fa-tags" href="/manage/{guildId}/tags" />
</ul>
</nav>
<nav class="bottom">
<hr/>
<ul class="nav-list">
<ManageSidebarLink {currentRoute} title="Documentation" icon="fa-book" href="https://docs.ticketsbot.net" newWindow />
<ManageSidebarLink {currentRoute} title="Logout" icon="fa-sign-out-alt" href="/logout" />
</ul>
</nav>
</section>
<style>
.sidebar {
display: flex;
flex-direction: column;
align-self: flex-start;
background-color: #272727;
padding: 15px;
width: 275px;
border-radius: 6px;
user-select: none;
}
header {
display: flex;
flex-direction: row;
align-items: center;
gap: 10px;
font-weight: bold;
padding: 6px 10px;
border-radius: 4px;
background: linear-gradient(33.3deg, #873ef5 0%, #995DF3 100%);
box-shadow: 0 6px 6px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .1);
}
.guild-icon {
width: 48px;
height: 48px;
border-radius: 50%;
}
nav > ul {
list-style-type: none;
padding: 0;
margin: 0;
}
nav hr {
width: 40%;
padding-left: 20px;
}
</style>
<script>
import {onMount} from "svelte";
import axios from "axios";
import {API_URL} from "../js/constants";
import {notifyError, withLoadingScreen} from "../js/util";
import ManageSidebarLink from "./ManageSidebarLink.svelte";
import SubNavigation from "./SubNavigation.svelte";
import SubNavigationLink from "./SubNavigationLink.svelte";
export let currentRoute;
export let permissionLevel;
$: isAdmin = permissionLevel >= 2;
let guildId = currentRoute.namedParams.id;
let guild = {};
async function loadGuild() {
const res = await axios.get(`${API_URL}/api/${guildId}/guild`);
if (res.status !== 200) {
notifyError(res.data.error);
return;
}
guild = res.data;
}
function isAnimated() {
if (guild.icon === undefined || guild.icon === "") {
return false;
} else {
return guild.icon.startsWith('a_')
}
}
function getIconUrl() {
if (!guild.icon) {
return `https://cdn.discordapp.com/embed/avatars/${Number((BigInt(guildId) >> BigInt(22)) % BigInt(6))}.png`
}
if (isAnimated()) {
return `https:\/\/cdn.discordapp.com/icons/${guild.id}/${guild.icon}.gif?size=256`
} else {
return `https:\/\/cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp?size=256`
}
}
onMount(async () => {
await withLoadingScreen(async () => {
await loadGuild();
})
});
</script>

View File

@ -0,0 +1,52 @@
<li>
<div style="width: 100%">
<a href="{href}" class:active target="{newWindow === true ? '_blank' : '_self'}">
{#if icon}
<i class="fas {icon}"/>
{/if}
<span>{title}</span>
</a>
{#if active}
<slot/>
{/if}
</div>
</li>
<style>
a.active {
background: linear-gradient(71.3deg, #873ef5 0%, #995DF3 100%);
box-shadow: 0 6px 6px rgba(10, 10, 10, .1), 0 0 0 1px rgba(10, 10, 10, .1);
}
a, a:link, a:hover, a:visited, a:active {
display: block;
color: inherit;
text-decoration: none;
font-size: 16px;
padding: 5px 10px 5px 20px;
border-radius: 4px;
}
i {
width: 20px;
text-align: center;
}
</style>
<script>
export let currentRoute;
export let title;
export let icon;
export let href = "#";
export let routePrefix;
export let newWindow;
let active = href !== "/" && ((routePrefix || href)?.toLowerCase() === currentRoute.name.toLowerCase() ||
currentRoute.name.toLowerCase().startsWith((routePrefix || href).toLowerCase()));
$: active;
</script>

View File

@ -19,12 +19,7 @@
<NavElement icon="fas fa-mouse-pointer" link="/manage/{guildId}/panels" on:click={closeDropdown}>Ticket Panels</NavElement> <NavElement icon="fas fa-mouse-pointer" link="/manage/{guildId}/panels" on:click={closeDropdown}>Ticket Panels</NavElement>
<NavElement icon="fas fa-poll-h" link="/manage/{guildId}/forms" on:click={closeDropdown}>Forms</NavElement> <NavElement icon="fas fa-poll-h" link="/manage/{guildId}/forms" on:click={closeDropdown}>Forms</NavElement>
<NavElement icon="fas fa-users" link="/manage/{guildId}/teams" on:click={closeDropdown}>Staff Teams</NavElement> <NavElement icon="fas fa-users" link="/manage/{guildId}/teams" on:click={closeDropdown}>Staff Teams</NavElement>
<NavElement icon="fas fa-robot" link="/manage/{guildId}/integrations" on:click={closeDropdown}> <NavElement icon="fas fa-robot" link="/manage/{guildId}/integrations" on:click={closeDropdown}>Integrations</NavElement>
<div style="display: flex; gap:4px">
Integrations
<Badge>New!</Badge>
</div>
</NavElement>
{/if} {/if}
<NavElement icon="fas fa-ticket-alt" link="/manage/{guildId}/tickets" on:click={closeDropdown}>Tickets</NavElement> <NavElement icon="fas fa-ticket-alt" link="/manage/{guildId}/tickets" on:click={closeDropdown}>Tickets</NavElement>
@ -63,7 +58,7 @@
<style> <style>
.navbar { .navbar {
display: flex; display: none;
justify-content: center; justify-content: center;
width: 100%; width: 100%;
background-color: #272727; background-color: #272727;
@ -89,6 +84,10 @@
} }
@media only screen and (max-width: 1154px) { @media only screen and (max-width: 1154px) {
.navbar {
display: flex;
}
.nav-section { .nav-section {
display: none; display: none;
} }

View File

@ -0,0 +1,19 @@
<div class="root">
<ul>
<slot/>
</ul>
</div>
<style>
.root {
display: flex;
flex-direction: row;
}
ul {
width: 100%;
list-style-type: none;
margin: 2px 0 0 55px;
padding: 0;
}
</style>

View File

@ -0,0 +1,53 @@
<li>
<div class="wrapper">
<a href="{href}" class:active>
{#if icon}
<i class="fas {icon}"/>
{/if}
<span>
<slot/>
</span>
</a>
</div>
</li>
<style>
li {
/*padding: 2px 0;*/
}
.wrapper {
width: 100%;
}
a.active {
font-weight: 600 !important;
}
a:not(.active) {
opacity: 0.75;
}
a, a:link, a:hover, a:visited, a:active {
color: inherit;
text-decoration: none;
}
i {
width: 20px;
text-align: center;
}
</style>
<script>
export let currentRoute;
export let icon;
export let href = "#";
export let routePrefix;
let active = href !== "/" && ((routePrefix || href).toLowerCase() === currentRoute.name.toLowerCase() ||
currentRoute.name.toLowerCase().startsWith((routePrefix || href).toLowerCase()));
$: active;
</script>

View File

@ -5,6 +5,7 @@
<div class="super-container" class:dropdown={$dropdown}> <div class="super-container" class:dropdown={$dropdown}>
<LoadingScreen/> <LoadingScreen/>
<div class="content-container" class:hide={$loadingScreen}> <div class="content-container" class:hide={$loadingScreen}>
<ManageSidebar {currentRoute} {permissionLevel} />
<Route {currentRoute} {params}/> <Route {currentRoute} {params}/>
</div> </div>
<NotifyModal/> <NotifyModal/>
@ -23,8 +24,13 @@
height: 100%; height: 100%;
} }
.super-container {
padding: 30px;
}
.content-container { .content-container {
display: flex; display: flex;
gap: 30px;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
@ -48,6 +54,7 @@
import {setDefaultHeaders} from '../includes/Auth.svelte' import {setDefaultHeaders} from '../includes/Auth.svelte'
import {permissionLevelCache} from '../js/stores'; import {permissionLevelCache} from '../js/stores';
import {get} from 'svelte/store'; import {get} from 'svelte/store';
import ManageSidebar from "../includes/ManageSidebar.svelte";
export let currentRoute; export let currentRoute;
export let params = {}; export let params = {};

View File

@ -55,7 +55,6 @@
{/if} {/if}
{#if data} {#if data}
<div class="parent">
<div class="content"> <div class="content">
<div class="main-col"> <div class="main-col">
<Card footer={false}> <Card footer={false}>
@ -87,7 +86,8 @@
{/if} {/if}
<td> <td>
<Button type="button" danger icon="fas fa-trash-can" on:click={() => removeRoleBlacklist(roleId, role)}> <Button type="button" danger icon="fas fa-trash-can"
on:click={() => removeRoleBlacklist(roleId, role)}>
Remove Remove
</Button> </Button>
</td> </td>
@ -113,7 +113,8 @@
{/if} {/if}
<td> <td>
<Button type="button" danger icon="fas fa-trash-can" on:click={() => removeUserBlacklist(user)}> <Button type="button" danger icon="fas fa-trash-can"
on:click={() => removeUserBlacklist(user)}>
Remove Remove
</Button> </Button>
</td> </td>
@ -135,7 +136,6 @@
</Card> </Card>
</div> </div>
</div> </div>
</div>
{/if} {/if}
<script> <script>
@ -296,21 +296,10 @@
</script> </script>
<style> <style>
.parent {
display: flex;
justify-content: flex-start;
padding-left: 2%;
width: 100%;
height: 100%;
}
.content { .content {
display: flex; display: flex;
justify-content: space-between; width: 100%;
width: 60%;
height: 100%; height: 100%;
margin-top: 30px;
padding-bottom: 4%;
} }
.main-col { .main-col {
@ -359,6 +348,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: 2px; gap: 2px;
margin-top: 20px;
} }
.pagination-chevron { .pagination-chevron {

View File

@ -1,4 +1,3 @@
<div class="parent">
<div class="content"> <div class="content">
<Card footer footerRight> <Card footer footerRight>
<span slot="title">Forms</span> <span slot="title">Forms</span>
@ -22,7 +21,9 @@
<div class="row form-name-edit-wrapper"> <div class="row form-name-edit-wrapper">
<Input col4 label="Form Title" placeholder="Form Title" bind:value={renamedTitle}/> <Input col4 label="Form Title" placeholder="Form Title" bind:value={renamedTitle}/>
<div class="form-name-save-wrapper"> <div class="form-name-save-wrapper">
<Button icon="fas fa-floppy-disk" fullWidth={windowWidth <= 950} on:click={updateTitle}>Save</Button> <Button icon="fas fa-floppy-disk" fullWidth={windowWidth <= 950} on:click={updateTitle}>
Save
</Button>
</div> </div>
</div> </div>
{:else} {:else}
@ -58,7 +59,8 @@
{/if} {/if}
{#if activeFormId !== null} {#if activeFormId !== null}
<div class="row" style="justify-content: center; align-items: center; gap: 10px; margin-top: 10px"> <div class="row"
style="justify-content: center; align-items: center; gap: 10px; margin-top: 10px">
<hr class="fill"> <hr class="fill">
<div class="row add-input-container" class:add-input-disabled={formLength >= 5}> <div class="row add-input-container" class:add-input-disabled={formLength >= 5}>
<i class="fas fa-plus"></i> <i class="fas fa-plus"></i>
@ -78,7 +80,6 @@
</div> </div>
</Card> </Card>
</div> </div>
</div>
<svelte:window bind:innerWidth={windowWidth}/> <svelte:window bind:innerWidth={windowWidth}/>
@ -282,20 +283,10 @@
</script> </script>
<style> <style>
.parent {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
}
.content { .content {
display: flex; display: flex;
justify-content: space-between; width: 100%;
width: 96%;
height: 100%; height: 100%;
margin-top: 30px;
margin-bottom: 50px;
} }
.body-wrapper { .body-wrapper {

View File

@ -19,8 +19,6 @@
flex-direction: row; flex-direction: row;
height: 100%; height: 100%;
width: 100%; width: 100%;
padding: 0 45px;
justify-content: space-between;
} }
.main-col { .main-col {
@ -28,7 +26,6 @@
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
width: 100%; width: 100%;
margin-top: 30px;
} }
.right-col { .right-col {

View File

@ -4,9 +4,7 @@
<TagEditor {isPremium} bind:data={editData} on:cancel={cancelEdit} on:confirm={editTag}/> <TagEditor {isPremium} bind:data={editData} on:cancel={cancelEdit} on:confirm={editTag}/>
{/if} {/if}
<div class="parent">
<div class="content"> <div class="content">
<div class="main-col">
<Card footer footerRight> <Card footer footerRight>
<span slot="title">Tags</span> <span slot="title">Tags</span>
<div slot="body" class="body-wrapper"> <div slot="body" class="body-wrapper">
@ -35,8 +33,6 @@
</div> </div>
</Card> </Card>
</div> </div>
</div>
</div>
<script> <script>
import Card from "../components/Card.svelte"; import Card from "../components/Card.svelte";
@ -45,7 +41,6 @@
import axios from "axios"; import axios from "axios";
import {API_URL} from "../js/constants"; import {API_URL} from "../js/constants";
import {setDefaultHeaders} from '../includes/Auth.svelte' import {setDefaultHeaders} from '../includes/Auth.svelte'
import {fade} from "svelte/transition";
import TagEditor from "../components/manage/TagEditor.svelte"; import TagEditor from "../components/manage/TagEditor.svelte";
export let currentRoute; export let currentRoute;
@ -192,27 +187,10 @@
</script> </script>
<style> <style>
.parent {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
}
.content { .content {
display: flex; display: flex;
justify-content: space-between; width: 100%;
width: 96%;
height: 100%; height: 100%;
margin-top: 30px;
}
.main-col {
display: flex;
flex-direction: column;
width: 64%;
height: 100%;
padding-bottom: 4%;
} }
.body-wrapper { .body-wrapper {

View File

@ -1,4 +1,3 @@
<div class="parent">
<div class="content"> <div class="content">
<Card footer={false}> <Card footer={false}>
<span slot="title">Support Teams</span> <span slot="title">Support Teams</span>
@ -76,7 +75,6 @@
</div> </div>
</Card> </Card>
</div> </div>
</div>
<script> <script>
import Card from "../components/Card.svelte"; import Card from "../components/Card.svelte";
@ -226,19 +224,10 @@
</script> </script>
<style> <style>
.parent {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
}
.content { .content {
display: flex; display: flex;
justify-content: space-between; width: 100%;
width: 96%;
height: 100%; height: 100%;
margin-top: 30px;
} }
.body-wrapper { .body-wrapper {

View File

@ -1,4 +1,3 @@
<div class="parent">
<div class="content"> <div class="content">
<Card footer={false}> <Card footer={false}>
<span slot="title">Open Tickets</span> <span slot="title">Open Tickets</span>
@ -34,11 +33,10 @@
</div> </div>
</Card> </Card>
</div> </div>
</div>
<script> <script>
import Card from "../components/Card.svelte"; import Card from "../components/Card.svelte";
import {notifyError, notifySuccess, withLoadingScreen} from '../js/util' import {notifyError, withLoadingScreen} from '../js/util'
import axios from "axios"; import axios from "axios";
import {API_URL} from "../js/constants"; import {API_URL} from "../js/constants";
import {setDefaultHeaders} from '../includes/Auth.svelte' import {setDefaultHeaders} from '../includes/Auth.svelte'
@ -67,20 +65,10 @@
</script> </script>
<style> <style>
.parent {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
margin-top: 30px;
}
.content { .content {
display: flex; display: flex;
justify-content: space-between; width: 100%;
width: 96%;
height: 100%; height: 100%;
margin-top: 30px;
} }
.body-wrapper { .body-wrapper {

View File

@ -242,9 +242,8 @@
.col { .col {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 95%;
height: 100%; height: 100%;
margin-top: 30px; width: 100%;
} }
.main-col { .main-col {

View File

@ -1,4 +1,3 @@
<div class="parent">
<div class="content"> <div class="content">
<div class="container"> <div class="container">
<div class="spread"> <div class="spread">
@ -55,10 +54,11 @@
</div> </div>
<div class="pagination"> <div class="pagination">
<i class="fas fa-chevron-left pagination-chevron" class:disabled-chevron={page === 1} on:click={previousPage}></i> <i class="fas fa-chevron-left pagination-chevron" class:disabled-chevron={page === 1}
on:click={previousPage}></i>
<p>Page {page}</p> <p>Page {page}</p>
<i class="fas fa-chevron-right pagination-chevron" class:disabled-chevron={!hasNextPage} on:click={nextPage}></i> <i class="fas fa-chevron-right pagination-chevron" class:disabled-chevron={!hasNextPage}
</div> on:click={nextPage}></i>
</div> </div>
</div> </div>
@ -161,21 +161,12 @@
</script> </script>
<style> <style>
.parent {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
}
.content { .content {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
width: 96%; width: 100%;
height: 100%; height: 100%;
margin-top: 30px;
padding-bottom: 5vh;
row-gap: 4vh; row-gap: 4vh;
} }
@ -193,7 +184,7 @@
} }
.integration { .integration {
flex: 0 0 23.5%; flex: 0 0 32%;
} }
.my-integrations { .my-integrations {
@ -231,19 +222,13 @@
cursor: default !important; cursor: default !important;
} }
@media only screen and (max-width: 1180px) { @media only screen and (max-width: 1200px) {
.integration {
flex: 0 0 32%;
}
}
@media only screen and (max-width: 930px) {
.integration { .integration {
flex: 0 0 49%; flex: 0 0 49%;
} }
} }
@media only screen and (max-width: 576px) { @media only screen and (max-width: 850px) {
.integration { .integration {
flex: 0 0 100%; flex: 0 0 100%;
} }

View File

@ -207,7 +207,7 @@
flex-direction: row; flex-direction: row;
height: 100%; height: 100%;
width: 100%; width: 100%;
margin-top: 30px; gap: 2%;
} }
.col { .col {
@ -219,7 +219,7 @@
.row { .row {
display: flex; display: flex;
width: 96%; width: 100%;
margin-bottom: 2%; margin-bottom: 2%;
} }