From 2fc3aeccad1c4534cdcd541180fdfa0be7cc830e Mon Sep 17 00:00:00 2001 From: Edward Kim <65283190+bepyan@users.noreply.github.com> Date: Thu, 22 Aug 2024 03:10:33 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=B4=88=EB=8C=80=EC=9E=A5=20SEO?= =?UTF-8?q?=20=EC=84=A4=EB=AA=85=20=EC=97=B0=EB=8F=99=20(#90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: apply subdomain to preview * db: add description to invitation * feat: apply seo description * feat: SEO 설명 수정 * feat: seo description 연동 --- src/app/(main)/i/[subdomain]/page.tsx | 1 + src/app/layout.tsx | 2 +- .../editor/sidebar/sidebar-settings-tab.tsx | 22 +- .../db/migrations/0004_tranquil_pandemic.sql | 1 + src/lib/db/migrations/meta/0004_snapshot.json | 398 ++++++++++++++++++ src/lib/db/migrations/meta/_journal.json | 7 + src/lib/db/schema/invitations.query.ts | 1 + src/lib/db/schema/invitations.ts | 1 + 8 files changed, 429 insertions(+), 4 deletions(-) create mode 100644 src/lib/db/migrations/0004_tranquil_pandemic.sql create mode 100644 src/lib/db/migrations/meta/0004_snapshot.json diff --git a/src/app/(main)/i/[subdomain]/page.tsx b/src/app/(main)/i/[subdomain]/page.tsx index 76dbccf..21877cb 100644 --- a/src/app/(main)/i/[subdomain]/page.tsx +++ b/src/app/(main)/i/[subdomain]/page.tsx @@ -29,6 +29,7 @@ export async function generateMetadata( default: invitation.title, template: "%s | 인비", }, + description: invitation.description ?? "", openGraph: { images, }, diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 65e997d..e651394 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -5,7 +5,7 @@ import "./globals.css"; export const metadata: Metadata = { title: "초대장 플랫폼, 인비", - description: "따뜻한 마음을 담아 당신의 환대를 전해보세요.", + description: "따뜻한 마음이 담긴 당신의 환대", openGraph: { images: "http://t1.daumcdn.net/brunch/service/user/d4v5/image/Axc3mTi7LoZC2GpsBWosDpRrNPU.png", diff --git a/src/components/editor/sidebar/sidebar-settings-tab.tsx b/src/components/editor/sidebar/sidebar-settings-tab.tsx index 123fa26..2fdd94c 100644 --- a/src/components/editor/sidebar/sidebar-settings-tab.tsx +++ b/src/components/editor/sidebar/sidebar-settings-tab.tsx @@ -175,6 +175,7 @@ function SEOSection() { mutationFn: async () => { await updateInvitation({ id: editor.config.invitationId, + description: editor.config.invitationDesc, thumbnailUrl: editor.config.invitationThumbnail, }); }, @@ -198,7 +199,7 @@ function SEOSection() { 링크 공유시 보여지는 정보를 설정해보세요.

-
+
{ @@ -217,7 +218,6 @@ function SEOSection() { id="invitationThumbnail" disabled={isPending} componentPrefix={"이미지 링크"} - className="mt-1" defaultValue={editor.config.invitationThumbnail} onDebounceChange={(e) => { dispatch({ @@ -228,6 +228,20 @@ function SEOSection() { }); }} /> + { + dispatch({ + type: "UPDATE_CONFIG", + payload: { + invitationDesc: e.target.value, + }, + }); + }} + />
@@ -247,7 +261,9 @@ function SEOSection() {
{editor.config.invitationDesc}
-
invi.my
+
+ {editor.config.invitationSubdomain}.invi.my +
diff --git a/src/lib/db/migrations/0004_tranquil_pandemic.sql b/src/lib/db/migrations/0004_tranquil_pandemic.sql new file mode 100644 index 0000000..c0455d0 --- /dev/null +++ b/src/lib/db/migrations/0004_tranquil_pandemic.sql @@ -0,0 +1 @@ +ALTER TABLE "invitation" ADD COLUMN "description" text; \ No newline at end of file diff --git a/src/lib/db/migrations/meta/0004_snapshot.json b/src/lib/db/migrations/meta/0004_snapshot.json new file mode 100644 index 0000000..1b8c048 --- /dev/null +++ b/src/lib/db/migrations/meta/0004_snapshot.json @@ -0,0 +1,398 @@ +{ + "id": "c18e5de9-ef82-4177-99e4-6d343f03a50d", + "prevId": "01030964-7b2b-4af2-81ae-c9b54fe627f4", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.invitation_response": { + "name": "invitation_response", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "invitation_id": { + "name": "invitation_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "participant_name": { + "name": "participant_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attendance": { + "name": "attendance", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "invitation_response_invitation_id_invitation_id_fk": { + "name": "invitation_response_invitation_id_invitation_id_fk", + "tableFrom": "invitation_response", + "tableTo": "invitation", + "columnsFrom": ["invitation_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.invitation": { + "name": "invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "custom_fields": { + "name": "custom_fields", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_url": { + "name": "event_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "thumbnail_url": { + "name": "thumbnail_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "invitation_user_id_user_id_fk": { + "name": "invitation_user_id_user_id_fk", + "tableFrom": "invitation", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "invitation_event_url_unique": { + "name": "invitation_event_url_unique", + "nullsNotDistinct": false, + "columns": ["event_url"] + } + } + }, + "public.template": { + "name": "template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "custum_fields": { + "name": "custum_fields", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "thumbnail_url": { + "name": "thumbnail_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.test_job": { + "name": "test_job", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "test_id": { + "name": "test_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "test_job_test_id_test_id_fk": { + "name": "test_job_test_id_test_id_fk", + "tableFrom": "test_job", + "tableTo": "test", + "columnsFrom": ["test_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.test": { + "name": "test", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number": { + "name": "number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "test_email_unique": { + "name": "test_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + } + } + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profile_image": { + "name": "profile_image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": ["email"] + } + } + } + }, + "enums": { + "public.provider": { + "name": "provider", + "schema": "public", + "values": ["google", "kakao", "naver"] + } + }, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/src/lib/db/migrations/meta/_journal.json b/src/lib/db/migrations/meta/_journal.json index e4ca7f0..61c2441 100644 --- a/src/lib/db/migrations/meta/_journal.json +++ b/src/lib/db/migrations/meta/_journal.json @@ -29,6 +29,13 @@ "when": 1724177710189, "tag": "0003_flippant_the_professor", "breakpoints": true + }, + { + "idx": 4, + "version": "7", + "when": 1724262141976, + "tag": "0004_tranquil_pandemic", + "breakpoints": true } ] } diff --git a/src/lib/db/schema/invitations.query.ts b/src/lib/db/schema/invitations.query.ts index 87b57d1..906b4a0 100644 --- a/src/lib/db/schema/invitations.query.ts +++ b/src/lib/db/schema/invitations.query.ts @@ -19,6 +19,7 @@ type CreateInvitationParams = Omit< type UpdateInvitationParams = { id: Invitation["id"]; title?: Invitation["title"]; + description?: Invitation["description"]; customFields?: Invitation["customFields"]; eventUrl?: Invitation["eventUrl"]; thumbnailUrl?: Invitation["thumbnailUrl"]; diff --git a/src/lib/db/schema/invitations.ts b/src/lib/db/schema/invitations.ts index 8f9aaf8..2150d4f 100644 --- a/src/lib/db/schema/invitations.ts +++ b/src/lib/db/schema/invitations.ts @@ -9,6 +9,7 @@ export const invitations = pgTable("invitation", { .notNull(), customFields: json("custom_fields").notNull().$type(), title: text("title").notNull(), + description: text("description"), eventUrl: text("event_url").unique().notNull(), thumbnailUrl: text("thumbnail_url"), createdAt: timestamp("created_at", {