This commit is contained in:
2026-02-06 03:16:06 +08:00
parent 9d42a45bb1
commit 5e24fa76a3
4 changed files with 51 additions and 56 deletions

View File

@@ -1,8 +0,0 @@
/*
Warnings:
- You are about to drop the column `name` on the `user` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "user" DROP COLUMN "name";

View File

@@ -1,4 +1,3 @@
generator client { generator client {
provider = "prisma-client" provider = "prisma-client"
output = "../generated/prisma" output = "../generated/prisma"
@@ -10,29 +9,27 @@ datasource db {
model User { model User {
id String @id id String @id
email String name String
email String @unique
emailVerified Boolean @default(false) emailVerified Boolean @default(false)
image String? image String?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
sessions Session[] displayUsername String?
username String? @unique
accounts Account[] accounts Account[]
folders Folder[]
dictionaryLookUps DictionaryLookUp[] dictionaryLookUps DictionaryLookUp[]
folders Folder[]
sessions Session[]
translationHistories TranslationHistory[] translationHistories TranslationHistory[]
username String?
displayUsername String?
@@unique([email])
@@map("user") @@map("user")
@@unique([username])
} }
model Session { model Session {
id String @id id String @id
expiresAt DateTime expiresAt DateTime
token String token String @unique
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
ipAddress String? ipAddress String?
@@ -40,7 +37,6 @@ model Session {
userId String userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([token])
@@index([userId]) @@index([userId])
@@map("session") @@map("session")
} }
@@ -50,7 +46,6 @@ model Account {
accountId String accountId String
providerId String providerId String
userId String userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
accessToken String? accessToken String?
refreshToken String? refreshToken String?
idToken String? idToken String?
@@ -60,6 +55,7 @@ model Account {
password String? password String?
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId]) @@index([userId])
@@map("account") @@map("account")
@@ -79,17 +75,16 @@ model Verification {
model Pair { model Pair {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
text1 String
text2 String
language1 String language1 String
language2 String language2 String
text1 String
text2 String
ipa1 String? ipa1 String?
ipa2 String? ipa2 String?
folderId Int @map("folder_id") folderId Int @map("folder_id")
createdAt DateTime @default(now()) @map("created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at") updatedAt DateTime @updatedAt @map("updated_at")
folder Folder @relation(fields: [folderId], references: [id], onDelete: Cascade)
folder Folder @relation(fields: [folderId], references: [id], onDelete: Cascade)
@@unique([folderId, language1, language2, text1, text2]) @@unique([folderId, language1, language2, text1, text2])
@@index([folderId]) @@index([folderId])
@@ -102,26 +97,24 @@ model Folder {
userId String @map("user_id") userId String @map("user_id")
createdAt DateTime @default(now()) @map("created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at") updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade) pairs Pair[]
pairs Pair[]
@@index([userId]) @@index([userId])
@@map("folders") @@map("folders")
} }
model DictionaryLookUp { model DictionaryLookUp {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
userId String? @map("user_id") userId String? @map("user_id")
text String text String
normalizedText String @default("") @map("normalized_text") queryLang String @map("query_lang")
queryLang String @map("query_lang") definitionLang String @map("definition_lang")
definitionLang String @map("definition_lang") createdAt DateTime @default(now()) @map("created_at")
createdAt DateTime @default(now()) @map("created_at") dictionaryItemId Int? @map("dictionary_item_id")
dictionaryItemId Int? @map("dictionary_item_id") normalizedText String @default("") @map("normalized_text")
dictionaryItem DictionaryItem? @relation(fields: [dictionaryItemId], references: [id])
user User? @relation(fields: [userId], references: [id]) user User? @relation(fields: [userId], references: [id])
dictionaryItem DictionaryItem? @relation(fields: [dictionaryItemId], references: [id], onDelete: SetNull)
@@index([userId]) @@index([userId])
@@index([createdAt]) @@index([createdAt])
@@ -130,16 +123,15 @@ model DictionaryLookUp {
} }
model DictionaryItem { model DictionaryItem {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
frequency Int @default(1) frequency Int @default(1)
standardForm String @map("standard_form") standardForm String @map("standard_form")
queryLang String @map("query_lang") queryLang String @map("query_lang")
definitionLang String @map("definition_lang") definitionLang String @map("definition_lang")
createdAt DateTime @default(now()) @map("created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at") updatedAt DateTime @updatedAt @map("updated_at")
entries DictionaryEntry[]
lookups DictionaryLookUp[] lookups DictionaryLookUp[]
entries DictionaryEntry[]
@@unique([standardForm, queryLang, definitionLang]) @@unique([standardForm, queryLang, definitionLang])
@@index([standardForm]) @@index([standardForm])
@@ -148,16 +140,15 @@ model DictionaryItem {
} }
model DictionaryEntry { model DictionaryEntry {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
itemId Int @map("item_id") itemId Int @map("item_id")
ipa String? ipa String?
definition String definition String
partOfSpeech String? @map("part_of_speech") partOfSpeech String? @map("part_of_speech")
example String example String
createdAt DateTime @default(now()) @map("created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at") updatedAt DateTime @updatedAt @map("updated_at")
item DictionaryItem @relation(fields: [itemId], references: [id], onDelete: Cascade)
item DictionaryItem @relation(fields: [itemId], references: [id], onDelete: Cascade)
@@index([itemId]) @@index([itemId])
@@index([createdAt]) @@index([createdAt])
@@ -175,8 +166,7 @@ model TranslationHistory {
targetIpa String? @map("target_ipa") targetIpa String? @map("target_ipa")
createdAt DateTime @default(now()) @map("created_at") createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at") updatedAt DateTime @updatedAt @map("updated_at")
user User? @relation(fields: [userId], references: [id])
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
@@index([userId]) @@index([userId])
@@index([createdAt]) @@index([createdAt])

View File

@@ -3,6 +3,9 @@ import { Container } from "@/components/ui/Container";
import { actionGetUserProfileByUsername } from "@/modules/auth/auth-action"; import { actionGetUserProfileByUsername } from "@/modules/auth/auth-action";
import { notFound } from "next/navigation"; import { notFound } from "next/navigation";
import { getTranslations } from "next-intl/server"; import { getTranslations } from "next-intl/server";
import { auth } from "@/auth";
import { headers } from "next/headers";
import { LogoutButton } from "@/app/users/[username]/LogoutButton";
interface UserPageProps { interface UserPageProps {
params: Promise<{ username: string; }>; params: Promise<{ username: string; }>;
@@ -12,6 +15,9 @@ export default async function UserPage({ params }: UserPageProps) {
const { username } = await params; const { username } = await params;
const t = await getTranslations("user_profile"); const t = await getTranslations("user_profile");
// Get current session
const session = await auth.api.getSession({ headers: await headers() });
// Get user profile // Get user profile
const result = await actionGetUserProfileByUsername({ username }); const result = await actionGetUserProfileByUsername({ username });
@@ -21,11 +27,18 @@ export default async function UserPage({ params }: UserPageProps) {
const user = result.data; const user = result.data;
// Check if viewing own profile
const isOwnProfile = session?.user?.username === username || session?.user?.email === username;
return ( return (
<div className="min-h-[calc(100vh-64px)] bg-gray-50 py-8"> <div className="min-h-[calc(100vh-64px)] bg-gray-50 py-8">
<Container className="max-w-3xl mx-auto"> <Container className="max-w-3xl mx-auto">
{/* Header */} {/* Header */}
<div className="bg-white rounded-lg shadow-md p-6 mb-6"> <div className="bg-white rounded-lg shadow-md p-6 mb-6">
<div className="flex items-center justify-between mb-4">
<div></div>
{isOwnProfile && <LogoutButton />}
</div>
<div className="flex items-center space-x-6"> <div className="flex items-center space-x-6">
{/* Avatar */} {/* Avatar */}
{user.image ? ( {user.image ? (