Skip to content

Commit 29a4ac4

Browse files
committed
fix: currency converter and auth apis
1 parent d71c483 commit 29a4ac4

File tree

3 files changed

+33
-19
lines changed

3 files changed

+33
-19
lines changed

app/api/currency/route.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getSession } from "@/lib/auth"
22
import { PoorManCache } from "@/lib/cache"
3-
import { format } from "date-fns"
3+
import { format, isSameDay, subDays } from "date-fns"
44
import { NextRequest, NextResponse } from "next/server"
55

66
type HistoricRate = {
@@ -36,11 +36,17 @@ export async function GET(request: NextRequest) {
3636
return NextResponse.json({ error: "Missing required parameters: from, to, date" }, { status: 400 })
3737
}
3838

39-
const date = new Date(dateParam)
39+
let date = new Date(dateParam)
40+
4041
if (isNaN(date.getTime())) {
4142
return NextResponse.json({ error: "Invalid date format" }, { status: 400 })
4243
}
4344

45+
// hack to get yesterday's rate if it's today
46+
if (isSameDay(date, new Date())) {
47+
date = subDays(date, 1)
48+
}
49+
4450
const formattedDate = format(date, "yyyy-MM-dd")
4551

4652
// Check cache first

components/forms/convert-currency.tsx

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import { FormError } from "@/components/forms/error"
12
import { formatCurrency } from "@/lib/utils"
23
import { format, startOfDay } from "date-fns"
34
import { Loader2 } from "lucide-react"
45
import { useEffect, useState } from "react"
5-
66
export const FormConvertCurrency = ({
77
originalTotal,
88
originalCurrencyCode,
@@ -25,18 +25,23 @@ export const FormConvertCurrency = ({
2525
const [exchangeRate, setExchangeRate] = useState(0)
2626
const [convertedTotal, setConvertedTotal] = useState(0)
2727
const [isLoading, setIsLoading] = useState(false)
28+
const [error, setError] = useState<string | null>(null)
2829

2930
useEffect(() => {
3031
const fetchData = async () => {
3132
try {
3233
setIsLoading(true)
34+
setError(null)
35+
3336
const exchangeRate = await getCurrencyRate(originalCurrencyCode, targetCurrencyCode, normalizedDate)
37+
3438
setExchangeRate(exchangeRate)
3539
setConvertedTotal(Math.round(originalTotal * exchangeRate * 100) / 100)
3640
} catch (error) {
3741
console.error("Error fetching currency rates:", error)
3842
setExchangeRate(0)
3943
setConvertedTotal(0)
44+
setError(error instanceof Error ? error.message : "Failed to fetch currency rate")
4045
} finally {
4146
setIsLoading(false)
4247
}
@@ -74,28 +79,26 @@ export const FormConvertCurrency = ({
7479
className="w-32 rounded-md border border-input px-2 py-1"
7580
/>
7681
</div>
77-
<div className="text-xs text-muted-foreground">The exchange rate will be added to the transaction</div>
82+
{!error && (
83+
<div className="text-xs text-muted-foreground">The exchange rate will be added to the transaction</div>
84+
)}
85+
{error && <FormError className="mt-0 text-sm">{error}</FormError>}
7886
</div>
7987
)}
8088
</div>
8189
)
8290
}
8391

8492
async function getCurrencyRate(currencyCodeFrom: string, currencyCodeTo: string, date: Date): Promise<number> {
85-
try {
86-
const formattedDate = format(date, "yyyy-MM-dd")
87-
const response = await fetch(`/api/currency?from=${currencyCodeFrom}&to=${currencyCodeTo}&date=${formattedDate}`)
93+
const formattedDate = format(date, "yyyy-MM-dd")
94+
const response = await fetch(`/api/currency?from=${currencyCodeFrom}&to=${currencyCodeTo}&date=${formattedDate}`)
8895

89-
if (!response.ok) {
90-
const errorData = await response.json()
91-
console.error("Currency API error:", errorData.error)
92-
return 0
93-
}
94-
95-
const data = await response.json()
96-
return data.rate
97-
} catch (error) {
98-
console.error("Error fetching currency rate:", error)
99-
return 0
96+
if (!response.ok) {
97+
const errorData = await response.json()
98+
console.log("Currency API error:", errorData.error)
99+
throw new Error(errorData.error || "Failed to fetch currency rate")
100100
}
101+
102+
const data = await response.json()
103+
return data.rate
101104
}

lib/auth.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import config from "@/lib/config"
22
import { createUserDefaults } from "@/models/defaults"
3-
import { getSelfHostedUser } from "@/models/users"
3+
import { getSelfHostedUser, getUserByEmail } from "@/models/users"
44
import { User } from "@prisma/client"
55
import { betterAuth } from "better-auth"
66
import { prismaAdapter } from "better-auth/adapters/prisma"
7+
import { APIError } from "better-auth/api"
78
import { nextCookies } from "better-auth/next-js"
89
import { emailOTP } from "better-auth/plugins/email-otp"
910
import { headers } from "next/headers"
@@ -56,6 +57,10 @@ export const auth = betterAuth({
5657
otpLength: 6,
5758
expiresIn: 10 * 60, // 10 minutes
5859
sendVerificationOTP: async ({ email, otp }) => {
60+
const user = await getUserByEmail(email)
61+
if (!user) {
62+
throw new APIError("NOT_FOUND", { message: "User with this email does not exist" })
63+
}
5964
await sendOTPCodeEmail({ email, otp })
6065
},
6166
}),

0 commit comments

Comments
 (0)