Compare changes

Choose any two refs to compare.

Changed files
+236 -63
src
assets
styles
components
layouts
pages
+4 -1
package.json
···
"@tailwindcss/vite": "^4.1.13",
"astro": "^5.13.7",
"nanoid": "^5.1.5",
"tailwindcss": "^4.1.13"
},
"scripts": {
···
"daisyui": "^5.1.10"
},
"trustedDependencies": [
-
"@tailwindcss/oxide"
]
}
···
"@tailwindcss/vite": "^4.1.13",
"astro": "^5.13.7",
"nanoid": "^5.1.5",
+
"quill": "^2.0.3",
"tailwindcss": "^4.1.13"
},
"scripts": {
···
"daisyui": "^5.1.10"
},
"trustedDependencies": [
+
"@tailwindcss/oxide",
+
"esbuild",
+
"sharp"
]
}
+130
src/assets/styles/global.css
···
@utility title {
font-family: var(--font-display);
font-size: var(--text-xl);
}
···
@utility title {
font-family: var(--font-display);
font-size: var(--text-xl);
+
}
+
+
body {
+
height: 100vh;
+
font-family: var(--body);
+
font-size: var(--step-0);
+
line-height: 1.5;
+
}
+
+
h1 {
+
font-size: 1.5em;
+
font-weight: bold;
+
}
+
+
label {
+
display: block;
+
font-size: .8em;
+
font-weight: bold;
+
}
+
+
input[type="text"],
+
input[type="number"],
+
input[type="email"],
+
textarea {
+
border: 1px var(--color-base-300) solid;
+
border-radius: 2px;
+
padding: 3px 5px;
+
font-size: inherit;
+
font-family: var(--sans);
+
width: 100%;
+
}
+
+
.btn-primary,
+
button[type="submit"],
+
input[type="submit"],
+
input[type="reset"] {
+
background-color: var(--color-primary);
+
color: var(--color-primary-content);
+
border-radius: 4px;
+
padding: 5px 10px;
+
font-size: 1em;
+
font-weight: bold;
+
text-align: center;
+
min-width: 150px;
+
transition: 0.3s;
+
position: relative;
+
}
+
+
.btn-primary:hover,
+
button[type="submit"]:hover,
+
input[type="submit"]:hover,
+
input[type="reset"]:hover {
+
background-color: color-mix(in srgb-linear, var(--color-primary), #000000 20%);
+
}
+
+
.btn-primary:active,
+
button[type="submit"]:active,
+
input[type="submit"]:active,
+
input[type="reset"]:active {
+
top: 1px;
+
}
+
+
.input-field {
+
display: block;
+
margin-bottom: 1em;
+
}
+
+
nav ul.menu {
+
gap: 20px;
+
align-items: center;
+
}
+
+
nav ul.menu form:hover {
+
background-color: transparent;
+
border-radius: none;
+
}
+
+
nav ul.menu .search-label {
+
width: 1px;
+
height: 1px;
+
position: absolute;
+
overflow: hidden;
+
text-indent: -100px;
+
}
+
+
nav ul.menu a {
+
padding-bottom: 5px;
+
border-width: 0 0 5px 0;
+
padding: 5px 0;
+
border-color: transparent;
+
border-style: solid;
+
box-shadow: none;
+
background-color: transparent;
+
border-radius: 0;
+
}
+
+
nav ul.menu a:hover {
+
border-width: 0 0 5px 0;
+
border-color: var(--color-secondary);
+
border-style: solid;
+
}
+
+
.ql-toolbar.ql-snow {
+
border-color: var(--color-base-300) !important;
+
border-radius: 2px 2px 0 0;
+
}
+
+
#content.ql-container.ql-snow {
+
border-color: var(--color-base-300);
+
border-radius: 0 0 2px 2px;
+
}
+
+
article.card {
+
border: 1px var(--color-base-300) solid;
+
border-radius: 5px;
+
}
+
+
article.card h2 {
+
font-size: 1.1em;
+
font-weight: bold;
+
}
+
+
article.card .author {
+
font-size: .8em;
+
font-weight: normal;
+
font-style: italic;
+
}
+
+
article.card time {
+
font-size: .8em;
}
+7 -2
src/components/Navbar.astro
···
---
<nav id="main-nav" class="navbar bg-base-100">
<div class="flex-1">
-
<a href="/" class="btn btn-ghost font-display text-xl">Home</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
-
<li><a href="/search">Search</a></li>
<li><a href="/works">Works</a></li>
{loggedInUser
? <>
···
---
<nav id="main-nav" class="navbar bg-base-100">
<div class="flex-1">
+
<a href="/" class="font-display text-xl">Home</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
+
<li>
+
<form method="get">
+
<label class="label search-label" for="work-search">Search</label>
+
<input class="input" type="search" name="workSearch" id="work-search" placeholder="Search" />
+
</form>
+
</li>
<li><a href="/works">Works</a></li>
{loggedInUser
? <>
+1 -1
src/layouts/Layout.astro
···
<slot />
</div>
-
<footer class="footer sm:footer-horizontal footer-center bg-base-300 text-base-content mt-auto p-5">
copyright or something ig
</footer>
</body>
···
<slot />
</div>
+
<footer class="footer sm:footer-horizontal footer-center bg-base-300 text-base-content mt-5 p-5">
copyright or something ig
</footer>
</body>
+1 -1
src/pages/index.astro
···
<button>logout</button>
</form>
</>
-
: <a href="/login">login</a>}
</Layout>
···
<button>logout</button>
</form>
</>
+
: <a href="/login" class="btn">login</a>}
</Layout>
+74 -48
src/pages/works/add.astro
···
---
import Layout from "@/layouts/Layout.astro";
import { actions, isInputError } from "astro:actions";
const loggedInUser = Astro.locals.loggedInUser;
···
<h1>Add a new work</h1>
<form action={actions.worksActions.addWork} method="post">
-
<label for="title">title</label>
-
<input
-
type="text"
-
name="title"
-
id="title"
-
aria-describedby="title-error"
-
required
-
transition:persist
-
/>
-
{errors.title && (
-
<div id="title-error">
-
{errors.title}
-
</div>
-
)}
-
<label for="tags">add tags</label>
-
<input
-
type="text"
-
list="tags-list"
-
name="tags"
-
id="tags"
-
aria-describedby="tags-error"
-
transition:persist
-
/>
-
<!-- could be cool to fetch tags from a tags server or smth? idk -->
-
<datalist id="tags-list">
-
<option value="test">here</option>
-
<option value="tag2">another</option>
-
<option value="tag3">try them all!</option>
-
</datalist>
-
{errors.tags && (
-
<div id="tags-error">
-
{errors.tags}
-
</div>
-
)}
-
<label for="content">body</label>
-
<!-- replace this with a rich text editor / code editor later -->
-
<textarea name="content" id="content" aria-describedby="content-error" transition:persist></textarea>
-
{errors.content && (
-
<div id="content-error">
-
{errors.content}
-
</div>
-
)}
-
-
<label for="publish">Publish to your PDS?</label>
-
<input type="checkbox" name="publish" id="publish" />
-
-
<button>submit</button>
</form>
{result?.error && (
···
</div>
)}
</main>
-
</Layout>
···
---
import Layout from "@/layouts/Layout.astro";
import { actions, isInputError } from "astro:actions";
+
import "quill/dist/quill.core.css";
+
import "quill/dist/quill.snow.css";
const loggedInUser = Astro.locals.loggedInUser;
···
<h1>Add a new work</h1>
<form action={actions.worksActions.addWork} method="post">
+
<div class="input-field">
+
<label for="title">Title</label>
+
<input
+
type="text"
+
name="title"
+
id="title"
+
aria-describedby="title-error"
+
required
+
transition:persist
+
/>
+
{errors.title && (
+
<div id="title-error">
+
{errors.title}
+
</div>
+
)}
+
</div>
+
<div class="input-field">
+
<label for="tags">Add Tags</label>
+
<input
+
type="text"
+
list="tags-list"
+
name="tags"
+
id="tags"
+
aria-describedby="tags-error"
+
transition:persist
+
/>
+
<!-- could be cool to fetch tags from a tags server or smth? idk -->
+
<!-- maybe from labelers the instance is subscribed to? - @veryroundbird.house -->
+
<datalist id="tags-list">
+
<option value="test">here</option>
+
<option value="tag2">another</option>
+
<option value="tag3">try them all!</option>
+
</datalist>
+
{errors.tags && (
+
<div id="tags-error">
+
{errors.tags}
+
</div>
+
)}
+
</div>
+
<div class="input-field">
+
<label for="content">Work Text</label>
+
<div id="content" aria-describedby="content-error" transition:persist rows="50"></div>
+
{errors.content && (
+
<div id="content-error">
+
{errors.content}
+
</div>
+
)}
+
</div>
+
<div class="input-field">
+
<label for="publish"><input type="checkbox" name="publish" id="publish" /> Publish to your PDS?</label>
+
</div>
+
<div class="input-field">
+
<button type="submit" class="btn-primary">Submit</button>
+
</div>
</form>
{result?.error && (
···
</div>
)}
</main>
+
</Layout>
+
+
<script>
+
import Quill from "quill";
+
+
const quill = new Quill('#content', {
+
theme: 'snow',
+
modules: {
+
syntax: true
+
}
+
});
+
</script>
+
+
<style>
+
#content {
+
min-height: 50vh;
+
}
+
</style>
+19 -10
src/pages/works/index.astro
···
{works.map(async ({ Works, Users }) => (
<article class="card rounded-box shadow p-5">
<header>
-
<div class="flex items-center justify-between">
<hgroup class="flex-1">
<h2 class="card-title">
<a href={`/works/${Works.slug}`}>{Works.title}</a>
</h2>
-
<h3>
{Users.nickname
? Users.nickname
: await didToHandle(Users.userDid)}
-
</h3>
</hgroup>
<time datetime={Works.createdAt.toISOString()}>
{Works.createdAt.toLocaleDateString()}
</time>
</div>
-
{JSON.stringify(Works.tags)}
-
{/* <ul class="flex flex-wrap gap-1.5">
-
{(Works.tags as Tag[]).map((tag: Tag) => (
-
<li><a class="tag" href={tag.url}>{tag.label}</a></li>
-
))}
-
</ul> */}
</header>
<div class="card-body prose lg:prose-xl">
···
@reference "../../assets/styles/global.css";
.tag {
-
@apply btn btn-accent;
}
</style>
···
{works.map(async ({ Works, Users }) => (
<article class="card rounded-box shadow p-5">
<header>
+
<div class="flex items-top justify-between">
<hgroup class="flex-1">
<h2 class="card-title">
<a href={`/works/${Works.slug}`}>{Works.title}</a>
</h2>
+
<p class="author">
{Users.nickname
? Users.nickname
: await didToHandle(Users.userDid)}
+
</p>
</hgroup>
<time datetime={Works.createdAt.toISOString()}>
{Works.createdAt.toLocaleDateString()}
</time>
</div>
+
{Array.isArray(Works.tags) &&
+
<ul class="flex flex-wrap gap-1.5">
+
{(Works.tags as Tag[]).map((tag: Tag) => (
+
<li><a class="tag" href={tag.url}>{tag.label}</a></li>
+
))}
+
</ul> }
</header>
<div class="card-body prose lg:prose-xl">
···
@reference "../../assets/styles/global.css";
.tag {
+
@apply btn btn-accent;
+
padding: 3px 12px;
+
border-radius: 12px;
+
height: auto;
+
line-height: 1;
+
}
+
+
.card-body {
+
padding-left: 0;
+
padding-right: 0;
}
</style>