diff --git a/prisma/migrations/20250511141123_announcement/migration.sql b/prisma/migrations/20250511141123_announcement/migration.sql
new file mode 100644
index 0000000..85d5632
--- /dev/null
+++ b/prisma/migrations/20250511141123_announcement/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "profile" ADD COLUMN "announcement" TEXT NOT NULL DEFAULT '';
diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml
index fbffa92..648c57f 100644
--- a/prisma/migrations/migration_lock.toml
+++ b/prisma/migrations/migration_lock.toml
@@ -1,3 +1,3 @@
# Please do not edit this file manually
-# It should be added in your version-control system (i.e. Git)
+# It should be added in your version-control system (e.g., Git)
provider = "postgresql"
\ No newline at end of file
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index c5a4203..0e18a28 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -59,6 +59,7 @@ model profile {
defaultPostVisibility PostVisibility @default(public)
defaultHideFromTimeline Boolean @default(false)
wordMuteList String[] @default([])
+ announcement String @default("")
}
model answer {
diff --git a/src/app/_dto/fetch-profile/Profile.dto.ts b/src/app/_dto/fetch-profile/Profile.dto.ts
index dcc0552..dd02da8 100644
--- a/src/app/_dto/fetch-profile/Profile.dto.ts
+++ b/src/app/_dto/fetch-profile/Profile.dto.ts
@@ -9,6 +9,7 @@ export interface userProfileDto {
questionBoxName: string;
hostname: string;
instanceType: $Enums.InstanceType;
+ announcement: string;
}
export interface userProfileMeDto extends userProfileDto {
diff --git a/src/app/_dto/settings/settings.dto.ts b/src/app/_dto/settings/settings.dto.ts
index bc8b193..e5a0743 100644
--- a/src/app/_dto/settings/settings.dto.ts
+++ b/src/app/_dto/settings/settings.dto.ts
@@ -34,4 +34,9 @@ export class UserSettingsUpdateDto {
@IsArray()
@IsString({ each: true })
wordMuteList: profile['wordMuteList'];
+
+ @IsString()
+ @IsOptional()
+ @MaxLength(80)
+ announcement: profile['announcement'];
}
diff --git a/src/app/api/_service/following/following-service.ts b/src/app/api/_service/following/following-service.ts
index adcbe2b..324df62 100644
--- a/src/app/api/_service/following/following-service.ts
+++ b/src/app/api/_service/following/following-service.ts
@@ -27,9 +27,7 @@ export class FollowingService {
const user = await prisma.user.findUniqueOrThrow({ where: { handle: tokenBody!.handle } });
const fn = async () => {
- const follows = await prisma.following.findMany({
- where: { followerHandle: user.handle },
- });
+ const follows = await prisma.following.findMany({ where: { followerHandle: user.handle } });
const filteredList = [];
for (const f of follows) {
@@ -70,6 +68,7 @@ export class FollowingService {
questionBoxName: exist.questionBoxName,
hostname: exist.user.hostName,
instanceType: exist.user.server.instanceType,
+ announcement: exist.announcement,
},
});
});
diff --git a/src/app/api/_service/profile/profile-service.ts b/src/app/api/_service/profile/profile-service.ts
index a517cbe..c0ecce3 100644
--- a/src/app/api/_service/profile/profile-service.ts
+++ b/src/app/api/_service/profile/profile-service.ts
@@ -37,16 +37,10 @@ export class ProfileService {
try {
const userProfile = await prisma.profile.findUnique({
include: {
- user: {
- include: { server: { select: { instanceType: true } } },
- },
- _count: {
- select: { answer: true, questions: true },
- },
- },
- where: {
- handle: handle,
+ user: { include: { server: { select: { instanceType: true } } } },
+ _count: { select: { answer: true, questions: true } },
},
+ where: { handle: handle },
});
if (!userProfile) {
return NextResponse.json({ message: `User not found` }, { status: 404 });
@@ -65,21 +59,14 @@ export class ProfileService {
stopNotiNewQuestion: userProfile.stopNotiNewQuestion,
hostname: userProfile.user.hostName,
instanceType: instanceType,
+ announcement: userProfile.announcement,
};
const resMe: userProfileMeDto = {
- handle: userProfile.handle,
- name: userProfile.name,
- stopNewQuestion: userProfile.stopNewQuestion,
- stopAnonQuestion: userProfile.stopAnonQuestion,
- avatarUrl: userProfile.avatarUrl,
- questionBoxName: userProfile.questionBoxName,
- stopNotiNewQuestion: userProfile.stopNotiNewQuestion,
- stopPostAnswer: userProfile.stopPostAnswer,
+ ...resNotMe,
questions: questionCount,
- instanceType: instanceType,
+ stopPostAnswer: userProfile.stopPostAnswer,
defaultPostVisibility: userProfile.defaultPostVisibility,
defaultHideFromTimeline: userProfile.defaultHideFromTimeline,
- hostname: userProfile.user.hostName,
wordMuteList: userProfile.wordMuteList,
};
if (isMe) {
diff --git a/src/app/api/_utils/profileToDto.ts b/src/app/api/_utils/profileToDto.ts
index 495f787..921885e 100644
--- a/src/app/api/_utils/profileToDto.ts
+++ b/src/app/api/_utils/profileToDto.ts
@@ -12,6 +12,7 @@ export function profileToDto(profile: profile, hostName: string, instanceType: $
questionBoxName: profile.questionBoxName,
hostname: hostName,
instanceType: instanceType,
+ announcement: profile.announcement,
};
return data;
}
diff --git a/src/app/main/settings/page.tsx b/src/app/main/settings/page.tsx
index 3569e8e..9cb65fa 100644
--- a/src/app/main/settings/page.tsx
+++ b/src/app/main/settings/page.tsx
@@ -11,7 +11,7 @@ import CollapseMenu from '@/app/_components/collapseMenu';
import DialogModalTwoButton from '@/app/_components/modalTwoButton';
import { AccountCleanReqDto } from '@/app/_dto/account-clean/account-clean.dto';
import { FaLock, FaUserLargeSlash } from 'react-icons/fa6';
-import { MdDeleteForever, MdDeleteSweep, MdInfoOutline, MdOutlineCleaningServices } from 'react-icons/md';
+import { MdDeleteForever, MdDeleteSweep, MdOutlineCleaningServices } from 'react-icons/md';
import { MyProfileContext } from '@/app/main/layout';
import { MyProfileEv } from '@/app/main/_events';
import { getProxyUrl } from '@/utils/getProxyUrl/getProxyUrl';
@@ -27,6 +27,7 @@ export type FormValue = {
questionBoxName: string;
visibility: $Enums.PostVisibility;
wordMuteList: string;
+ announcement: string;
};
async function updateUserSettings(value: FormValue) {
const body: UserSettingsUpdateDto = {
@@ -42,6 +43,7 @@ async function updateUserSettings(value: FormValue) {
.map((v) => v.trim())
.filter((v) => v.length > 0)
.map((word) => word.replace(/^\/|\/[igmsuy]{0,6}$/g, '')),
+ announcement: value.announcement,
};
try {
const res = await fetch('/api/user/settings', {
@@ -93,6 +95,7 @@ export default function Settings() {
questionBoxName: userInfo.questionBoxName,
visibility: userInfo.defaultPostVisibility,
wordMuteList: userInfo.wordMuteList.join('\n'),
+ announcement: userInfo.announcement,
};
setDefaultFormValue(value);
}
@@ -289,14 +292,23 @@ export default function Settings() {
{...register('questionBoxName', { maxLength: 10 })}
type="text"
placeholder="질문함"
- className={`input input-bordered input-sm w-48 ${
- errors.questionBoxName?.type === 'maxLength' && 'input-error'
- }`}
+ className={`input input-bordered input-sm w-48 ${errors.questionBoxName?.type === 'maxLength' && 'input-error'
+ }`}
/>
질문함 이름 (10글자 이내)