feature/research-di #1
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,7 +9,7 @@
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/versions
|
||||
|
||||
.vscode
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import fetchSummaryInfoUsecase from '@/feature/core/summary-info/domain/usecase/fetch-summary-info-usecase';
|
||||
import {
|
||||
BanknotesIcon,
|
||||
ClockIcon,
|
||||
UserGroupIcon,
|
||||
InboxIcon,
|
||||
} from '@heroicons/react/24/outline';
|
||||
import { fetchCardData } from '@/app/lib/data';
|
||||
|
||||
const iconMap = {
|
||||
collected: BanknotesIcon,
|
||||
@ -14,21 +14,16 @@ const iconMap = {
|
||||
};
|
||||
|
||||
export default async function CardWrapper() {
|
||||
const {
|
||||
numberOfInvoices,
|
||||
numberOfCustomers,
|
||||
totalPaidInvoices,
|
||||
totalPendingInvoices,
|
||||
} = await fetchCardData();
|
||||
const {customersNumber, invoicesNumber, invoicesSummary } = await fetchSummaryInfoUsecase();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card title="Collected" value={totalPaidInvoices} type="collected" />
|
||||
<Card title="Pending" value={totalPendingInvoices} type="pending" />
|
||||
<Card title="Total Invoices" value={numberOfInvoices} type="invoices" />
|
||||
<Card title="Collected" value={invoicesSummary.paid} type="collected" />
|
||||
<Card title="Pending" value={invoicesSummary.pending} type="pending" />
|
||||
<Card title="Total Invoices" value={invoicesNumber} type="invoices" />
|
||||
<Card
|
||||
title="Total Customers"
|
||||
value={numberOfCustomers}
|
||||
value={customersNumber}
|
||||
type="customers"
|
||||
/>
|
||||
</>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import fetchCustomerInvoicesUsecase from '@/feature/core/customer-invoice/domain/usecase/fetch-customer-invoices-usecase';
|
||||
import { ArrowPathIcon } from '@heroicons/react/24/outline';
|
||||
import clsx from 'clsx';
|
||||
import Image from 'next/image';
|
||||
import { fetchLatestInvoices } from '@/app/lib/data';
|
||||
export default async function LatestInvoices() {
|
||||
const latestInvoices = await fetchLatestInvoices();
|
||||
const latestInvoices = await fetchCustomerInvoicesUsecase();
|
||||
|
||||
return (
|
||||
<div className="flex w-full flex-col md:col-span-4">
|
||||
@ -26,25 +26,25 @@ export default async function LatestInvoices() {
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<Image
|
||||
src={invoice.image_url}
|
||||
alt={`${invoice.name}'s profile picture`}
|
||||
src={invoice.customerImageUrl}
|
||||
alt={`${invoice.customerName}'s profile picture`}
|
||||
className="mr-4 rounded-full"
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<div className="min-w-0">
|
||||
<p className="truncate text-sm font-semibold md:text-base">
|
||||
{invoice.name}
|
||||
{invoice.customerName}
|
||||
</p>
|
||||
<p className="hidden text-sm text-gray-500 sm:block">
|
||||
{invoice.email}
|
||||
{invoice.customerEmail}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
className="truncate text-sm font-medium md:text-base"
|
||||
>
|
||||
{invoice.amount}
|
||||
{invoice.invoicesAmount}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { generateYAxis } from '@/app/lib/utils';
|
||||
import fetchRevenuesUsecase from '@/feature/core/revenue/domain/usecase/fetch-revenues-usecase';
|
||||
import { CalendarIcon } from '@heroicons/react/24/outline';
|
||||
import { fetchRevenue } from '@/app/lib/data';
|
||||
|
||||
export default async function RevenueChart() {
|
||||
const revenue = await fetchRevenue();
|
||||
const revenue = await fetchRevenuesUsecase();
|
||||
|
||||
const chartHeight = 350;
|
||||
|
||||
|
27
src/app/dashboard/module/dashboard-app-module.ts
Normal file
27
src/app/dashboard/module/dashboard-app-module.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import di from "@/bootstrap/di/init-di"
|
||||
import fetchCustomerInvoicesUsecase from "@/feature/core/customer-invoice/domain/usecase/fetch-customer-invoices-usecase";
|
||||
import fetchCustomersUsecase from "@/feature/core/customer/domain/usecase/fetch-customers-usecase";
|
||||
import fetchAllInvoicesAmountUsecase from "@/feature/core/invoice/domain/usecase/fetch-all-invoices-amount-usecase";
|
||||
import fetchRevenuesUsecase from "@/feature/core/revenue/domain/usecase/fetch-revenues-usecase";
|
||||
|
||||
export default function dashboardAppModule() {
|
||||
const dashboardDi = di.createChildContainer()
|
||||
|
||||
dashboardDi.register(fetchCustomersUsecase.name, {
|
||||
useValue: fetchCustomersUsecase
|
||||
})
|
||||
|
||||
dashboardDi.register(fetchAllInvoicesAmountUsecase.name, {
|
||||
useValue: fetchAllInvoicesAmountUsecase
|
||||
})
|
||||
dashboardDi.register(fetchAllInvoicesAmountUsecase.name, {
|
||||
useValue: fetchAllInvoicesAmountUsecase
|
||||
})
|
||||
dashboardDi.register(fetchCustomerInvoicesUsecase.name, {
|
||||
useValue: fetchCustomerInvoicesUsecase
|
||||
})
|
||||
dashboardDi.register(fetchRevenuesUsecase.name, {
|
||||
useValue: fetchRevenuesUsecase
|
||||
})
|
||||
return dashboardDi
|
||||
}
|
@ -12,7 +12,10 @@ import getSummaryInfoDi from "@/feature/core/summary-info/data/module/summary-in
|
||||
import { revenueModuleKey } from "@/feature/core/revenue/domain/revenue-module-key";
|
||||
import getRevenueDi from "@/feature/core/revenue/data/module/revenue-di";
|
||||
|
||||
const memoizedDis: Record<string, DependencyContainer> = {}
|
||||
|
||||
export default function serverDi(module: string): DependencyContainer {
|
||||
if (memoizedDis[module]) return memoizedDis[module]
|
||||
const getDi = {
|
||||
[testModuleKey]: getTestModule,
|
||||
[customerKey]: getCustomerDi,
|
||||
@ -24,5 +27,7 @@ export default function serverDi(module: string): DependencyContainer {
|
||||
|
||||
if (!getDi) throw new Error("Server Di didn't found for module: " + module)
|
||||
|
||||
return getDi()
|
||||
const di = getDi()
|
||||
memoizedDis[module] = di
|
||||
return di
|
||||
}
|
@ -1,16 +1,11 @@
|
||||
import di from "@/bootstrap/di/init-di";
|
||||
import CustomerInvoiceDbRepo from "@/feature/core/customer-invoice/data/repo/customer-invoice-db-repo";
|
||||
import { customerInvoiceRepoKey } from "@/feature/core/customer-invoice/domain/i-repo/customer-invoice-repo";
|
||||
import fetchCustomerInvoicesUsecase from "@/feature/core/customer-invoice/domain/usecase/fetch-customer-invoices-usecase";
|
||||
import CustomerDbRepo from "@/feature/core/customer/data/repo/customer-db-repo";
|
||||
import { DependencyContainer } from "tsyringe";
|
||||
|
||||
export default function getCustomerInvoiceDi(): DependencyContainer {
|
||||
const customerInvoiceDi = di.createChildContainer()
|
||||
|
||||
customerInvoiceDi.register(fetchCustomerInvoicesUsecase.name, {
|
||||
useValue: fetchCustomerInvoicesUsecase
|
||||
})
|
||||
|
||||
customerInvoiceDi.register(customerInvoiceRepoKey, CustomerDbRepo)
|
||||
customerInvoiceDi.register(customerInvoiceRepoKey, CustomerInvoiceDbRepo)
|
||||
return customerInvoiceDi
|
||||
}
|
@ -2,7 +2,6 @@ import { formatCurrency } from "@/app/lib/utils";
|
||||
import { sql } from "@/bootstrap/db/db";
|
||||
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice";
|
||||
import CustomerInvoiceRepo from "@/feature/core/customer-invoice/domain/i-repo/customer-invoice-repo";
|
||||
import { connection } from "next/server";
|
||||
import postgres from "postgres";
|
||||
|
||||
type customerInvoiceDbResponse = {
|
||||
@ -13,11 +12,8 @@ type customerInvoiceDbResponse = {
|
||||
amount: string;
|
||||
}
|
||||
|
||||
export default class CustomerDbRepo implements CustomerInvoiceRepo {
|
||||
export default class CustomerInvoiceDbRepo implements CustomerInvoiceRepo {
|
||||
async fetchList(): Promise<CustomerInvoice[]> {
|
||||
// This is equivalent to in fetch(..., {cache: 'no-store'}).
|
||||
connection()
|
||||
|
||||
try {
|
||||
const data = await sql`
|
||||
SELECT invoices.amount, customers.name, customers.image_url, customers.email, invoices.id
|
||||
|
@ -3,9 +3,10 @@ import serverDi from "@/feature/common/server-di";
|
||||
import CustomerInvoice from "@/feature/core/customer-invoice/domain/entity/customer-invoice";
|
||||
import CustomerInvoiceRepo, { customerInvoiceRepoKey } from "@/feature/core/customer-invoice/domain/i-repo/customer-invoice-repo";
|
||||
import { customerInvoiceModuleKey } from "@/feature/core/customer-invoice/invoice-module-key";
|
||||
import { connection } from "next/server";
|
||||
|
||||
export default function fetchCustomerInvoicesUsecase(): Promise<CustomerInvoice[]> {
|
||||
export default async function fetchCustomerInvoicesUsecase(): Promise<CustomerInvoice[]> {
|
||||
connection()
|
||||
const repo = serverDi(customerInvoiceModuleKey).resolve<CustomerInvoiceRepo>(customerInvoiceRepoKey)
|
||||
|
||||
return repo.fetchList()
|
||||
}
|
@ -1,16 +1,11 @@
|
||||
import di from "@/bootstrap/di/init-di";
|
||||
import CustomerDbRepo from "@/feature/core/customer/data/repo/customer-db-repo";
|
||||
import { customerRepoKey } from "@/feature/core/customer/domain/i-repo/customer-repo";
|
||||
import fetchCustomersUsecase from "@/feature/core/customer/domain/usecase/fetch-customers-usecase";
|
||||
import { DependencyContainer } from "tsyringe";
|
||||
|
||||
export default function getCustomerDi(): DependencyContainer {
|
||||
const customerDi = di.createChildContainer()
|
||||
|
||||
customerDi.register(fetchCustomersUsecase.name, {
|
||||
useValue: fetchCustomersUsecase
|
||||
})
|
||||
|
||||
customerDi.register(customerRepoKey, CustomerDbRepo)
|
||||
return customerDi
|
||||
}
|
@ -2,7 +2,7 @@ import serverDi from "@/feature/common/server-di";
|
||||
import { customerKey } from "@/feature/core/customer/customer-key";
|
||||
import CustomerRepo, { customerRepoKey } from "@/feature/core/customer/domain/i-repo/customer-repo";
|
||||
|
||||
export default function fetchCustomersAmountUsecase(): Promise<number> {
|
||||
export default async function fetchCustomersAmountUsecase(): Promise<number> {
|
||||
const repo = serverDi(customerKey).resolve<CustomerRepo>(customerRepoKey)
|
||||
return repo.fetchCustomersAmount()
|
||||
}
|
@ -5,7 +5,7 @@ import { customerKey } from "@/feature/core/customer/customer-key";
|
||||
import Customer from "@/feature/core/customer/domain/entity/customer";
|
||||
import CustomerRepo, { customerRepoKey } from "@/feature/core/customer/domain/i-repo/customer-repo";
|
||||
|
||||
export default function fetchCustomersUsecase(query: string): Promise<Customer[]> {
|
||||
export default async function fetchCustomersUsecase(query: string): Promise<Customer[]> {
|
||||
const repo = serverDi(customerKey).resolve<CustomerRepo>(customerRepoKey)
|
||||
|
||||
return repo.fetchList(query)
|
||||
|
@ -3,7 +3,7 @@ import serverDi from "@/feature/common/server-di";
|
||||
import InvoiceRepo, { invoiceRepoKey } from "@/feature/core/invoice/domain/i-repo/invoice-repo";
|
||||
import { invoiceModuleKey } from "@/feature/core/invoice/invoice-module-key";
|
||||
|
||||
export default function fetchAllInvoicesAmountUsecase(): Promise<number> {
|
||||
export default async function fetchAllInvoicesAmountUsecase(): Promise<number> {
|
||||
const repo = serverDi(invoiceModuleKey).resolve<InvoiceRepo>(invoiceRepoKey)
|
||||
|
||||
return repo.fetchAllInvoicesAmount()
|
||||
|
@ -3,7 +3,7 @@ import InvoiceRepo, { invoiceRepoKey } from "@/feature/core/invoice/domain/i-rep
|
||||
import InvoiceStatusSummary from "@/feature/core/invoice/domain/value-object/invoice-status";
|
||||
import { invoiceModuleKey } from "@/feature/core/invoice/invoice-module-key";
|
||||
|
||||
export default function fetchInvoicesStatusSummary(): Promise<InvoiceStatusSummary> {
|
||||
export default async function fetchInvoicesStatusSummary(): Promise<InvoiceStatusSummary> {
|
||||
const repo = serverDi(invoiceModuleKey).resolve<InvoiceRepo>(invoiceRepoKey)
|
||||
return repo.fetchInvoicesStatusSummary()
|
||||
}
|
@ -11,7 +11,6 @@ export type RevenueDbResponse = {
|
||||
export default class RevenueDbRepo implements RevenueRepo {
|
||||
async fetchRevenues(): Promise<Revenue[]> {
|
||||
// This is equivalent to in fetch(..., {cache: 'no-store'}).
|
||||
connection()
|
||||
try {
|
||||
// Artificially delay a response for demo purposes.
|
||||
// Don't do this in production :)
|
||||
|
@ -1,9 +1,9 @@
|
||||
import serverDi from "@/feature/common/server-di";
|
||||
import Revenue from "@/feature/core/revenue/domain/entity/revenue";
|
||||
import RevenueRepo from "@/feature/core/revenue/domain/i-repo/revenue-repo";
|
||||
import RevenueRepo, { revenueRepoKey } from "@/feature/core/revenue/domain/i-repo/revenue-repo";
|
||||
import { revenueModuleKey } from "@/feature/core/revenue/domain/revenue-module-key";
|
||||
|
||||
export default function fetchRevenuesUsecase(): Promise<Revenue[]> {
|
||||
const repo = serverDi(revenueModuleKey).resolve<RevenueRepo>(revenueModuleKey)
|
||||
export default async function fetchRevenuesUsecase(): Promise<Revenue[]> {
|
||||
const repo = serverDi(revenueModuleKey).resolve<RevenueRepo>(revenueRepoKey)
|
||||
return repo.fetchRevenues()
|
||||
}
|
@ -2,7 +2,6 @@ import di from "@/bootstrap/di/init-di"
|
||||
import fetchCustomersAmountUsecase from "@/feature/core/customer/domain/usecase/fetch-customers-amount-usecase"
|
||||
import fetchAllInvoicesAmountUsecase from "@/feature/core/invoice/domain/usecase/fetch-all-invoices-amount-usecase"
|
||||
import fetchInvoicesStatusSummary from "@/feature/core/invoice/domain/usecase/fetch-invoices-status-summary"
|
||||
import fetchSummaryInfoUsecase from "@/feature/core/summary-info/domain/usecase/fetch-summary-info-usecase"
|
||||
|
||||
export default function getSummaryInfoDi() {
|
||||
const summaryInfoDi = di.createChildContainer()
|
||||
@ -14,7 +13,7 @@ export default function getSummaryInfoDi() {
|
||||
useValue: fetchCustomersAmountUsecase
|
||||
})
|
||||
summaryInfoDi.register(fetchInvoicesStatusSummary.name, {
|
||||
useValue: fetchSummaryInfoUsecase
|
||||
useValue: fetchInvoicesStatusSummary
|
||||
})
|
||||
return summaryInfoDi
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user