diff --git a/apps/web/src/lib/api/auth.ts b/apps/web/src/lib/api/auth.ts index ef05a696..7f8f014a 100644 --- a/apps/web/src/lib/api/auth.ts +++ b/apps/web/src/lib/api/auth.ts @@ -13,8 +13,35 @@ export interface SessionPayload { tenant?: unknown } +export interface SocialProvider { + id: string + name: string + icon: string + callbackPath: string +} + +export interface SocialProvidersResponse { + providers: SocialProvider[] +} + export const authApi = { async getSession(): Promise { return await apiFetch('/api/auth/session') }, + async getSocialProviders(): Promise { + return await apiFetch('/api/auth/social/providers') + }, + async signInSocial(provider: string): Promise<{ url: string }> { + return await apiFetch<{ url: string }>('/api/auth/social', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + provider, + disableRedirect: true, + callbackURL: window.location.href, + }), + }) + }, } diff --git a/apps/web/src/lib/api/comments.ts b/apps/web/src/lib/api/comments.ts index 7c96f7e1..d054feae 100644 --- a/apps/web/src/lib/api/comments.ts +++ b/apps/web/src/lib/api/comments.ts @@ -28,11 +28,25 @@ export interface Comment { viewerReactions: string[] } +export interface CommentUser { + id: string + name: string + image: string | null +} + export interface CommentListResult { - items: Comment[] + comments: Comment[] + relations: Record + users: Record nextCursor: string | null } +export interface CreateCommentResult { + comments: Comment[] + relations: Record + users: Record +} + export interface CreateCommentInput { photoId: string content: string @@ -44,6 +58,25 @@ export interface ToggleReactionInput { reaction: string } +interface CommentUserDto { + id: string + name: string + image: string | null +} + +interface CommentListResponseDto { + comments: CommentDto[] + relations: Record + users: Record + next_cursor: string | null +} + +interface CreateCommentResponseDto { + comments: CommentDto[] + relations: Record + users: Record +} + function mapComment(dto: CommentDto): Comment { return { id: dto.id, @@ -59,6 +92,14 @@ function mapComment(dto: CommentDto): Comment { } } +function mapRelations(relations: Record): Record { + const result: Record = {} + for (const [key, dto] of Object.entries(relations)) { + result[key] = mapComment(dto) + } + return result +} + export const commentsApi = { async list(photoId: string, cursor?: string | null, limit = 20): Promise { const params = new URLSearchParams({ @@ -67,17 +108,17 @@ export const commentsApi = { }) if (cursor) params.set('cursor', cursor) - const data = await apiFetch<{ items: CommentDto[]; next_cursor: string | null }>( - `/api/comments?${params.toString()}`, - ) + const data = await apiFetch(`/api/comments?${params.toString()}`) return { - items: data.items.map(mapComment), + comments: data.comments.map(mapComment), + relations: mapRelations(data.relations), + users: data.users, nextCursor: data.next_cursor ?? null, } }, - async create(input: CreateCommentInput): Promise { - const data = await apiFetch<{ item: CommentDto }>('/api/comments', { + async create(input: CreateCommentInput): Promise { + const data = await apiFetch('/api/comments', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ @@ -86,7 +127,11 @@ export const commentsApi = { parentId: input.parentId ?? undefined, }), }) - return mapComment(data.item) + return { + comments: data.comments.map(mapComment), + relations: mapRelations(data.relations), + users: data.users, + } }, async toggleReaction(input: ToggleReactionInput): Promise { diff --git a/apps/web/src/modules/social/comments/CommentActionBar.tsx b/apps/web/src/modules/social/comments/CommentActionBar.tsx index 156baa0e..2615f790 100644 --- a/apps/web/src/modules/social/comments/CommentActionBar.tsx +++ b/apps/web/src/modules/social/comments/CommentActionBar.tsx @@ -1,22 +1,31 @@ import clsx from 'clsx' +import { useSetAtom } from 'jotai' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' +import type { Comment } from '~/lib/api/comments' + +import { useCommentsContext } from './context' + interface CommentActionBarProps { reacted: boolean reactionCount: number - onReply: () => void - onToggleReaction: () => void + comment: Comment } -export const CommentActionBar = ({ reacted, reactionCount, onReply, onToggleReaction }: CommentActionBarProps) => { +export const CommentActionBar = ({ reacted, reactionCount, comment }: CommentActionBarProps) => { const { t } = useTranslation() + + const { atoms, methods } = useCommentsContext() + const handleReaction = useCallback(() => { - onToggleReaction() - }, [onToggleReaction]) + methods.toggleReaction({ comment }) + }, [methods, comment]) + + const setReplyTo = useSetAtom(atoms.replyToAtom) return ( -
+
+
+ )} + + {replyTo && !submitError ? ( +
- + - {t('comments.replyingTo', { - user: replyTo.userId.slice(-6), - })} + }} + values={{ user: replyUserName }} + />
) : null}
-
- {(sessionUser?.name || sessionUser?.id || 'G')[0]} -
+