Skip to content

Commit f867469

Browse files
committed
feat: Improve authentication error handling and add file upload validation in profile settings
1 parent 964cb22 commit f867469

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed

web/pages/Auth.tsx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import { THEMES } from '../constants';
88
import { useAuth } from '../contexts/AuthContext';
99
import { useTheme } from '../contexts/ThemeContext';
1010
import {
11-
login as apiLogin,
12-
signup as apiSignup,
13-
loginWithGoogle,
11+
login as apiLogin,
12+
signup as apiSignup,
13+
loginWithGoogle,
1414
} from '../services/api';
1515
import { signInWithGoogle } from '../services/firebase';
1616

@@ -34,16 +34,22 @@ export const Auth = () => {
3434
try {
3535
const idToken = await signInWithGoogle();
3636
const res = await loginWithGoogle(idToken);
37-
const { access_token, user } = res.data;
37+
const { access_token, user } = res.data ?? {};
38+
if (!access_token || !user) {
39+
throw new Error('Invalid response from server');
40+
}
3841
login(access_token, user);
3942
navigate('/dashboard');
4043
} catch (err: any) {
4144
console.error('Google login error:', err);
4245
if (err.code === 'auth/popup-closed-by-user') {
4346
setError('');
4447
} else if (err.response) {
48+
const detail = err.response.data?.detail;
4549
setError(
46-
err.response.data?.detail || 'Google authentication failed'
50+
typeof detail === 'string'
51+
? detail
52+
: detail?.[0]?.msg || 'Google authentication failed'
4753
);
4854
} else {
4955
setError(err.message || 'Google authentication failed. Please try again.');
@@ -71,8 +77,11 @@ export const Auth = () => {
7177
navigate('/dashboard');
7278
} catch (err: any) {
7379
if (err.response) {
80+
const detail = err.response.data?.detail;
7481
setError(
75-
err.response.data?.detail?.[0]?.msg || 'Authentication failed'
82+
typeof detail === 'string'
83+
? detail
84+
: detail?.[0]?.msg || 'Authentication failed'
7685
);
7786
} else {
7887
setError('Something went wrong');
@@ -161,7 +170,11 @@ export const Auth = () => {
161170
}`}
162171
>
163172
{googleLoading ? (
164-
<div className="w-5 h-5 border-2 border-black/20 border-t-black rounded-full animate-spin" />
173+
<div
174+
className="w-5 h-5 border-2 border-black/20 border-t-black rounded-full animate-spin"
175+
role="status"
176+
aria-label="Signing in with Google"
177+
/>
165178
) : (
166179
<svg className="w-5 h-5" viewBox="0 0 24 24" role="img" aria-labelledby="google-logo-title">
167180
<title id="google-logo-title">Google logo</title>

web/pages/Friends.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ export const Friends = () => {
239239
? 'text-orange-500'
240240
: 'opacity-30'
241241
}`}>
242-
{formatCurrency(friend.netBalance)}
242+
{friend.netBalance > 0 ? '+' : friend.netBalance < 0 ? '-' : ''}{formatCurrency(friend.netBalance)}
243243
</p>
244244
</div>
245245

web/pages/GroupDetails.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ import { Expense, Group, GroupMember, SplitType } from '../types';
2626

2727
type UnequalMode = 'amount' | 'percentage' | 'shares';
2828

29+
interface Settlement {
30+
fromUserId: string;
31+
fromUserName: string;
32+
toUserId: string;
33+
toUserName: string;
34+
amount: number;
35+
}
36+
2937
export const GroupDetails = () => {
3038
const { id } = useParams<{ id: string }>();
3139
const navigate = useNavigate();
@@ -35,7 +43,7 @@ export const GroupDetails = () => {
3543
const [group, setGroup] = useState<Group | null>(null);
3644
const [expenses, setExpenses] = useState<Expense[]>([]);
3745
const [members, setMembers] = useState<GroupMember[]>([]);
38-
const [settlements, setSettlements] = useState<any[]>([]);
46+
const [settlements, setSettlements] = useState<Settlement[]>([]);
3947
const [loading, setLoading] = useState(true);
4048
const [activeTab, setActiveTab] = useState<'expenses' | 'settlements'>('expenses');
4149

@@ -178,7 +186,7 @@ export const GroupDetails = () => {
178186
setSelectedUsers(new Set(expense.splits.map(s => s.userId)));
179187
} else {
180188
setUnequalMode('amount');
181-
const vals: any = {};
189+
const vals: Record<string, string> = {};
182190
expense.splits.forEach(s => vals[s.userId] = s.amount.toString());
183191
setSplitValues(vals);
184192
}

web/pages/Profile.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ export const Profile = () => {
2626
const file = e.target.files?.[0];
2727
if (!file) return;
2828

29+
const maxSize = 5 * 1024 * 1024; // 5MB
30+
if (file.size > maxSize) {
31+
setSaveError('Image must be less than 5MB');
32+
return;
33+
}
34+
35+
if (!file.type.startsWith('image/')) {
36+
setSaveError('Please select a valid image file');
37+
return;
38+
}
39+
2940
const reader = new FileReader();
3041
reader.onload = () => {
3142
const result = reader.result as string;

0 commit comments

Comments
 (0)