fix: currency converter and auth apis

This commit is contained in:
Vasily Zubarev
2025-04-09 15:04:48 +02:00
parent d71c4834c1
commit 29a4ac4977
3 changed files with 33 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
import { getSession } from "@/lib/auth"
import { PoorManCache } from "@/lib/cache"
import { format } from "date-fns"
import { format, isSameDay, subDays } from "date-fns"
import { NextRequest, NextResponse } from "next/server"
type HistoricRate = {
@@ -36,11 +36,17 @@ export async function GET(request: NextRequest) {
return NextResponse.json({ error: "Missing required parameters: from, to, date" }, { status: 400 })
}
const date = new Date(dateParam)
let date = new Date(dateParam)
if (isNaN(date.getTime())) {
return NextResponse.json({ error: "Invalid date format" }, { status: 400 })
}
// hack to get yesterday's rate if it's today
if (isSameDay(date, new Date())) {
date = subDays(date, 1)
}
const formattedDate = format(date, "yyyy-MM-dd")
// Check cache first

View File

@@ -1,8 +1,8 @@
import { FormError } from "@/components/forms/error"
import { formatCurrency } from "@/lib/utils"
import { format, startOfDay } from "date-fns"
import { Loader2 } from "lucide-react"
import { useEffect, useState } from "react"
export const FormConvertCurrency = ({
originalTotal,
originalCurrencyCode,
@@ -25,18 +25,23 @@ export const FormConvertCurrency = ({
const [exchangeRate, setExchangeRate] = useState(0)
const [convertedTotal, setConvertedTotal] = useState(0)
const [isLoading, setIsLoading] = useState(false)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
const fetchData = async () => {
try {
setIsLoading(true)
setError(null)
const exchangeRate = await getCurrencyRate(originalCurrencyCode, targetCurrencyCode, normalizedDate)
setExchangeRate(exchangeRate)
setConvertedTotal(Math.round(originalTotal * exchangeRate * 100) / 100)
} catch (error) {
console.error("Error fetching currency rates:", error)
setExchangeRate(0)
setConvertedTotal(0)
setError(error instanceof Error ? error.message : "Failed to fetch currency rate")
} finally {
setIsLoading(false)
}
@@ -74,7 +79,10 @@ export const FormConvertCurrency = ({
className="w-32 rounded-md border border-input px-2 py-1"
/>
</div>
{!error && (
<div className="text-xs text-muted-foreground">The exchange rate will be added to the transaction</div>
)}
{error && <FormError className="mt-0 text-sm">{error}</FormError>}
</div>
)}
</div>
@@ -82,20 +90,15 @@ export const FormConvertCurrency = ({
}
async function getCurrencyRate(currencyCodeFrom: string, currencyCodeTo: string, date: Date): Promise<number> {
try {
const formattedDate = format(date, "yyyy-MM-dd")
const response = await fetch(`/api/currency?from=${currencyCodeFrom}&to=${currencyCodeTo}&date=${formattedDate}`)
if (!response.ok) {
const errorData = await response.json()
console.error("Currency API error:", errorData.error)
return 0
console.log("Currency API error:", errorData.error)
throw new Error(errorData.error || "Failed to fetch currency rate")
}
const data = await response.json()
return data.rate
} catch (error) {
console.error("Error fetching currency rate:", error)
return 0
}
}

View File

@@ -1,9 +1,10 @@
import config from "@/lib/config"
import { createUserDefaults } from "@/models/defaults"
import { getSelfHostedUser } from "@/models/users"
import { getSelfHostedUser, getUserByEmail } from "@/models/users"
import { User } from "@prisma/client"
import { betterAuth } from "better-auth"
import { prismaAdapter } from "better-auth/adapters/prisma"
import { APIError } from "better-auth/api"
import { nextCookies } from "better-auth/next-js"
import { emailOTP } from "better-auth/plugins/email-otp"
import { headers } from "next/headers"
@@ -56,6 +57,10 @@ export const auth = betterAuth({
otpLength: 6,
expiresIn: 10 * 60, // 10 minutes
sendVerificationOTP: async ({ email, otp }) => {
const user = await getUserByEmail(email)
if (!user) {
throw new APIError("NOT_FOUND", { message: "User with this email does not exist" })
}
await sendOTPCodeEmail({ email, otp })
},
}),