diff --git a/agency/Makefile_ECR b/agency/Makefile_ECR index 37caf190..de9149c9 100644 --- a/agency/Makefile_ECR +++ b/agency/Makefile_ECR @@ -1,6 +1,6 @@ Image = curieo-agency ECR = 698471419283.dkr.ecr.eu-central-1.amazonaws.com/curieo-agency -TAG = 2.0 +TAG = 3.0 ecr_deploy: login docker buildx build --platform linux/amd64 -t $(Image) . @@ -8,4 +8,4 @@ ecr_deploy: login docker push $(ECR):$(TAG) login: - aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin 698471419283.dkr.ecr.eu-central-1.amazonaws.com \ No newline at end of file + aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin 698471419283.dkr.ecr.eu-central-1.amazonaws.com diff --git a/agency/app/pubmed_retrieval/cluster_engine.py b/agency/app/pubmed_retrieval/cluster_engine.py index cbc34d9d..2d35dd01 100644 --- a/agency/app/pubmed_retrieval/cluster_engine.py +++ b/agency/app/pubmed_retrieval/cluster_engine.py @@ -116,5 +116,7 @@ async def retrieve_cluster_nodes( for pubmed_id, pubmed_value in nodes_dict.items() for child_node_id in pubmed_value.get("children_node_ids", []) if child_node_id in children_node_texts - for child_node_json in [json.loads(children_node_texts[child_node_id])] + for child_node_json in [ + json.loads(json.dumps(children_node_texts[child_node_id])) + ] ] diff --git a/agency/helm/values.yaml b/agency/helm/values.yaml index fd5be479..86d7f727 100644 --- a/agency/helm/values.yaml +++ b/agency/helm/values.yaml @@ -3,7 +3,7 @@ # Declare variables to be passed into your templates. service: - image: 698471419283.dkr.ecr.eu-central-1.amazonaws.com/curieo-agency:2.0 + image: 698471419283.dkr.ecr.eu-central-1.amazonaws.com/curieo-agency:3.0 replica_count: 1 port: 50051 diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 5708db66..731dde66 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -18,12 +18,16 @@ ARG POSTHOG_KEY ARG POSTHOG_API_HOST ARG POSTHOG_UI_HOST ARG API_URL +ARG AUTH_URL +ARG AUTH_SECRET ENV NEXT_TELEMETRY_DISABLED 1 ENV NEXT_PUBLIC_POSTHOG_KEY $POSTHOG_KEY ENV NEXT_PUBLIC_POSTHOG_API_HOST $POSTHOG_API_HOST ENV NEXT_PUBLIC_POSTHOG_UI_HOST $POSTHOG_UI_HOST ENV NEXT_PUBLIC_API_URL $API_URL +ENV AUTH_URL $AUTH_URL +ENV AUTH_SECRET $AUTH_SECRET RUN npm run build diff --git a/frontend/Makefile b/frontend/Makefile index b83fed51..8e250b3a 100644 --- a/frontend/Makefile +++ b/frontend/Makefile @@ -6,9 +6,11 @@ POSTHOG_KEY = POSTHOG_API_HOST = /ingest POSTHOG_UI_HOST = https://app.posthog.com API_URL = +AUTH_URL = +AUTH_SECRET = ecr_deploy: login - docker buildx build --platform linux/amd64 --build-arg POSTHOG_KEY=$(POSTHOG_KEY) --build-arg POSTHOG_API_HOST=$(POSTHOG_API_HOST) --build-arg POSTHOG_UI_HOST=$(POSTHOG_UI_HOST) --build-arg API_URL=$(API_URL) -t $(Image) . + docker buildx build --platform linux/amd64 --build-arg POSTHOG_KEY=$(POSTHOG_KEY) --build-arg POSTHOG_API_HOST=$(POSTHOG_API_HOST) --build-arg POSTHOG_UI_HOST=$(POSTHOG_UI_HOST) --build-arg API_URL=$(API_URL) --build-arg AUTH_URL=${AUTH_URL} --build-arg AUTH_SECRET=${AUTH_SECRET} -t $(Image) . docker tag $(Image) $(ECR):$(TAG) docker push $(ECR):$(TAG) diff --git a/frontend/helm/templates/deployment.yaml b/frontend/helm/templates/deployment.yaml index b4fb6782..6edddb93 100644 --- a/frontend/helm/templates/deployment.yaml +++ b/frontend/helm/templates/deployment.yaml @@ -13,10 +13,10 @@ spec: template: metadata: labels: - app: {{ .Release.Name }} + app: search-{{ .Release.Name }} spec: containers: - - image: {{ .Values.service.replica_count }} + - image: {{ .Values.service.image }} imagePullPolicy: Always env: - name: NEXT_PUBLIC_POSTHOG_UI_HOST @@ -24,9 +24,13 @@ spec: - name: NEXT_PUBLIC_POSTHOG_KEY value: phc_Qau6pGkA8BXUr7JuDxgALufZqhxMKAk9UVGY4UFQyXu - name: NEXT_PUBLIC_POSTHOG_API_HOST - value: https://search-fronrend.search.svc.cluster.local:3000/ingest + value: https://search.curieo.ai/ingest - name: NEXT_PUBLIC_API_URL - value: http://search-server.search.svc.cluster.local:3030 + value: http://search-server.search.svc.cluster.local:3030 + - name: AUTH_URL + value: https://search.curieo.ai + - name: AUTH_SECRET + value: 05mk7ukF/GSG1dHLYVp04Mxa49slQb2W3N9v1aMcRTM= name: search-{{ .Release.Name }} ports: - containerPort: {{ .Values.service.port }} @@ -38,4 +42,4 @@ spec: memory: {{ .Values.resources.limits.memory }} requests: cpu: {{ .Values.resources.requests.cpu }} - memory: {{ .Values.resources.requests.memory }} \ No newline at end of file + memory: {{ .Values.resources.requests.memory }} diff --git a/frontend/helm/templates/service.yaml b/frontend/helm/templates/service.yaml index 89cf9cb6..8f440459 100644 --- a/frontend/helm/templates/service.yaml +++ b/frontend/helm/templates/service.yaml @@ -10,5 +10,5 @@ spec: protocol: TCP name: http-web selector: - app: {{ .Release.Name }} - sessionAffinity: "ClientIP" \ No newline at end of file + app: search-{{ .Release.Name }} + sessionAffinity: "ClientIP" diff --git a/frontend/helm/templates/virtualservice.yaml b/frontend/helm/templates/virtualservice.yaml index d395e001..71134449 100644 --- a/frontend/helm/templates/virtualservice.yaml +++ b/frontend/helm/templates/virtualservice.yaml @@ -7,7 +7,7 @@ spec: gateways: - {{ .Release.Name }}-gateway hosts: - - {{ .Release.Name }}.{{ .Values.service.dns_zone }} + - search.{{ .Values.service.dns_zone }} http: - match: - port: 443 diff --git a/frontend/helm/values.yaml b/frontend/helm/values.yaml index f43933ef..c215261f 100644 --- a/frontend/helm/values.yaml +++ b/frontend/helm/values.yaml @@ -3,7 +3,7 @@ # Declare variables to be passed into your templates. service: - image: 698471419283.dkr.ecr.eu-central-1.amazonaws.com/curieo-search-frontend:4.0 + image: 698471419283.dkr.ecr.eu-central-1.amazonaws.com/curieo-search-frontend:7.0 replica_count: 1 port: 3000 dns_zone: curieo.ai diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 279b6365..f9cede52 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,6 +11,7 @@ "@auth/core": "^0.32.0", "@tanstack/react-query": "^5.37.1", "date-fns": "^3.6.0", + "dompurify": "^3.1.5", "lodash": "^4.17.21", "next": "^14.2.3", "next-auth": "^5.0.0-beta.19", @@ -25,6 +26,7 @@ "zustand": "^4.5.2" }, "devDependencies": { + "@types/dompurify": "^3.0.5", "@types/lodash": "^4.17.4", "@types/node": "^20", "@types/react": "^18", @@ -580,6 +582,15 @@ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", "license": "MIT" }, + "node_modules/@types/dompurify": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", + "integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==", + "dev": true, + "dependencies": { + "@types/trusted-types": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -629,6 +640,12 @@ "@types/react": "*" } }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true + }, "node_modules/@typescript-eslint/scope-manager": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", @@ -1530,6 +1547,11 @@ "node": ">=0.10.0" } }, + "node_modules/dompurify": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz", + "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index f45ff88a..f93f7ddd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,6 +13,7 @@ "@auth/core": "^0.32.0", "@tanstack/react-query": "^5.37.1", "date-fns": "^3.6.0", + "dompurify": "^3.1.5", "lodash": "^4.17.21", "next": "^14.2.3", "next-auth": "^5.0.0-beta.19", @@ -27,6 +28,7 @@ "zustand": "^4.5.2" }, "devDependencies": { + "@types/dompurify": "^3.0.5", "@types/lodash": "^4.17.4", "@types/node": "^20", "@types/react": "^18", diff --git a/frontend/public/images/answer-logo.svg b/frontend/public/images/answer-logo.svg new file mode 100644 index 00000000..cf98a32e --- /dev/null +++ b/frontend/public/images/answer-logo.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/actions/fetch.ts b/frontend/src/actions/fetch.ts index ec63c982..64b2b43b 100644 --- a/frontend/src/actions/fetch.ts +++ b/frontend/src/actions/fetch.ts @@ -1,3 +1,4 @@ +import { signOut } from '@/auth' import { headers as next_headers } from 'next/headers' function curieoApiUrl(reqInfo?: RequestInfo): URL { @@ -36,6 +37,13 @@ export async function curieoFetch(reqInfo: RequestInfo, init?: RequestInit): Pro } else { init = { headers } } + const url: URL = curieoApiUrl(reqInfo) - return fetch(url, init) + const response = await fetch(url, init) + + if (response.status === 405) { + await signOut() + } + + return response.ok ? Promise.resolve(response) : Promise.reject(response) } diff --git a/frontend/src/actions/search.ts b/frontend/src/actions/search.ts index f7de7c40..69290b1d 100644 --- a/frontend/src/actions/search.ts +++ b/frontend/src/actions/search.ts @@ -1,15 +1,7 @@ 'use server' -import { SearchReactionBody, SearchResult } from '@/types/search' import { curieoFetch } from '@/actions/fetch' - -export async function search(query: string): Promise { - const response = await curieoFetch(`/search?${new URLSearchParams({ query })}`) - if (response.ok) { - return (await response.json()) as SearchResult - } - throw new Error('Search failed') -} +import { SearchHistoryResponse, SearchReactionBody, SearchResult, ThreadByIdResponse } from '@/types/search' export async function searchById(id: string): Promise { const response = await curieoFetch(`/search/one?search_history_id=${id}`) @@ -19,21 +11,35 @@ export async function searchById(id: string): Promise { throw new Error('Retrieving search failed') } -export async function searchHistory({ limit, offset }: { limit: number; offset: number }): Promise { +export async function searchHistory({ + limit, + offset, +}: { + limit: number + offset: number +}): Promise { const response = await curieoFetch(`/search/history?limit=${limit ?? 10}${offset ? `&offset=${offset}` : ``}`) if (response.ok) { - return (await response.json()) as SearchResult[] + return (await response.json()) as SearchHistoryResponse } throw new Error('Retrieving search history failed') } -export async function searchReaction(reaction: SearchReactionBody): Promise { +export async function searchReaction(reaction: SearchReactionBody): Promise { const response = await curieoFetch('/search/reaction', { method: 'PATCH', body: JSON.stringify(reaction), }) if (response.ok) { - return (await response.json()) as SearchResult + return } throw new Error('Could not submit reaction') } + +export async function threadById(id: string): Promise { + const response = await curieoFetch(`/search/threads?thread_id=${id}`) + if (response.ok) { + return (await response.json()) as ThreadByIdResponse + } + throw new Error('Retrieving search failed') +} diff --git a/frontend/src/actions/settings.ts b/frontend/src/actions/settings.ts new file mode 100644 index 00000000..bbfe7e21 --- /dev/null +++ b/frontend/src/actions/settings.ts @@ -0,0 +1,38 @@ +'use server' + +import { UpdatePasswordBody, UpdateProfileBody, UserProfile } from '@/types/settings' +import { encodeAsUrlSearchParams } from '@/utils' +import { curieoFetch } from './fetch' + +export async function fetchUserProfile(): Promise { + const response = await curieoFetch('/users/me') + if (response.ok) { + return (await response.json()) as UserProfile + } + throw new Error('Could not retrieve user profile') +} + +export async function updateUserProfile(payload: UpdateProfileBody): Promise { + const response = await curieoFetch('/users/me', { + method: 'PATCH', + body: JSON.stringify(payload), + }) + if (response.ok) { + return (await response.json()) as UserProfile + } + throw new Error('Could not update user profile') +} + +export async function updatePassword(payload: UpdatePasswordBody): Promise { + const response = await curieoFetch('/users/update-password', { + method: 'PATCH', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: encodeAsUrlSearchParams(payload), + }) + if (response.ok) { + return + } + throw new Error('Could not update password') +} diff --git a/frontend/src/app/api/search/route.ts b/frontend/src/app/api/search/route.ts new file mode 100644 index 00000000..b07b07cc --- /dev/null +++ b/frontend/src/app/api/search/route.ts @@ -0,0 +1,47 @@ +import { curieoFetch } from '@/actions/fetch' +import { NextRequest, NextResponse } from 'next/server' + +export const GET = async (req: NextRequest) => { + const { searchParams } = new URL(req.url) + const searchQuery = searchParams.get('searchQuery') + const threadId = searchParams.get('threadId') + + if (!searchQuery) { + return NextResponse.json({ error: 'searchQuery is required' }, { status: 400 }) + } + + async function pump(reader: ReadableStreamDefaultReader, writer: WritableStreamDefaultWriter) { + while (true) { + const { done, value } = await reader.read() + if (done) break + writer.write(value) + } + writer.close() + } + + try { + const response = await curieoFetch(`/search?query=${searchQuery}${threadId ? `&thread_id=${threadId}` : ``}`) + + if (!response.ok) { + return NextResponse.json({ error: 'Failed to fetch data from external API' }, { status: response.status }) + } + + const reader = response.body?.getReader() + if (!reader) { + return NextResponse.json({ error: 'Failed to read from external API stream' }, { status: 500 }) + } + + const headers = new Headers(response.headers) + headers.delete('Content-Encoding') + headers.set('Content-Encoding', 'identity') + + const { readable, writable } = new TransformStream() + const writer = writable.getWriter() + + pump(reader!, writer).catch(err => err) + + return new NextResponse(readable, { headers }) + } catch (error) { + return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) + } +} diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 176eabb3..13beb61e 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -3,11 +3,11 @@ import Providers from '@/components/wrappers/providers' import { appDescription, appTitle } from '@/constants/app' import '@/styles/globals.css' import type { Metadata } from 'next' -import { Onest } from 'next/font/google' +import { Manrope } from 'next/font/google' import { ReactNode } from 'react' import 'react-toastify/dist/ReactToastify.css' -const onest = Onest({ subsets: ['latin'] }) +const manrope = Manrope({ subsets: ['latin'] }) export const metadata: Metadata = { title: appTitle, @@ -25,7 +25,7 @@ export default async function RootLayout({ children }: LayoutProps) { Curieo Search - + {children} diff --git a/frontend/src/app/search/[searchHistoryId]/page.tsx b/frontend/src/app/search/[searchHistoryId]/page.tsx deleted file mode 100644 index e99abeaf..00000000 --- a/frontend/src/app/search/[searchHistoryId]/page.tsx +++ /dev/null @@ -1,76 +0,0 @@ -'use client' - -import SearchActions from '@/components/search/search-actions' -import SearchInput from '@/components/search/search-input' -import SearchResponse from '@/components/search/search-response' -import SearchTitle from '@/components/search/search-title' -import SourcesMenu from '@/components/search/sources-menu' -import SearchResultPageSkeleton from '@/components/skeletons/search-result-page-skeleton' -import ErrorPage from '@/components/util/error-page' -import { useFetchSearchByIdQuery } from '@/queries/search/fetch-search-by-id-query' -import { useSearchQuery } from '@/queries/search/search-query' -import { useSearchStore } from '@/stores/search/search-store' -import { SearchByIdParams } from '@/types/search' -import { useParams, useRouter } from 'next/navigation' -import { useEffect } from 'react' - -export default function SearchResult() { - const router = useRouter() - const { reset } = useSearchStore() - const { searchHistoryId } = useParams() - - const { - data: searchResult, - isLoading: isPageDataLoading, - isError: isErrorInPageData, - } = useFetchSearchByIdQuery({ - searchHistoryId, - } as SearchByIdParams) - - const { - data: newSearchResult, - isLoading: isNewSearchResultLoading, - isSuccess: isNewSearchSuccess, - refetch: fetchNewSearchResult, - } = useSearchQuery() - - const handleSearch = () => { - fetchNewSearchResult() - } - - useEffect(() => { - if (isNewSearchSuccess) { - reset() - router.push(`/search/${newSearchResult.search_history_id}`) - } - }, [isNewSearchSuccess]) - - if (isNewSearchResultLoading || isPageDataLoading) { - return - } else if (isErrorInPageData || !searchResult) { - return - } else { - return ( -
-
-
- - - -
-
- -
-
- -
- ) - } -} diff --git a/frontend/src/app/search/page.tsx b/frontend/src/app/search/page.tsx index 67f2dffc..28c5b9e8 100644 --- a/frontend/src/app/search/page.tsx +++ b/frontend/src/app/search/page.tsx @@ -1,46 +1,98 @@ 'use client' -import { P } from '@/components/lib/typography' -import SearchInput from '@/components/search/search-input' +import NewSearch from '@/components/search/new-search' +import NewSearchResponse from '@/components/search/new-search-response' +import Thread from '@/components/search/thread' import SearchResultPageSkeleton from '@/components/skeletons/search-result-page-skeleton' +import { useFetchThreadByIdQuery } from '@/queries/search/fetch-thread-by-id-query' import { useSearchQuery } from '@/queries/search/search-query' -import { useSearchStore } from '@/stores/search/search-store' -import { useRouter } from 'next/navigation' -import { useEffect } from 'react' +import { useSearchParams } from 'next/navigation' +import { useEffect, useState } from 'react' import { toast } from 'react-toastify' export default function Search() { - const router = useRouter() - const { reset } = useSearchStore() - const { data, isLoading, isSuccess, isError, refetch: fetchSearchResult } = useSearchQuery() + const searchParams = useSearchParams() + const [searchQuery, setSearchQuery] = useState('') + const [queryTrigger, setQueryTrigger] = useState(false) + const [isLoading, setIsLoading] = useState(false) + const [isStreaming, setIsStreaming] = useState(false) + const { + data: newSearchResult, + isCompleted, + isError, + isTimedOut, + } = useSearchQuery(searchQuery, queryTrigger, setIsStreaming) const handleSearch = () => { - fetchSearchResult().then(r => r) + setIsLoading(true) + setQueryTrigger(true) } + const threadIdFromParams = searchParams.get('thread_id') + const [threadId, setThreadId] = useState('') + const { data: thread, refetch: refetchThread } = useFetchThreadByIdQuery({ threadId: threadId as string }) useEffect(() => { - if (isSuccess) { - reset() - router.push(`/search/${data.search_history_id}`) + setThreadId(threadIdFromParams as string) + }, [threadIdFromParams]) + + useEffect(() => { + if (isCompleted) { + setSearchQuery('') + setQueryTrigger(false) + setIsLoading(false) + setIsStreaming(false) + if (newSearchResult.length === 0) { + toast.error('Failed to fetch search result. Please try again later...') + } else { + setThreadId(newSearchResult[0].search.thread_id) + const params = new URLSearchParams() + params.set('thread_id', newSearchResult[0].search.thread_id) + window.history.pushState(null, '', `?${params.toString()}`) + } + } + }, [isCompleted]) + + useEffect(() => { + if (isTimedOut) { + setIsLoading(false) + setIsStreaming(false) + setSearchQuery('') + setQueryTrigger(false) + toast.error('The server took too long to respond. Please try again later.') } - }, [isSuccess]) + }, [isTimedOut]) useEffect(() => { if (isError) { - toast.error('Failed to fetch search result. Please try again later...') + setIsLoading(false) + setIsStreaming(false) + setSearchQuery('') + setQueryTrigger(false) + toast.error('The server ran into an error while generating stream.') } }, [isError]) + useEffect(() => { + if (Boolean(threadId)) { + refetchThread().then(r => r) + } + }, [threadId]) + return ( <> - {isLoading ? ( - + {!!thread ? ( + + ) : isLoading ? ( + <>{isStreaming ? : } ) : ( -
-
-

How can I help you today?

- -
-
+ { + if (!isLoading) { + handleSearch() + } + }} + searchQuery={searchQuery} + setSearchQuery={setSearchQuery} + /> )} ) diff --git a/frontend/src/app/settings/page.tsx b/frontend/src/app/settings/page.tsx index f3d2273b..91d58d81 100644 --- a/frontend/src/app/settings/page.tsx +++ b/frontend/src/app/settings/page.tsx @@ -1,16 +1,16 @@ -import { H1 } from '@/components/lib/typography' -import AccountDetails from '@/components/settings/account-details' import LogoutSection from '@/components/settings/log-out-section' -import ProfileInfo from '@/components/settings/profile-info' +import SettingsContent from '@/components/settings/settings-content' +import SettingsNavmenu from '@/components/settings/settings-navmenu' export default function Settings() { return (
-
-

Settings

- - - +
+
+ + +
+
) diff --git a/frontend/src/components/auth/auth-form-contents.tsx b/frontend/src/components/auth/auth-form-contents.tsx index 5595a7d9..7b67bbfd 100644 --- a/frontend/src/components/auth/auth-form-contents.tsx +++ b/frontend/src/components/auth/auth-form-contents.tsx @@ -3,17 +3,11 @@ import { emailErrorMessage, passwordErrorMessage } from '@/constants/messages' import { useInputValidation } from '@/hooks/form/use-input-validation' import { useAuthFormStore } from '@/stores/auth/auth-form-store' -import { useEffect } from 'react' import { z } from 'zod' import { Button } from '../lib/button' import { Input, PasswordInput } from '../lib/form' -import { useAppContext } from '@/components/wrappers/app-middleware' - export default function AuthFormContents({ csrfToken }: { csrfToken: string }) { - const { updateAuthStatus } = useAppContext() - - useEffect(() => updateAuthStatus('loading'), []) const { state: { email, password }, setAuthFormState, diff --git a/frontend/src/components/auth/oauth-providers.tsx b/frontend/src/components/auth/oauth-providers.tsx index 79ae5129..3f6b0665 100644 --- a/frontend/src/components/auth/oauth-providers.tsx +++ b/frontend/src/components/auth/oauth-providers.tsx @@ -5,7 +5,7 @@ import GoogleIcon from '@/components/icons/google' export default function OAuthProviders() { const handleContinueWithGoogle = () => { - console.log('CLICKED!') + //console.log('CLICKED!') } return (
) diff --git a/frontend/src/components/navmenu/search-history-button.tsx b/frontend/src/components/navmenu/search-history-button.tsx index 6af62bf3..5df3895f 100644 --- a/frontend/src/components/navmenu/search-history-button.tsx +++ b/frontend/src/components/navmenu/search-history-button.tsx @@ -1,5 +1,5 @@ import { useNavmenuStore } from '@/stores/navmenu/nav-menu-store' -import { SearchResult } from '@/types/search' +import { Thread } from '@/types/search' import classNames from 'classnames' import { usePathname, useRouter } from 'next/navigation' import { HTMLAttributes } from 'react' @@ -7,7 +7,7 @@ import { twMerge } from 'tailwind-merge' import { Button } from '../lib/button' type SearchHistoryButtonProps = HTMLAttributes & { - searchResult: SearchResult + thread: Thread } export default function SearchHistoryButton(props: SearchHistoryButtonProps) { @@ -18,15 +18,15 @@ export default function SearchHistoryButton(props: SearchHistoryButtonProps) { state: { isNavmenuCollapsed }, } = useNavmenuStore() - const searchResultPagePath = `/search/${props.searchResult.search_history_id}` + const threadPagePath = `/search?thread_id=${props.thread.thread_id}` - const handleNavigateToSearchResultPage = () => { - router.push(searchResultPagePath) + const handleNavigateToThreadPage = () => { + router.push(threadPagePath) } - const isActive = pathname === searchResultPagePath + const isActive = pathname === threadPagePath - const { className, searchResult, ...rest } = props + const { className, thread, ...rest } = props return (