fix layout and updating works

Changed files
+137 -83
db
src
+35 -3
astro.config.mjs
···
provider: fontProviders.fontsource(),
name: "IBM Plex Serif",
cssVariable: "--plex-serif",
-
fallbacks: [ 'Charter', 'Bitstream Charter', 'Sitka Text', 'Cambria', 'Georgia', "serif"],
+
},
+
{
+
provider: fontProviders.fontsource(),
+
name: "Libertinus Serif",
+
cssVariable: "--libertinus-serif",
+
},
+
{
+
provider: fontProviders.fontsource(),
+
name: "Noto Serif",
+
cssVariable: "--noto-serif",
+
},
+
{
+
provider: fontProviders.fontsource(),
+
name: "Lora",
+
cssVariable: "--lora",
},
{
provider: fontProviders.fontsource(),
-
name: "IBM Plex Mono",
+
name: "iA Writer Mono",
cssVariable: "--plex-mono",
+
},
+
{
+
provider: fontProviders.fontsource(),
+
name: "Intel One Mono",
+
cssVariable: "--intel-mono",
+
},
+
{
+
provider: fontProviders.fontsource(),
+
name: "Recursive",
+
cssVariable: "--recursive",
+
styles: ["oblique", "normal"],
+
weights: [300, 1000],
+
variationSettings: "'slnt' -15 0, 'CASL' 0 1, 'CRSV' 0 1, 'MONO' 0 1",
},
{
provider: fontProviders.fontsource(),
···
style: "italic",
},
],
-
}
+
},
+
{
+
provider: fontProviders.fontsource(),
+
name: "Jacquard 12",
+
cssVariable: "--jacquard-12",
+
},
],
},
});
+9
db/seed.ts
···
await db.insert(Users).values([
{ id: 1, userDid: "test" },
{ id: 2, userDid: "another" },
+
{ userDid: "did:plc:dg2qmmjic7mmecrbvpuhtvh6", nickname: "haetae" },
]);
await db.insert(Works).values([
···
content: "<p>whoag i have <b>BOLD</b></p>",
tags: [{ label: "label", url: "#" }],
},
+
{
+
uri: "at://did:plc:dg2qmmjic7mmecrbvpuhtvh6/moe.fanfics.works/3lyeiyq32ek2o",
+
slug: "1236",
+
author: "did:plc:dg2qmmjic7mmecrbvpuhtvh6",
+
title: "testing title",
+
content: "what's up?! <b>bold</b> and <em>italics</em> should work.",
+
tags: "hey",
+
}
]);
}
+1 -2
src/actions/works.ts
···
});
}
-
// we'll just smush this in and pray
const result = await agent.com.atproto.repo.putRecord({
repo: work.author, // since the author will be a did
collection: "moe.fanfics.works",
···
title,
tags,
content,
+
createdAt: work.createdAt.toISOString(),
updatedAt: updatedAt.toISOString(),
},
validate: false,
-
swapRecord: rkey, // idk what this does
});
if (!result.success) {
+1 -17
src/assets/styles/global.css
···
--text-7xl: clamp(7.4506rem, 71.4115rem + -82.5302cqi, 52.8422rem);
--text-8xl: clamp(9.3132rem, 116.6654rem + -138.5189cqi, 85.4986rem);
--text-9xl: clamp(11.6415rem, 190.1667rem + -230.355cqi, 138.3368rem);
-
}
-
-
@custom-variant dark (&:where(
-
[data-theme=dark],
-
[data-theme=dracula],
-
[data-theme=synthwave],
-
[data-theme=halloween],
-
[data-theme=forest],
-
[data-theme=aqua],
-
[data-theme=black],
-
[data-theme=luxury],
-
[data-theme=business],
-
[data-theme=night],
-
[data-theme=coffee],
-
[data-theme=sunset],
-
[data-theme=abyss]
-
));
+
}
+1 -1
src/layouts/Layout.astro
···
<Navbar />
</header>
-
<div class:list={["min-w-[65ch] max-w-10/12 mx-auto text-base", className]} {...rest}>
+
<div class:list={["sm:w-10/12 sm:mx-auto max-w-full mx-6 text-base", className]} {...rest}>
<slot />
</div>
+2 -2
src/layouts/WorkPage.astro
···
<a href="">previous chaptertitle</a>
)}
<!-- if theres more than one chapter, render this box -->
-
<select name="chapterSelect" id={`${slug}-chapters`}>
+
<select name="chapterSelect" id={`${slug}-chapters`} class="select">
<option value="default" selected>Choose chapter...</option>
<!-- map each chapter here -->
</select>
···
</div>
</header>
-
<section id={`${slug}-content`} class="prose lg:prose-xl">
+
<section id={`${slug}-content`}>
<!-- if work has its own style, render it here somehow -->
<details>
<summary>Author's notes</summary>
+7
src/pages/errors/unauthorized.astro
···
+
---
+
import Layout from "@/layouts/Layout.astro";
+
---
+
<Layout>
+
<h1>Unauthorized</h1>
+
<p>You don't have the proper permissions to make that operation.</p>
+
</Layout>
+1 -1
src/pages/not-found.astro src/pages/errors/not-found.astro
···
---
-
import Layout from "../layouts/Layout.astro"
+
import Layout from "@/layouts/Layout.astro";
---
<Layout>
<h1>Not found!</h1>
+62 -48
src/pages/works/[workId]/edit.astro
···
.limit(1);
if (!work) {
-
return Astro.redirect("/not-found");
+
return Astro.redirect("/errors/not-found");
}
if (!loggedInUser) {
···
}
if (work.Users.userDid !== loggedInUser.did) {
-
return Astro.redirect("/unauthorized");
+
return Astro.redirect("/errors/unauthorized");
}
const result = Astro.getActionResult(actions.worksActions.updateWork);
···
<Layout skipLink={`edit-${workId}`}>
<main id={`edit-${workId}`}>
<form action={actions.worksActions.updateWork} method="post">
-
<label for="title">title</label>
-
<input
-
type="text"
-
name="title"
-
id="title"
-
aria-describedby="title-error"
-
value={work.Works.title}
-
required
-
transition:persist
-
/>
-
{errors.title && (
-
<div id="title-error">
-
{errors.title}
-
</div>
-
)}
+
<fieldset class="fieldset">
+
<label for="title" class="label">Title</label>
+
<input
+
type="text"
+
name="title"
+
id="title"
+
class="input w-full"
+
aria-describedby="title-error"
+
value={work.Works.title}
+
required
+
transition:persist
+
/>
+
{errors.title && (
+
<div id="title-error">
+
{errors.title}
+
</div>
+
)}
+
</fieldset>
-
<label for="tags">add tags</label>
-
<input
-
type="text"
-
list="tags-list"
-
name="tags"
-
id="tags"
-
aria-describedby="tags-error"
-
value={work.Works.tags as string}
-
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>
-
)}
+
<fieldset class="fieldset">
+
<label for="tags" class="label">Add tags</label>
+
<input
+
type="text"
+
list="tags-list"
+
name="tags"
+
id="tags"
+
class="input"
+
aria-describedby="tags-error"
+
value={work.Works.tags as string}
+
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>
+
)}
+
</fieldset>
-
<label for="content">body</label>
-
<textarea name="content" id="content" aria-describedby="content-error" transition:persist>
-
{work.Works.content}
-
</textarea>
-
{errors.content && (
-
<div id="content-error">
-
{errors.content}
-
</div>
-
)}
+
<fieldset class="fieldset">
+
<label for="content" class="label">Body</label>
+
<textarea
+
name="content"
+
id="content"
+
class="textarea"
+
aria-describedby="content-error"
+
transition:persist
+
>
+
{work.Works.content.trim()}
+
</textarea>
+
{errors.content && (
+
<div id="content-error">
+
{errors.content}
+
</div>
+
)}
+
</fieldset>
-
<button>submit</button>
+
<button class="btn btn-primary">Submit</button>
</form>
{result?.error && (
+7 -4
src/pages/works/[workId]/index.astro
···
const { workId } = Astro.params;
const loggedInUser = Astro.locals.loggedInUser;
-
// the work could be fetched from the database or from the pds
-
// would this potentially lighten db load? maybe
const [work] = await db.select()
.from(Works)
.where(eq(Works.slug, workId!))
···
<WorkPage
slug={work.Works.slug}
title={work.Works.title}
-
author={await didToHandle(work.Users.userDid)}
+
author={work.Users.nickname
+
? work.Users.nickname
+
: await didToHandle(work.Users.userDid)}
createdAt={work.Works.createdAt}
updatedAt={work.Works.updatedAt}
tags={work.Works.tags}
···
{(work.Users.userDid === loggedInUser?.did) && (
<a href={`/works/${workId}/edit`}>Edit your work</a>
)}
-
<Fragment set:html={work.Works.content} />
+
+
<div class="prose lg:prose-xl">
+
<Fragment set:html={work.Works.content} />
+
</div>
</WorkPage>
+11 -5
src/pages/works/index.astro
···
<Layout>
<h1 class="text-5xl">works</h1>
-
<main id="content">
+
<main id="content" class="flex flex-col gap-5 max-w-full">
{loggedInUser &&
<a href="/works/add">wanna write kid?</a>
}
-
+
{works.map(async ({ Works, Users }) => (
-
<article class="card">
+
<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>{await didToHandle(Users.userDid)}</h3>
+
<h3>
+
{Users.nickname
+
? Users.nickname
+
: await didToHandle(Users.userDid)}
+
</h3>
</hgroup>
-
<time datetime={Works.createdAt.toISOString()}>{Works.createdAt}</time>
+
<time datetime={Works.createdAt.toISOString()}>
+
{Works.createdAt.toLocaleDateString()}
+
</time>
</div>
{JSON.stringify(Works.tags)}
{/* <ul class="flex flex-wrap gap-1.5">