Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from 'lucide-react'
import { Navbar } from './components/Navbar'
import EmptyState from './components/EmptyState'
import { BACKEND_URL } from './config'
import { CuratedTips } from './components/CuratedTips'
import { StepProgress } from './components/StepProgress'
import { OnboardingTour } from './components/OnboardingTour'
Expand Down Expand Up @@ -124,10 +125,9 @@ function ResumePreview({ text, skills }: { text: string; skills: string[] }) {
interface SuggestionCardProps {
text: string
index: number
backendUrl?: string
}

const SuggestionCard: React.FC<SuggestionCardProps> = ({ text, index, backendUrl = '' }) => {
const SuggestionCard: React.FC<SuggestionCardProps> = ({ text, index }) => {
const [copied, setCopied] = React.useState(false)
const [voted, setVoted] = React.useState<'up' | 'down' | null>(null)
const [isVoting, setIsVoting] = React.useState(false)
Expand All @@ -142,7 +142,7 @@ const SuggestionCard: React.FC<SuggestionCardProps> = ({ text, index, backendUrl
if (voted !== null || isVoting) return
setIsVoting(true)
try {
await axios.post(`${backendUrl}/api/suggestion-feedback/`, {
await axios.post(`${BACKEND_URL}/api/suggestion-feedback/`, {
suggestion: text,
vote,
index,
Expand Down Expand Up @@ -362,12 +362,10 @@ function App() {
setEntries,
} = useAnalysisHistory()

const backendUrl = import.meta.env.VITE_BACKEND_URL || 'http://127.0.0.1:8000'

const handleDeleteEntry = async (id: string) => {
if (user) {
try {
await axios.delete(`${backendUrl}/api/history/${id}/`, {
await axios.delete(`${BACKEND_URL}/api/history/${id}/`, {
headers: { Authorization: `Bearer ${user.token}` },
})
} catch (error) {
Expand All @@ -384,7 +382,7 @@ function App() {
const handleClearAll = async () => {
if (user) {
try {
await axios.delete(`${backendUrl}/api/history/clear/`, {
await axios.delete(`${BACKEND_URL}/api/history/clear/`, {
headers: { Authorization: `Bearer ${user.token}` },
})
} catch (error) {
Expand All @@ -397,7 +395,7 @@ function App() {
const fetchDbHistory = useCallback(
async (token: string) => {
try {
const res = await axios.get(`${backendUrl}/api/history/`, {
const res = await axios.get(`${BACKEND_URL}/api/history/`, {
headers: { Authorization: `Bearer ${token}` },
})
const dbEntries: AnalysisEntry[] = res.data.map(
Expand Down Expand Up @@ -433,7 +431,7 @@ function App() {
/* silently ignore */
}
},
[backendUrl, setEntries]
[setEntries]
)

useEffect(() => {
Expand Down Expand Up @@ -602,7 +600,7 @@ function App() {
}, 1000)

const headers = user ? { Authorization: `Bearer ${user.token}` } : {}
const res = await axios.post(`${backendUrl}/api/upload/`, formData, { headers })
const res = await axios.post(`${BACKEND_URL}/api/upload/`, formData, { headers })

clearTimeout(stageTimer1)
clearTimeout(stageTimer2)
Expand Down Expand Up @@ -1626,7 +1624,6 @@ function App() {
key={index}
text={suggestion}
index={index}
backendUrl={backendUrl}
/>
))}
</div>
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/components/AccountSettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from "react";
import { X, Trash2, Loader2, ShieldAlert } from "lucide-react";
import { BACKEND_URL } from "../config";
import type { AuthUser } from "../hooks/useAuth";
import axios from "axios";

Expand All @@ -20,8 +21,6 @@ export const AccountSettingsModal: React.FC<AccountSettingsModalProps> = ({
const [loading, setLoading] = useState(false);
const [showDeleteZone, setShowDeleteZone] = useState(false);

const backendUrl = import.meta.env.VITE_BACKEND_URL || "http://127.0.0.1:8000";

const handleDelete = async (e: React.FormEvent) => {
e.preventDefault();
if (!user) return;
Expand All @@ -35,7 +34,7 @@ export const AccountSettingsModal: React.FC<AccountSettingsModalProps> = ({
setLoading(true);

try {
await axios.delete(`${backendUrl}/api/auth/delete-account/`, {
await axios.delete(`${BACKEND_URL}/api/auth/delete-account/`, {
headers: { Authorization: `Bearer ${user.token}` },
data: { password, confirm_text: confirmText },
});
Expand Down
13 changes: 7 additions & 6 deletions frontend/src/components/Navbar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('Navbar Component (#241)', () => {
user: null,
onLogin: vi.fn(),
onLogout: vi.fn(),
onHistoryClick: vi.fn(),
onSettingsClick: vi.fn(), onHistoryClick: vi.fn(),
}

it('renders the header brand with emoji and "AI Resume Analyzer" title text', () => {
Expand All @@ -36,7 +36,7 @@ describe('Navbar Component right-side cluster (#244)', () => {
user={null}
onLogin={() => {}}
onLogout={() => {}}
onHistoryClick={() => {}}
onSettingsClick={() => {}} onHistoryClick={() => {}}
/>
)

Expand All @@ -58,7 +58,7 @@ describe('Navbar Component right-side cluster (#244)', () => {
user={user}
onLogin={() => {}}
onLogout={() => {}}
onHistoryClick={() => {}}
onSettingsClick={() => {}} onHistoryClick={() => {}}
/>
)

Expand All @@ -76,7 +76,7 @@ describe('Navbar responsive hamburger (#245)', () => {
user={null}
onLogin={() => {}}
onLogout={() => {}}
onHistoryClick={() => {}}
onSettingsClick={() => {}} onHistoryClick={() => {}}
/>
)

Expand All @@ -94,7 +94,7 @@ describe('Navbar responsive hamburger (#245)', () => {
user={null}
onLogin={() => {}}
onLogout={() => {}}
onHistoryClick={() => {}}
onSettingsClick={() => {}} onHistoryClick={() => {}}
/>
)

Expand All @@ -121,6 +121,7 @@ describe('Navbar responsive hamburger (#245)', () => {
user={null}
onLogin={() => {}}
onLogout={() => {}}
onSettingsClick={() => {}}
onHistoryClick={onHistoryClick}
/>
)
Expand All @@ -145,7 +146,7 @@ describe('Navbar responsive hamburger (#245)', () => {
user={null}
onLogin={() => {}}
onLogout={() => {}}
onHistoryClick={() => {}}
onSettingsClick={() => {}} onHistoryClick={() => {}}
/>
)

Expand Down
24 changes: 24 additions & 0 deletions frontend/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const ENV_CONFIG = {
development: {
BACKEND_URL: 'http://127.0.0.1:8000',
},
staging: {
BACKEND_URL: 'https://staging-api.airesumeanalyzer.com',
},
production: {
BACKEND_URL: 'https://api.airesumeanalyzer.com',
},
}

const getEnvMode = () => {
const mode = import.meta.env.MODE || 'development'
return mode as keyof typeof ENV_CONFIG
}

const currentConfig = ENV_CONFIG[getEnvMode()] || ENV_CONFIG.development

/**
* BACKEND_URL prioritizes the explicit VITE_BACKEND_URL environment variable.
* If not provided, it falls back to the configured URL for the current environment mode (dev/staging/prod).
*/
export const BACKEND_URL = import.meta.env.VITE_BACKEND_URL || currentConfig.BACKEND_URL
8 changes: 4 additions & 4 deletions frontend/src/hooks/useAuth.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState, useCallback } from 'react'
import axios from 'axios'

const BACKEND = import.meta.env.VITE_BACKEND_URL || 'http://127.0.0.1:8000'
import { BACKEND_URL } from '../config'

export interface AuthUser {
username: string
Expand Down Expand Up @@ -31,13 +31,13 @@ export function useAuth() {
}

const signup = useCallback(async (username: string, password: string) => {
await axios.post(`${BACKEND}/api/auth/signup/`, { username, password })
const res = await axios.post(`${BACKEND}/api/auth/login/`, { username, password })
await axios.post(`${BACKEND_URL}/api/auth/signup/`, { username, password })
const res = await axios.post(`${BACKEND_URL}/api/auth/login/`, { username, password })
persist({ username, token: res.data.access })
}, [])

const login = useCallback(async (username: string, password: string) => {
const res = await axios.post(`${BACKEND}/api/auth/login/`, { username, password })
const res = await axios.post(`${BACKEND_URL}/api/auth/login/`, { username, password })
persist({ username, token: res.data.access })
}, [])

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/hooks/useCompareVersions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface VersionComparison {
insights: string[]
}

const BACKEND = import.meta.env.VITE_BACKEND_URL || 'http://127.0.0.1:8000'
import { BACKEND_URL } from '../config'

export function useCompareVersions(token: string | undefined) {
const [comparison, setComparison] = useState<VersionComparison | null>(null)
Expand All @@ -39,7 +39,7 @@ export function useCompareVersions(token: string | undefined) {
setLoading(true)
setError(null)
try {
const res = await axios.get<VersionComparison>(`${BACKEND}/api/compare/`, {
const res = await axios.get<VersionComparison>(`${BACKEND_URL}/api/compare/`, {
headers: { Authorization: `Bearer ${token}` },
params: { older: olderId, newer: newerId },
})
Expand Down