Remove old post types to reduce confusion

This commit is contained in:
Justin Edmund 2025-06-11 00:06:44 -07:00
parent 318f33709f
commit 3d993d76ed
13 changed files with 45 additions and 227 deletions

0
prisma/dev.db Normal file
View file

View file

@ -0,0 +1,24 @@
/*
Warnings:
- You are about to drop the column `albumId` on the `Post` table. All the data in the column will be lost.
- You are about to drop the column `linkDescription` on the `Post` table. All the data in the column will be lost.
- You are about to drop the column `linkUrl` on the `Post` table. All the data in the column will be lost.
- You are about to drop the column `photoId` on the `Post` table. All the data in the column will be lost.
- You are about to drop the `_db_initialization` table. If the table is not empty, all the data it contains will be lost.
*/
-- DropForeignKey
ALTER TABLE "Post" DROP CONSTRAINT "Post_albumId_fkey";
-- DropForeignKey
ALTER TABLE "Post" DROP CONSTRAINT "Post_photoId_fkey";
-- AlterTable
ALTER TABLE "Post" DROP COLUMN "albumId",
DROP COLUMN "linkDescription",
DROP COLUMN "linkUrl",
DROP COLUMN "photoId";
-- DropTable
DROP TABLE "_db_initialization";

View file

