-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Created a dummy data file to add trannsactions in user accountn to ma…
…ke development efficient
- Loading branch information
1 parent
b8b9585
commit c0c047a
Showing
7 changed files
with
493 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { DB } from "@/lib/prisma"; | ||
import { auth } from "@clerk/nextjs/server"; | ||
|
||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
|
||
const serializeDecimal = (obj: any) => { | ||
const serialized = { ...obj }; | ||
if (obj.balance) { | ||
serialized.balance = obj.balance.toNumber(); | ||
} | ||
if (obj.amount) { | ||
serialized.amount = obj.amount.toNumber(); | ||
} | ||
return serialized; | ||
}; | ||
|
||
export async function getAccountDetails(acccountId: string) { | ||
try { | ||
const { userId } = await auth(); | ||
|
||
if (!userId) { | ||
throw new Error("Unauthorized!!"); | ||
} | ||
|
||
// Get accounts | ||
const user = await DB.user.findUnique({ | ||
where: { | ||
clerkUserId: userId, | ||
}, | ||
}); | ||
|
||
if (!user) { | ||
throw new Error("User not found"); | ||
} | ||
|
||
const account = await DB.account.findUnique({ | ||
where: { | ||
id: acccountId, | ||
userId: user.id, | ||
}, | ||
include: { | ||
transactions: { | ||
orderBy: { | ||
createdAt: "desc", | ||
}, | ||
}, | ||
_count: { | ||
select: { transactions: true }, | ||
}, | ||
}, | ||
}); | ||
|
||
if (!account) return null; | ||
|
||
return { | ||
...serializeDecimal(account), | ||
transactions: account.transactions.map(serializeDecimal), | ||
}; | ||
} catch (error: any) { | ||
console.error(error?.message); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
// app/account/[id]/seedTransactions.ts | ||
|
||
"use server"; | ||
|
||
import { DB } from "@/lib/prisma"; | ||
import { subDays } from "date-fns"; | ||
import { v4 as uuidv4 } from "uuid"; // Using uuid library for broader compatibility | ||
|
||
// Constants for account and user IDs | ||
const ACCOUNT_ID = "4440ff34-e541-4f6d-a784-2e07a8c92cb6"; // Replace with actual account ID or use environment variables | ||
const USER_ID = "9f09201a-dc5a-4bc8-afb0-2044ea947e77"; // Replace with actual user ID or use environment variables | ||
|
||
// Define Category and Type interfaces | ||
interface Category { | ||
name: string; | ||
range: [number, number]; | ||
} | ||
|
||
interface Categories { | ||
INCOME: Category[]; | ||
EXPENSE: Category[]; | ||
} | ||
|
||
// Categories with their typical amount ranges | ||
const CATEGORIES: Categories = { | ||
INCOME: [ | ||
{ name: "salary", range: [5000, 8000] }, | ||
{ name: "freelance", range: [1000, 3000] }, | ||
{ name: "investments", range: [500, 2000] }, | ||
{ name: "other-income", range: [100, 1000] }, | ||
], | ||
EXPENSE: [ | ||
{ name: "housing", range: [1000, 2000] }, | ||
{ name: "transportation", range: [100, 500] }, | ||
{ name: "groceries", range: [200, 600] }, | ||
{ name: "utilities", range: [100, 300] }, | ||
{ name: "entertainment", range: [50, 200] }, | ||
{ name: "food", range: [50, 150] }, | ||
{ name: "shopping", range: [100, 500] }, | ||
{ name: "healthcare", range: [100, 1000] }, | ||
{ name: "education", range: [200, 1000] }, | ||
{ name: "travel", range: [500, 2000] }, | ||
], | ||
}; | ||
|
||
// Define TransactionStatus as a union of possible statuses | ||
type TransactionStatus = "COMPLETED" | "PENDING" | "FAILED"; | ||
|
||
// Transaction interface | ||
interface Transaction { | ||
id: string; | ||
type: "INCOME" | "EXPENSE"; | ||
amount: number; | ||
description: string; | ||
date: Date; | ||
category: string; | ||
status: TransactionStatus; | ||
userId: string; | ||
accountId: string; | ||
createdAt: Date; | ||
updatedAt: Date; | ||
} | ||
|
||
// Seed result interface | ||
interface SeedResult { | ||
success: boolean; | ||
message?: string; | ||
error?: string; | ||
} | ||
|
||
// Helper to generate random amount within a range | ||
function getRandomAmount(min: number, max: number): number { | ||
return Number((Math.random() * (max - min) + min).toFixed(2)); | ||
} | ||
|
||
// Helper to get random category with amount | ||
function getRandomCategory(type: keyof Categories): { | ||
category: string; | ||
amount: number; | ||
} { | ||
const categories = CATEGORIES[type]; | ||
const category = categories[Math.floor(Math.random() * categories.length)]; | ||
const amount = getRandomAmount(category.range[0], category.range[1]); | ||
return { category: category.name, amount }; | ||
} | ||
|
||
// Seed transactions function | ||
export async function seedTransactions(): Promise<SeedResult> { | ||
try { | ||
// Generate 90 days of transactions | ||
const transactions: Transaction[] = []; | ||
let totalBalance = 0; | ||
|
||
for (let i = 90; i >= 0; i--) { | ||
const date = subDays(new Date(), i); | ||
|
||
// Generate 1-3 transactions per day | ||
const transactionsPerDay = Math.floor(Math.random() * 3) + 1; | ||
|
||
for (let j = 0; j < transactionsPerDay; j++) { | ||
// 40% chance of income, 60% chance of expense | ||
const type: "INCOME" | "EXPENSE" = | ||
Math.random() < 0.4 ? "INCOME" : "EXPENSE"; | ||
const { category, amount } = getRandomCategory(type); | ||
|
||
const transaction: Transaction = { | ||
id: uuidv4(), // Using uuidv4 for UUID generation | ||
type, | ||
amount, | ||
description: `${ | ||
type === "INCOME" ? "Received" : "Paid for" | ||
} ${category}`, | ||
date, | ||
category, | ||
status: "COMPLETED", // Assuming all transactions are completed; adjust if needed | ||
userId: USER_ID, | ||
accountId: ACCOUNT_ID, | ||
createdAt: date, | ||
updatedAt: date, | ||
}; | ||
|
||
totalBalance += type === "INCOME" ? amount : -amount; | ||
transactions.push(transaction); | ||
} | ||
} | ||
|
||
// Insert transactions in batches and update account balance | ||
await DB.$transaction(async (tx) => { | ||
// Clear existing transactions | ||
await tx.transaction.deleteMany({ | ||
where: { accountId: ACCOUNT_ID }, | ||
}); | ||
|
||
// Insert new transactions | ||
await tx.transaction.createMany({ | ||
data: transactions, | ||
}); | ||
|
||
// Update account balance | ||
await tx.account.update({ | ||
where: { id: ACCOUNT_ID }, | ||
data: { balance: totalBalance }, | ||
}); | ||
}); | ||
|
||
return { | ||
success: true, | ||
message: `Created ${transactions.length} transactions`, | ||
}; | ||
} catch (error: any) { | ||
console.error("Error seeding transactions:", error); | ||
return { success: false, error: error.message }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,83 @@ | ||
import React from "react"; | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
"// app/account/[id]/page.tsx"; | ||
|
||
const Account = () => { | ||
return <div>Account</div>; | ||
export const dynamic = "force-dynamic"; | ||
|
||
import { Suspense } from "react"; | ||
import { BarLoader } from "react-spinners"; | ||
import { notFound } from "next/navigation"; | ||
import { getAccountDetails } from "@/actions/Account"; | ||
|
||
// Define the Account interface | ||
interface Account { | ||
id: string; | ||
name: string; | ||
type: string; | ||
balance: number; | ||
_count: { | ||
transactions: number; | ||
}; | ||
transactions: any[]; | ||
} | ||
|
||
const AccountPage = async ({ params }: { params: { id: string } }) => { | ||
const parameters = await params; | ||
const accountId = parameters.id; | ||
|
||
const accountData: Account | null = await getAccountDetails(accountId); | ||
|
||
if (!accountData) { | ||
notFound(); | ||
} | ||
|
||
const { transactions, ...account } = accountData; | ||
|
||
console.log(transactions); | ||
|
||
return ( | ||
<div className="container mx-auto py-8 px-5"> | ||
<div className="space-y-8 px-5"> | ||
<div className="flex gap-4 items-end justify-between space-y-0 pb-2"> | ||
<div> | ||
<h1 className="text-3xl sm:text-5xl font-bold tracking-tight text-transparent bg-clip-text bg-gradient-to-r from-sky-500 to-blue-600 capitalize"> | ||
{account.name} | ||
</h1> | ||
<p className="text-muted-foreground "> | ||
{account.type.charAt(0) + account.type.slice(1).toLowerCase()}{" "} | ||
Account | ||
</p> | ||
</div> | ||
|
||
<div className="text-right pb-2"> | ||
<div className="text-xl sm:text-2xl font-bold"> | ||
${account.balance.toFixed(2)} | ||
</div> | ||
<p className="text-sm text-muted-foreground"> | ||
{account._count.transactions} Transactions | ||
</p> | ||
</div> | ||
</div> | ||
|
||
{/* Chart Section */} | ||
<Suspense | ||
fallback={ | ||
<BarLoader className="mt-4" width={"100%"} color="#9333ea" /> | ||
} | ||
> | ||
{/* <AccountChart transactions={transactions} /> */} | ||
</Suspense> | ||
|
||
{/* Transactions Table */} | ||
<Suspense | ||
fallback={ | ||
<BarLoader className="mt-4" width={"100%"} color="#9333ea" /> | ||
} | ||
> | ||
{/* <TransactionTable transactions={transactions} /> */} | ||
</Suspense> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Account; | ||
export default AccountPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import { seedTransactions } from "@/actions/seed"; | ||
|
||
export async function GET() { | ||
const result = await seedTransactions(); | ||
|
||
return Response.json(result); | ||
} |
Oops, something went wrong.