Skip to content

Commit b23e0dc

Browse files
committed
Improvements to tags pages
1 parent 27ec2bf commit b23e0dc

File tree

6 files changed

+38
-13
lines changed

6 files changed

+38
-13
lines changed

app/components/Tag.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { Link as RemixLink } from "@remix-run/react";
33
type TagProps = {
44
tag: string,
55
url: string,
6+
onClick?: (e: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void,
67
}
78

8-
export function Tag({ tag, url }: TagProps) {
9+
export function Tag({ tag, onClick, url }: TagProps) {
910
return (
1011
<RemixLink
1112
key={tag}
1213
to={url}
14+
onClick={onClick}
1315
preventScrollReset={true}
1416
className="badge text-bg-primary text-decoration-none me-2"
1517
>

app/components/TagTree.tsx

+12-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,18 @@ export type TagTreeEntry = {
1313

1414
function TagTreeRow(tag: string, currentTag: string, entries: SerializeFrom<TagTreeEntry>[]) {
1515
return (
16-
<details className="mt-2" open={tag === currentTag}>
17-
<summary><Tag tag={tag} url={`?tag=${encodeURIComponent(tag)}`} /></summary>
16+
<details className="mt-2" open={tag === currentTag} key={tag} id={tag}>
17+
<summary><Tag tag={tag} url={`?tag=${encodeURIComponent(tag)}`} onClick={(e) => {
18+
console.log(`clicked ${tag}`);
19+
e.preventDefault();
20+
const el = document.getElementById(tag) as HTMLDetailsElement | null;
21+
if (el == null) {
22+
console.log(`how is el for ${tag} null?`);
23+
return;
24+
}
25+
el.open = !el.open;
26+
history.replaceState(null, "", `?tag=${encodeURIComponent(tag)}`);
27+
}} /> ({entries.length})</summary>
1828
<ul className="mt-1">
1929
{entries?.map((entry) => (
2030
<li key={entry.url}>

app/routes/links.edit[.]html.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { ActionFunctionArgs, LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
22
import { json, Link as RemixLink, redirect, useLoaderData, useSearchParams } from "@remix-run/react";
33
import { eq } from "drizzle-orm"
4+
import { PiArrowSquareOut } from "react-icons/pi";
45

56
import { dborm } from "~/db/connection.server";
67
import { regex_link } from "~/db/schema";
@@ -81,7 +82,7 @@ export default function Index() {
8182
const [searchParams] = useSearchParams();
8283
const next = searchParams.get("next") || "/links/";
8384

84-
const theLink = data.link;
85+
const theLink = data.link as unknown as typeof regex_link.$inferSelect;
8586

8687
return (
8788
<>
@@ -90,7 +91,7 @@ export default function Index() {
9091
<input type="hidden" name="rxl_id" value={theLink.rxl_id} />
9192
<input type="hidden" name="next" value={next} />
9293
<div className="mb-3">
93-
<label htmlFor="rxl_url" className="form-label">URL</label>
94+
<label htmlFor="rxl_url" className="form-label">URL <a className="ms-2" href={theLink.rxl_url} target="_new">open<PiArrowSquareOut className="ms-1"/></a></label>
9495
<input type="text" className="form-control" id="rxl_url" name="rxl_url" defaultValue={theLink.rxl_url} />
9596
</div>
9697
<div className="mb-3">

app/routes/links.tags[.]html.tsx

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import type { MetaFunction } from "@remix-run/node";
1+
import type { LoaderFunctionArgs, MetaFunction } from "@remix-run/node";
22
import { json, Link as RemixLink, useLoaderData, useSearchParams } from "@remix-run/react";
33
import { dbconnection } from "~/db/connection.server";
44
import { TagTree, TagTreeEntry } from "~/components/TagTree";
5+
import { authenticator } from "~/services/auth.server";
56

67

78
export const meta: MetaFunction = () => {
@@ -10,7 +11,9 @@ export const meta: MetaFunction = () => {
1011
];
1112
};
1213

13-
export async function loader() {
14+
export async function loader({ request }: LoaderFunctionArgs) {
15+
16+
const user = await authenticator.isAuthenticated(request);
1417

1518
const taglinks = await dbconnection`SELECT rxl_id, rxl_title, rxl_url, UNNEST(rxl_tags) as tag FROM regex_link ORDER BY tag`;
1619

@@ -22,7 +25,11 @@ export async function loader() {
2225
links = [];
2326
tagmap[tag] = links;
2427
}
25-
links.push({ id: taglink.rxl_id, title: taglink.rxl_title, url: taglink.rxl_url });
28+
links.push({
29+
id: taglink.rxl_id,
30+
title: taglink.rxl_title,
31+
url: user?.isAdmin ? `/links/edit.html?rxl_id=${encodeURIComponent(taglink.rxl_id)}` : taglink.rxl_url
32+
});
2633
}
2734

2835
return json(tagmap);
@@ -37,7 +44,10 @@ export default function Tags() {
3744
<>
3845
<h1 className="py-2">Links by Tag</h1>
3946
{TagTree(currentTag, tagMap)}
40-
<RemixLink to="/links/untagged.html" className="btn btn-primary">Untagged</RemixLink>
47+
<div className="mt-3">
48+
{Object.entries(tagMap).length} tags
49+
</div>
50+
<RemixLink to="/links/untagged.html" className="btn btn-primary mt-3">Untagged</RemixLink>
4151
</>
4252
);
4353

app/routes/patterns.tags[.]html.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,9 @@ export default function Tags() {
4343
<>
4444
<h1 className="py-2">Tags</h1>
4545
{ TagTree(currentTag, tagMap) }
46-
<hr />
47-
<details><summary>Raw data</summary>
48-
<pre>{JSON.stringify(tagMap, null, 4)}</pre>
49-
</details>
46+
<div className="mt-3">
47+
{Object.entries(tagMap).length} tags
48+
</div>
5049
</>
5150
);
5251
}

app/util/constants.ts

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
3+
export const MIN_ARCHIVE_YEAR = 2007;

0 commit comments

Comments
 (0)