@ -43,16 +43,10 @@ model Project {
model Post {
id Int @id @default(autoincrement())
slug String @unique @db.VarChar(255)
postType String @db.VarChar(50) // blog, microblog, link, photo, album
postType String @db.VarChar(50) // blog, microblog
title String? @db.VarChar(255) // Optional for microblog posts
content Json? // BlockNote JSON for blog/microblog
// Type-specific fields
linkUrl String? @db.VarChar(500)
linkDescription String? @db.Text
photoId Int?
albumId Int?
featuredImage String? @db.VarChar(500)
attachments Json? // Array of media IDs for photo attachments
tags Json? // Array of tags
@ -61,10 +55,6 @@ model Post {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
photo Photo? @relation(fields: [photoId], references: [id])
album Album? @relation(fields: [albumId], references: [id])
@@index([slug])
@@index([status])
@@index([postType])
@ -87,7 +77,6 @@ model Album {
// Relations
photos Photo[]
posts Post[]
@@index([slug])
@@index([status])
@ -118,7 +107,6 @@ model Photo {
// Relations
album Album? @relation(fields: [albumId], references: [id], onDelete: Cascade)
posts Post[]
@@index([slug])
@@index([status])

View file

@ -25,17 +25,6 @@
{/if}
</header>
{#if post.linkUrl}
<div class="post-link-preview">
<LinkCard
link={{
url: post.linkUrl,
title: post.title,
description: post.linkDescription
}}
/>
</div>
{/if}
{#if post.album && post.album.photos && post.album.photos.length > 0}
<!-- Album slideshow -->

View file

@ -23,17 +23,6 @@
</h2>
{/if}
{#if post.linkUrl}
<!-- Link post type -->
<div class="link-preview">
<a href={post.linkUrl} target="_blank" rel="noopener noreferrer" class="link-url">
{post.linkUrl}
</a>
{#if post.linkDescription}
<p class="link-description">{post.linkDescription}</p>
{/if}
</div>
{/if}
{#if post.content}
<div class="post-excerpt">

View file

@ -11,8 +11,6 @@
excerpt: string | null
status: string
tags: string[] | null
linkUrl: string | null
linkDescription: string | null
featuredImage: string | null
publishedAt: string | null
createdAt: string
@ -28,12 +26,9 @@
const postTypeLabels: Record<string, string> = {
post: 'Post',
essay: 'Essay',
// Legacy types for backward compatibility
// Map database types to display names
blog: 'Essay',
microblog: 'Post',
link: 'Post',
photo: 'Post',
album: 'Album'
microblog: 'Post'
}
function handlePostClick() {
@ -108,9 +103,6 @@
{/if}
<div class="post-content">
{#if post.linkUrl}
<p class="post-link-url">{post.linkUrl}</p>
{/if}
<p class="post-preview">{getPostSnippet(post)}</p>
</div>

View file

@ -28,10 +28,6 @@
type: 'doc',
content: [{ type: 'paragraph' }]
}
let linkUrl = ''
let linkTitle = ''
let linkDescription = ''
let showLinkFields = false
let characterCount = 0
let editorInstance: Editor
@ -64,7 +60,7 @@
}
function hasContent(): boolean {
return characterCount > 0 || linkUrl.length > 0 || attachedPhotos.length > 0
return characterCount > 0 || attachedPhotos.length > 0
}
function resetComposer() {
@ -73,10 +69,6 @@
type: 'doc',
content: [{ type: 'paragraph' }]
}
linkUrl = ''
linkTitle = ''
linkDescription = ''
showLinkFields = false
characterCount = 0
attachedPhotos = []
if (editorInstance) {
@ -100,9 +92,6 @@
essaySlug = generateSlug(essayTitle)
}
function toggleLinkFields() {
showLinkFields = !showLinkFields
}
function handlePhotoUpload() {
fileInput.click()
@ -219,18 +208,11 @@
tags: essayTags ? essayTags.split(',').map((tag) => tag.trim()) : []
}
} else {
// All other content is just a "post" with optional link data and attachments
// All other content is just a "post" with attachments
postData = {
...postData,
type: 'microblog' // 'microblog' is for shorter posts
}
// Add link fields if present
if (showLinkFields) {
postData.link_url = linkUrl
postData.linkTitle = linkTitle
postData.linkDescription = linkDescription
}
}
try {
@ -266,7 +248,6 @@
$: isOverLimit = characterCount > CHARACTER_LIMIT
$: canSave =
(postType === 'post' && (characterCount > 0 || attachedPhotos.length > 0) && !isOverLimit) ||
(showLinkFields && linkUrl.length > 0) ||
(postType === 'essay' && essayTitle.length > 0 && content)
</script>
@ -320,23 +301,6 @@
class="composer-editor"
/>
{#if showLinkFields}
<div class="link-fields">
<Input
type="url"
bind:value={linkUrl}
placeholder="https://example.com"
autocomplete="off"
/>
<Input bind:value={linkTitle} placeholder="Link title (optional)" autocomplete="off" />
<Input
type="textarea"
bind:value={linkDescription}
placeholder="Add context..."
rows={2}
/>
</div>
{/if}
{#if attachedPhotos.length > 0}
<div class="attached-photos">
@ -371,36 +335,6 @@
<div class="composer-footer">
<div class="footer-left">
<Button
variant="ghost"
iconOnly
buttonSize="icon"
onclick={toggleLinkFields}
active={showLinkFields}
title="Add link"
class="tool-button"
>
<svg slot="icon" width="18" height="18" viewBox="0 0 18 18" fill="none">
<path
d="M8 10a3 3 0 0 1 0-5l2.5-2.5a3 3 0 0 1 4.243 4.243l-1.25 1.25"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
/>
<path
d="M10 8a3 3 0 0 1 0 5l-2.5 2.5a3 3 0 0 1-4.243-4.243l1.25-1.25"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
/>
<path
d="M11 7l-4 4"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
/>
</svg>
</Button>
<Button
variant="ghost"
@ -452,7 +386,7 @@
</div>
<div class="footer-right">
{#if postType === 'post' && !showLinkFields}
{#if postType === 'post'}
<span
class="character-count"
class:warning={characterCount > CHARACTER_LIMIT * 0.9}
@ -565,23 +499,6 @@
class="inline-composer-editor"
/>
{#if showLinkFields}
<div class="link-fields">
<Input
type="url"
bind:value={linkUrl}
placeholder="https://example.com"
autocomplete="off"
/>
<Input bind:value={linkTitle} placeholder="Link title (optional)" autocomplete="off" />
<Input
type="textarea"
bind:value={linkDescription}
placeholder="Add context..."
rows={2}
/>
</div>
{/if}
{#if attachedPhotos.length > 0}
<div class="attached-photos">
@ -616,36 +533,6 @@
<div class="composer-footer">
<div class="footer-left">
<Button
variant="ghost"
iconOnly
buttonSize="icon"
onclick={toggleLinkFields}
active={showLinkFields}
title="Add link"
class="tool-button"
>
<svg slot="icon" width="18" height="18" viewBox="0 0 18 18" fill="none">
<path
d="M8 10a3 3 0 0 1 0-5l2.5-2.5a3 3 0 0 1 4.243 4.243l-1.25 1.25"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
/>
<path
d="M10 8a3 3 0 0 1 0 5l-2.5 2.5a3 3 0 0 1-4.243-4.243l1.25-1.25"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
/>
<path
d="M11 7l-4 4"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
/>
</svg>
</Button>
<Button
variant="ghost"
@ -697,15 +584,13 @@
</div>
<div class="footer-right">
{#if !showLinkFields}
<span
class="character-count"
class:warning={characterCount > CHARACTER_LIMIT * 0.9}
class:error={isOverLimit}
>
{CHARACTER_LIMIT - characterCount}
</span>
{/if}
<span
class="character-count"
class:warning={characterCount > CHARACTER_LIMIT * 0.9}
class:error={isOverLimit}
>
{CHARACTER_LIMIT - characterCount}
</span>
<Button variant="primary" onclick={handleSave} disabled={!canSave}>Post</Button>
</div>
</div>

View file

@ -18,8 +18,6 @@
excerpt: string | null
status: string
tags: string[] | null
linkUrl: string | null
linkDescription: string | null
featuredImage: string | null
publishedAt: string | null
createdAt: string
@ -130,7 +128,7 @@
filteredPosts = posts
} else if (selectedFilter === 'post') {
filteredPosts = posts.filter((post) =>
['post', 'microblog', 'link', 'photo'].includes(post.postType)
['post', 'microblog'].includes(post.postType)
)
} else if (selectedFilter === 'essay') {
filteredPosts = posts.filter((post) => ['essay', 'blog'].includes(post.postType))

View file

@ -97,27 +97,8 @@ export const POST: RequestHandler = async (event) => {
featuredImageId = data.attachedPhotos[0]
}
// Handle album gallery - use first image as featured image
if (data.gallery && data.gallery.length > 0 && !featuredImageId) {
// Get the media URL for the first gallery item
const firstMedia = await prisma.media.findUnique({
where: { id: data.gallery[0] },
select: { url: true }
})
if (firstMedia) {
featuredImageId = firstMedia.url
}
}
// For albums, store gallery IDs in content field as a special structure
// Use content as-is (no special handling needed)
let postContent = data.content
if (data.type === 'album' && data.gallery) {
postContent = {
type: 'album',
gallery: data.gallery,
description: data.content
}
}
const post = await prisma.post.create({
data: {
@ -126,8 +107,6 @@ export const POST: RequestHandler = async (event) => {
postType: data.type,
status: data.status,
content: postContent,
linkUrl: data.link_url,
linkDescription: data.linkDescription,
featuredImage: featuredImageId,
attachments:
data.attachedPhotos && data.attachedPhotos.length > 0 ? data.attachedPhotos : null,

View file

@ -64,28 +64,9 @@ export const PUT: RequestHandler = async (event) => {
}
}
// Handle album gallery updates
// Use content as-is (no special handling needed)
let featuredImageId = data.featuredImage
if (data.gallery && data.gallery.length > 0 && !featuredImageId) {
// Get the media URL for the first gallery item
const firstMedia = await prisma.media.findUnique({
where: { id: data.gallery[0] },
select: { url: true }
})
if (firstMedia) {
featuredImageId = firstMedia.url
}
}
// For albums, store gallery IDs in content field as a special structure
let postContent = data.content
if (data.type === 'album' && data.gallery) {
postContent = {
type: 'album',
gallery: data.gallery,
description: data.content
}
}
const post = await prisma.post.update({
where: { id },
@ -95,8 +76,6 @@ export const PUT: RequestHandler = async (event) => {
postType: data.type,
status: data.status,
content: postContent,
linkUrl: data.link_url,
linkDescription: data.linkDescription,
featuredImage: featuredImageId,
attachments:
data.attachedPhotos && data.attachedPhotos.length > 0 ? data.attachedPhotos : null,

View file

@ -14,9 +14,8 @@ export interface UniverseItem {
// Post-specific fields
postType?: string
linkUrl?: string
linkDescription?: string
attachments?: any
featuredImage?: string
// Album-specific fields
description?: string
@ -46,9 +45,8 @@ export const GET: RequestHandler = async (event) => {
postType: true,
title: true,
content: true,
linkUrl: true,
linkDescription: true,
attachments: true,
featuredImage: true,
publishedAt: true,
createdAt: true
},
@ -96,9 +94,8 @@ export const GET: RequestHandler = async (event) => {
title: post.title || undefined,
content: post.content,
postType: post.postType,
linkUrl: post.linkUrl || undefined,
linkDescription: post.linkDescription || undefined,
attachments: post.attachments,
featuredImage: post.featuredImage || undefined,
publishedAt: post.publishedAt!.toISOString(),
createdAt: post.createdAt.toISOString()
}))

View file

@ -134,7 +134,7 @@ export const GET: RequestHandler = async (event) => {
pubDate: post.publishedAt || post.createdAt,
updatedDate: post.updatedAt,
postType: post.postType,
linkUrl: post.linkUrl || null
featuredImage: post.featuredImage || null
})),
...universeAlbums.map((album) => ({
type: 'album',
@ -206,7 +206,6 @@ ${item.content ? `<content:encoded><![CDATA[${item.content}]]></content:encoded>
${item.updatedDate ? `<atom:updated>${new Date(item.updatedDate).toISOString()}</atom:updated>` : ''}
<category>${item.section}</category>
<category>${item.type === 'post' ? item.postType : 'album'}</category>
${item.type === 'post' && item.linkUrl ? `<comments>${item.linkUrl}</comments>` : ''}
${
item.type === 'album' && item.coverPhoto
? `

View file

@ -95,7 +95,7 @@ export const GET: RequestHandler = async (event) => {
pubDate: post.publishedAt || post.createdAt,
updatedDate: post.updatedAt,
postType: post.postType,
linkUrl: post.linkUrl || null
featuredImage: post.featuredImage || null
})),
...albums.map((album) => ({
type: 'album',
@ -143,7 +143,6 @@ ${item.content ? `<content:encoded><![CDATA[${item.content}]]></content:encoded>
<pubDate>${formatRFC822Date(new Date(item.pubDate))}</pubDate>
${item.updatedDate ? `<atom:updated>${new Date(item.updatedDate).toISOString()}</atom:updated>` : ''}
<category>${item.type === 'post' ? item.postType : 'album'}</category>
${item.type === 'post' && item.linkUrl ? `<comments>${item.linkUrl}</comments>` : ''}
<author>noreply@jedmund.com (Justin Edmund)</author>
</item>`
)