Skip to content

Commit

Permalink
create tag page (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohannesNakayama committed Oct 11, 2024
1 parent 145f744 commit cf5ca94
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
46 changes: 46 additions & 0 deletions app/modules/posts/post-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { type DB } from '#app/types/kysely-types.ts'
import { invariant } from '#app/utils/misc.tsx'
import { insertPostTag, insertTag } from '../tags/tag-repository.ts'
import { tagContent } from '../tags/tagger-client.ts'
import { getPollPost } from './polls/poll-repository.ts'
import { incrementReplyCount, insertPost } from './post-repository.ts'
import { type PollPagePost, type PollType, type Post } from './post-types.ts'
import { vote } from './scoring/vote-service.ts'

export async function createPost(
Expand Down Expand Up @@ -62,3 +64,47 @@ export async function initPostStats(trx: Transaction<DB>, postId: number) {
.onConflict(oc => oc.column('postId').doNothing())
.execute()
}

export async function getPostsAndPollsByTagId(
trx: Transaction<DB>,
tagId: number,
): Promise<{
posts: Post[]
polls: PollPagePost[]
}> {
const results = await trx
.selectFrom('Post')
.innerJoin('PostTag', 'PostTag.postId', 'Post.id')
.leftJoin('Poll', 'Poll.postId', 'Post.id')
.where('PostTag.tagId', '=', tagId)
.selectAll('Post')
.select(['Poll.pollType as pollType'])
.execute()

const posts = results
.filter(row => row.pollType === null)
.map(row => {
return {
id: row.id,
parentId: row.parentId,
content: row.content,
createdAt: row.createdAt,
deletedAt: row.deletedAt,
isPrivate: row.isPrivate,
pollType: row.pollType as PollType,
}
})

const polls = await Promise.all(
results
.filter(row => row.pollType !== null)
.map(async row => {
return await getPollPost(trx, row.id)
}),
)

return {
posts: posts,
polls: polls,
}
}
11 changes: 11 additions & 0 deletions app/modules/tags/tag-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ export async function getTag(trx: Transaction<DB>, tag: string): Promise<Tag> {
.executeTakeFirstOrThrow()
}

export async function getTagById(
trx: Transaction<DB>,
tagId: number,
): Promise<Tag> {
return await trx
.selectFrom('Tag')
.where('id', '=', tagId)
.selectAll()
.executeTakeFirstOrThrow()
}

export async function insertPostTag(
trx: Transaction<DB>,
postId: number,
Expand Down
66 changes: 66 additions & 0 deletions app/routes/tag.$tagId.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { json, type LoaderFunctionArgs } from '@remix-run/node'
import { useLoaderData } from '@remix-run/react'
import { z } from 'zod'
import { Markdown } from '#app/components/markdown.tsx'
import { db } from '#app/db.ts'
import { getPostsAndPollsByTagId } from '#app/modules/posts/post-service.ts'
import { type PollPagePost, type Post } from '#app/modules/posts/post-types.ts'
import { getTagById } from '#app/modules/tags/tag-repository.ts'
import { type Tag } from '#app/modules/tags/tag-types.ts'

const tagIdSchema = z.coerce.number()

export async function loader({ params }: LoaderFunctionArgs) {
const tagId = tagIdSchema.parse(params.tagId)
const {
tag,
posts,
polls,
}: {
tag: Tag
posts: Post[]
polls: PollPagePost[]
} = await db.transaction().execute(async trx => {
const tag = await getTagById(trx, tagId)
const { posts, polls } = await getPostsAndPollsByTagId(trx, tag.id)
return {
tag: tag,
posts: posts,
polls: polls,
}
})

return json({ tag, posts, polls })
}

export default function TagPage() {
const { tag, posts, polls } = useLoaderData<typeof loader>()

return (
<>
<div className="mb-6">
<Markdown deactivateLinks={false}>{`# # ${tag.tag}`}</Markdown>
</div>
<div className="mb-6">
<h1>Posts</h1>
{posts.map(post => {
return (
<div key={`post-${post.id}`} className="mb-4">
{post.content}
</div>
)
})}
</div>
<div className="mb-6">
<h1>Polls</h1>
{polls.map(poll => {
return (
<div key={`post-${poll.id}`} className="mb-4">
{poll.content}
</div>
)
})}
</div>
</>
)
}

0 comments on commit cf5ca94

Please sign in to comment.