diff --git a/flake.nix b/flake.nix
index 401db06..90279a9 100644
--- a/flake.nix
+++ b/flake.nix
@@ -23,6 +23,7 @@
in
{
api = pkgs.mkShell {
+ packages = with pkgs; [ postgresql_16 ];
shellHook = ''
alias dbmate="${pkgs.dbmate}/bin/dbmate --url postgres://postgres@localhost:15432/archtika?sslmode=disable"
alias formatsql="${pkgs.pgformatter}/bin/pg_format -s 2 -f 2 -U 2 -i db/migrations/*.sql"
diff --git a/web-app/src/app.css b/web-app/src/app.css
index e01e5e4..e4deba5 100644
--- a/web-app/src/app.css
+++ b/web-app/src/app.css
@@ -12,6 +12,40 @@
--border-primary: 0.0625rem solid var(--bg-tertiary);
--border-radius: 0.125rem;
+ /* Step -1: 14.9953px → 14.9953px */
+ --font-size--1: clamp(0.9372rem, 0.9372rem + 0cqi, 0.9372rem);
+ /* Step 0: 16px → 16px */
+ --font-size-0: clamp(1rem, 1rem + 0cqi, 1rem);
+ /* Step 1: 17.072px → 17.072px */
+ --font-size-1: clamp(1.067rem, 1.067rem + 0cqi, 1.067rem);
+ /* Step 2: 18.2158px → 18.2158px */
+ --font-size-2: clamp(1.1385rem, 1.1385rem + 0cqi, 1.1385rem);
+ /* Step 3: 19.4363px → 19.4363px */
+ --font-size-3: clamp(1.2148rem, 1.2148rem + 0cqi, 1.2148rem);
+ /* Step 4: 20.7385px → 20.7385px */
+ --font-size-4: clamp(1.2962rem, 1.2962rem + 0cqi, 1.2962rem);
+ /* Step 5: 22.128px → 22.128px */
+ --font-size-5: clamp(1.383rem, 1.383rem + 0cqi, 1.383rem);
+
+ /* Space 3xs: 4px → 5px */
+ --space-3xs: clamp(0.25rem, 0.2336rem + 0.0822cqi, 0.3125rem);
+ /* Space 2xs: 8px → 10px */
+ --space-2xs: clamp(0.5rem, 0.4671rem + 0.1645cqi, 0.625rem);
+ /* Space xs: 12px → 15px */
+ --space-xs: clamp(0.75rem, 0.7007rem + 0.2467cqi, 0.9375rem);
+ /* Space s: 16px → 20px */
+ --space-s: clamp(1rem, 0.9342rem + 0.3289cqi, 1.25rem);
+ /* Space m: 24px → 30px */
+ --space-m: clamp(1.5rem, 1.4013rem + 0.4934cqi, 1.875rem);
+ /* Space l: 32px → 40px */
+ --space-l: clamp(2rem, 1.8684rem + 0.6579cqi, 2.5rem);
+ /* Space xl: 48px → 60px */
+ --space-xl: clamp(3rem, 2.8026rem + 0.9868cqi, 3.75rem);
+ /* Space 2xl: 64px → 80px */
+ --space-2xl: clamp(4rem, 3.7368rem + 1.3158cqi, 5rem);
+ /* Space 3xl: 96px → 120px */
+ --space-3xl: clamp(6rem, 5.6053rem + 1.9737cqi, 7.5rem);
+
color-scheme: light;
}
@@ -51,11 +85,11 @@ body {
section {
display: flex;
flex-direction: column;
- gap: 1rem;
+ gap: var(--space-s);
}
section + section {
- margin-block-start: 2rem;
+ margin-block-start: var(--space-l);
}
button,
@@ -63,7 +97,8 @@ label,
select,
summary,
[role="button"],
-[role="option"] {
+[role="option"],
+label[for="toggle-mobile-preview"] {
cursor: pointer;
}
@@ -71,13 +106,14 @@ input,
button,
textarea,
select,
-a[role="button"] {
+a[role="button"],
+label[for="toggle-mobile-preview"] {
font: inherit;
color: inherit;
border: var(--border-primary);
border-radius: var(--border-radius);
- padding-inline: 0.5rem;
- padding-block: 0.25rem;
+ padding-inline: var(--space-2xs);
+ padding-block: var(--space-3xs);
}
input,
@@ -90,6 +126,10 @@ textarea {
resize: vertical;
}
+input[type="file"] {
+ inline-size: 100%;
+}
+
a {
color: var(--color-accent);
}
@@ -101,14 +141,21 @@ a[role="button"] {
}
button,
-a[role="button"] {
+a[role="button"],
+label[for="toggle-mobile-preview"] {
background-color: var(--bg-secondary);
}
-:is(button, a[role="button"]):hover {
+:is(button, a[role="button"], label[for="toggle-mobile-preview"]):hover {
background-color: var(--bg-tertiary);
}
+:is(a, button, input, textarea, select):focus,
+#toggle-mobile-preview:checked + label {
+ outline: 0.125rem solid var(--color-accent);
+ outline-offset: 0.25rem;
+}
+
img,
picture,
svg,
@@ -132,18 +179,29 @@ h6 {
overflow-wrap: break-word;
}
-h1,
-h2,
-h3,
+h6 {
+ font-size: var(--font-size-0);
+}
+h5 {
+ font-size: var(--font-size-1);
+}
h4 {
- line-height: 1.2;
- text-wrap: balance;
+ font-size: var(--font-size-2);
+}
+h3 {
+ font-size: var(--font-size-3);
+}
+h2 {
+ font-size: var(--font-size-4);
+}
+h1 {
+ font-size: var(--font-size-5);
}
form[method="POST"] {
display: flex;
flex-direction: column;
- gap: 1rem;
+ gap: var(--space-s);
}
form > button[type="submit"] {
@@ -152,7 +210,7 @@ form > button[type="submit"] {
form[method="GET"] {
display: grid;
- gap: 1rem;
+ gap: var(--space-s);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 20ch), 1fr));
align-items: start;
}
@@ -164,7 +222,7 @@ form[method="GET"] > button[type="submit"] {
form label {
display: flex;
flex-direction: column;
- gap: 0.25rem;
+ gap: var(--space-2xs);
max-inline-size: 30ch;
}
@@ -175,6 +233,6 @@ form label:has(textarea) {
form .file-field {
display: flex;
align-items: end;
- gap: 0.5rem;
+ gap: var(--space-2xs);
flex-wrap: wrap;
}
diff --git a/web-app/src/lib/components/Modal.svelte b/web-app/src/lib/components/Modal.svelte
index 445c146..a5f5683 100644
--- a/web-app/src/lib/components/Modal.svelte
+++ b/web-app/src/lib/components/Modal.svelte
@@ -25,7 +25,7 @@
display: flex;
flex-direction: column;
align-items: center;
- padding: 1rem;
+ padding: var(--space-s);
}
.modal__closeoverlay {
@@ -38,15 +38,15 @@
.modal__content {
display: flex;
flex-direction: column;
- gap: 2rem;
- padding-inline: 1rem;
- padding-block: 2rem;
+ gap: var(--space-s);
+ padding-inline: var(--space-s);
+ padding-block: var(--space-m);
background-color: var(--bg-primary);
border-radius: var(--border-radius);
border: var(--border-primary);
inline-size: 300px;
max-inline-size: 100%;
- max-block-size: calc(100vh - 2rem);
+ max-block-size: calc(100vh - var(--space-m));
overflow-y: auto;
z-index: 20;
}
diff --git a/web-app/src/lib/components/SuccessOrError.svelte b/web-app/src/lib/components/SuccessOrError.svelte
index 436145e..3b52515 100644
--- a/web-app/src/lib/components/SuccessOrError.svelte
+++ b/web-app/src/lib/components/SuccessOrError.svelte
@@ -16,10 +16,12 @@
diff --git a/web-app/src/routes/(authenticated)/+page.server.ts b/web-app/src/routes/(authenticated)/+page.server.ts
index d9a63ab..d896d21 100644
--- a/web-app/src/routes/(authenticated)/+page.server.ts
+++ b/web-app/src/routes/(authenticated)/+page.server.ts
@@ -1,9 +1,10 @@
import type { Actions, PageServerLoad } from "./$types";
import { API_BASE_PREFIX } from "$lib/utils";
-export const load: PageServerLoad = async ({ fetch, cookies, url }) => {
+export const load: PageServerLoad = async ({ fetch, cookies, url, locals }) => {
const searchQuery = url.searchParams.get("website_search_query");
const sortBy = url.searchParams.get("website_sort");
+ const filterBy = url.searchParams.get("website_filter");
const params = new URLSearchParams();
@@ -29,6 +30,15 @@ export const load: PageServerLoad = async ({ fetch, cookies, url }) => {
break;
}
+ switch (filterBy) {
+ case "creations":
+ params.append("user_id", `eq.${locals.user.id}`);
+ break;
+ case "shared":
+ params.append("user_id", `not.eq.${locals.user.id}`);
+ break;
+ }
+
const constructedFetchUrl = `${baseFetchUrl}?${params.toString()}`;
const totalWebsitesData = await fetch(baseFetchUrl, {
diff --git a/web-app/src/routes/(authenticated)/+page.svelte b/web-app/src/routes/(authenticated)/+page.svelte
index 8ec8870..746bd44 100644
--- a/web-app/src/routes/(authenticated)/+page.svelte
+++ b/web-app/src/routes/(authenticated)/+page.svelte
@@ -157,24 +157,24 @@
diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.server.ts b/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.server.ts
index da0bd19..cfaa6e2 100644
--- a/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.server.ts
+++ b/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.server.ts
@@ -1,9 +1,10 @@
import type { Actions, PageServerLoad } from "./$types";
import { API_BASE_PREFIX } from "$lib/utils";
-export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent }) => {
+export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent, locals }) => {
const searchQuery = url.searchParams.get("article_search_query");
const sortBy = url.searchParams.get("article_sort");
+ const filterBy = url.searchParams.get("article_filter");
const parameters = new URLSearchParams();
@@ -29,6 +30,15 @@ export const load: PageServerLoad = async ({ params, fetch, cookies, url, parent
break;
}
+ switch (filterBy) {
+ case "creations":
+ parameters.append("user_id", `eq.${locals.user.id}`);
+ break;
+ case "shared":
+ parameters.append("user_id", `not.eq.${locals.user.id}`);
+ break;
+ }
+
const constructedFetchUrl = `${baseFetchUrl}&${parameters.toString()}`;
const totalArticlesData = await fetch(baseFetchUrl, {
diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.svelte b/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.svelte
index 8be8554..a0bb03e 100644
--- a/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.svelte
+++ b/web-app/src/routes/(authenticated)/website/[websiteId]/articles/+page.svelte
@@ -66,6 +66,14 @@
{/each}
+
@@ -109,19 +117,24 @@
.article-card {
display: flex;
align-items: center;
- column-gap: 2rem;
- row-gap: 0.5rem;
+ column-gap: var(--space-s);
+ row-gap: var(--space-2xs);
flex-wrap: wrap;
justify-content: space-between;
}
+ .article-card + .article-card {
+ padding-block-start: var(--space-s);
+ border-block-start: var(--border-primary);
+ }
+
.article-card:nth-of-type(1) {
- margin-block-start: 1rem;
+ margin-block-start: var(--space-m);
}
.article-card__actions {
display: flex;
- gap: 1rem;
+ gap: var(--space-s);
align-items: center;
}
diff --git a/web-app/src/routes/(authenticated)/website/[websiteId]/collaborators/+page.svelte b/web-app/src/routes/(authenticated)/website/[websiteId]/collaborators/+page.svelte
index 04e7420..bdeaee5 100644
--- a/web-app/src/routes/(authenticated)/website/[websiteId]/collaborators/+page.svelte
+++ b/web-app/src/routes/(authenticated)/website/[websiteId]/collaborators/+page.svelte
@@ -117,19 +117,24 @@
.collaborator-card {
display: flex;
align-items: center;
- column-gap: 2rem;
- row-gap: 0.5rem;
+ column-gap: var(--space-s);
+ row-gap: var(--space-2xs);
flex-wrap: wrap;
justify-content: space-between;
}
+ .collaborator-card + .collaborator-card {
+ padding-block-start: var(--space-s);
+ border-block-start: var(--border-primary);
+ }
+
.collaborator-card:nth-of-type(1) {
- margin-block-start: 1rem;
+ margin-block-start: var(--space-xs);
}
.collaborator-card__actions {
display: flex;
- gap: 0.5rem;
+ gap: var(--space-2xs);
align-items: center;
}
diff --git a/web-app/src/routes/+layout.svelte b/web-app/src/routes/+layout.svelte
index c0b2f62..df24635 100644
--- a/web-app/src/routes/+layout.svelte
+++ b/web-app/src/routes/+layout.svelte
@@ -3,7 +3,6 @@
import { page } from "$app/stores";
import type { LayoutServerData } from "./$types";
import type { Snippet } from "svelte";
- import { dev } from "$app/environment";
const { data, children } = $props<{ data: LayoutServerData; children: Snippet }>();
@@ -17,13 +16,23 @@
{#if !isProjectRoute}
@@ -38,7 +47,9 @@
@@ -47,20 +58,24 @@
header,
main,
footer {
- padding-block: 1rem;
- inline-size: min(100% - 2rem, 1024px);
+ padding-block: var(--space-s);
+ inline-size: min(100% - var(--space-m), 1024px);
margin-inline: auto;
}
nav {
display: flex;
align-items: center;
- gap: 1rem;
- overflow-x: auto;
+ column-gap: var(--space-m);
+ row-gap: var(--space-3xs);
+ flex-wrap: wrap;
+ justify-content: space-between;
}
- nav > *:first-child {
- margin-inline-end: auto;
+ nav > .link-wrapper {
+ display: flex;
+ align-items: center;
+ gap: var(--space-s);
}
footer {
@@ -69,11 +84,17 @@
}
.editor {
- inline-size: min(100% - 2rem, 1536px);
- block-size: calc(100vh - 7rem);
- border-block-start: var(--border-primary);
display: grid;
- grid-template-columns: 1fr 1fr;
+ block-size: calc(100vh - (4 * var(--space-s) + 2 * 1.5rem));
+ inline-size: min(100% - var(--space-m), 1536px);
+ border-block-start: var(--border-primary);
padding-block: 0;
+ position: relative;
+ }
+
+ @media (min-width: 640px) {
+ .editor {
+ grid-template-columns: 1fr 1fr;
+ }
}