Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed May 20, 2024
1 parent fb3408b commit 7bf0332
Show file tree
Hide file tree
Showing 23 changed files with 474 additions and 324 deletions.
3 changes: 1 addition & 2 deletions apps/dashboard/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
## Dashboard
##
## Dashboard
1 change: 0 additions & 1 deletion apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
"@zip.js/zip.js": "2.7.44",
"ai": "^3.1.12",
"change-case": "^5.4.4",
"currency-symbol-map": "^5.1.0",
"dub": "^0.25.2",
"framer-motion": "^11.2.4",
"geist": "^1.3.0",
Expand Down
53 changes: 53 additions & 0 deletions apps/dashboard/src/actions/create-bank-account-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use server";

// import { LogEvents } from "@midday/events/events";
// import { setupLogSnag } from "@midday/events/server";
import { getUser } from "@midday/supabase/cached-queries";
import { createClient } from "@midday/supabase/server";
import { nanoid } from "nanoid";
import { revalidateTag } from "next/cache";
import { action } from "./safe-action";
import { createBankAccountSchema } from "./schema";

export const createBankAccountAction = action(
createBankAccountSchema,
async ({ name, currency }) => {
const supabase = createClient();
const user = await getUser();
const teamId = user?.data?.team_id;

const { data, error } = await supabase
.from("decrypted_bank_accounts")
.insert({
name,
currency,
team_id: teamId,
created_by: user?.data?.id,
enabled: true,
account_id: nanoid(),
manual: true,
})
.select("id, name:decrypted_name")
.single();

if (error) {
throw Error(error.message);
}

revalidateTag(`bank_accounts_${teamId}`);
revalidateTag(`bank_accounts_currencies_${teamId}`);

// const logsnag = await setupLogSnag({
// userId: user.data.id,
// fullName: user.data.full_name,
// });

// logsnag.track({
// event: LogEvents.CategoryCreate.name,
// icon: LogEvents.CategoryCreate.icon,
// channel: LogEvents.CategoryCreate.channel,
// });

return data;
}
);
22 changes: 22 additions & 0 deletions apps/dashboard/src/actions/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,25 @@ export const inboxOrder = z.boolean();
export const getVatRateSchema = z.object({
name: z.string().min(2),
});

export const createBankAccountSchema = z.object({
name: z.string(),
currency: z.string().optional(),
});

export const createTransactionsSchema = z.object({
accountId: z.string().uuid(),
currency: z.string(),
transactions: z.array(
z.object({
id: z.string(),
description: z.string(),
amount: z.number(),
currency: z.string(),
})
),
});

export type CreateTransactionsFormValues = z.infer<
typeof createTransactionsSchema
>;
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@ import { SelectBankAccountsModal } from "@/components/modals/select-bank-account
import { Sidebar } from "@/components/sidebar";
import { Cookies } from "@/utils/constants";
import { getCountryCode, isEUCountry } from "@midday/location";
import { currencies } from "@midday/location/src/currencies";
import { getUser } from "@midday/supabase/cached-queries";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

const uniqueCurrencies = () => {
const uniqueSet = new Set(Object.values(currencies));
return [...uniqueSet];
};

export default async function Layout({
children,
}: {
Expand Down Expand Up @@ -45,7 +51,10 @@ export default async function Layout({
<ConnectTransactionsModal isEU={isEU} />
<ConnectGoCardLessModal countryCode={countryCode} />
<SelectBankAccountsModal countryCode={countryCode} />
<ImportCSVModal />
<ImportCSVModal
currencies={uniqueCurrencies()}
defaultCurrency={currencies[countryCode]}
/>
<ExportStatus />
<CommandMenu />
<HotKeys />
Expand Down
7 changes: 3 additions & 4 deletions apps/dashboard/src/components/chart-currency.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { getBankAccountsCurrencies } from "@midday/supabase/cached-queries";
import getSymbolFromCurrency from "currency-symbol-map";
import { SelectCurrency } from "./select-currency";
import { SelectChartCurrency } from "./select-chart-currency";

type Props = {
defaultValue?: string;
Expand All @@ -15,12 +14,12 @@ export async function ChartCurrency({ defaultValue }: Props) {
}

return (
<SelectCurrency
<SelectChartCurrency
defaultValue={defaultValue}
currencies={
currencies?.data?.map(({ currency }) => ({
id: currency,
label: `${currency} ${getSymbolFromCurrency(currency)}`,
label: currency,
})) ?? []
}
/>
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/connect-bank-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function ConnectBankButton() {
data-channel="bank"
onClick={() => setStep("connect")}
>
Connect bank
Connect account
</Button>
);
}
142 changes: 142 additions & 0 deletions apps/dashboard/src/components/forms/import-transactions-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
"use client";

import {
type CreateTransactionsFormValues,
createTransactionsSchema,
} from "@/actions/schema";
import { FormatAmount } from "@/components/format-amount";
import { SelectAccount } from "@/components/select-account";
import { SelectCurrency } from "@/components/select-currency";
import { formatTransactionDate } from "@/utils/format";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@midday/ui/button";
import { cn } from "@midday/ui/cn";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormMessage,
} from "@midday/ui/form";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@midday/ui/table";
import { useForm } from "react-hook-form";

type Props = {
defaultCurrency: string;
};

export function ImportTransactionsForm({
currencies,
defaultCurrency,
transactions,
}: Props) {
const form = useForm<CreateTransactionsFormValues>({
resolver: zodResolver(createTransactionsSchema),
defaultValues: {
accountId: undefined,
currency: defaultCurrency,
},
});

const onSubmit = form.handleSubmit((data) => {});

return (
<Form {...form}>
<form onSubmit={onSubmit}>
<div className="flex space-x-2">
<FormField
control={form.control}
name="accountId"
render={({ field }) => (
<FormItem className="w-full">
<FormControl>
<SelectAccount
className="w-full"
placeholder="Select account"
{...field}
/>
</FormControl>
<FormDescription>
Select or create a new account.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="currency"
render={({ field }) => (
<FormItem className="w-full">
<FormControl>
<SelectCurrency
className="w-full"
{...field}
currencies={Object.values(currencies)?.map(
(currency) => currency
)}
/>
</FormControl>
<FormDescription>
Select the currency for your transactions.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
</div>

<div className="h-[480px] overflow-auto mt-8 mb-4">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[80px]">Date</TableHead>
<TableHead>Description</TableHead>
<TableHead className="text-right">Amount</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{transactions?.map((transaction) => (
<TableRow key={transaction.internal_id} className="h-[45px]">
<TableCell>
{transaction?.date &&
formatTransactionDate(transaction.date)}
</TableCell>
<TableCell
className={transaction.amount > 0 && "text-[#00C969]"}
>
{transaction.name}
</TableCell>
<TableCell
className={cn(
"text-right",
transaction.amount > 0 && "text-[#00C969]"
)}
>
<FormatAmount
amount={transaction.amount}
currency={form.watch("currency")}
/>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>

<div className="w-full absolute bottom-0 left-0 h-[150px] flex flex-col justify-end pointer-events-none bg-gradient-to-b from-transparent via-background to-background">
<Button className="w-full">Save</Button>
</div>
</form>
</Form>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export function TrackerProjectForm({ onSubmit, isSaving, form }) {
<FormLabel>Hourly Rate</FormLabel>
<FormControl>
<CurrencyInput
className="flex h-9 w-full rounded-md border border bg-transparent px-3 py-2 text-sm focus-visible:outline-none"
className="flex h-9 w-full rounded-md border bg-transparent px-3 py-2 text-sm focus-visible:outline-none"
onValueChange={(values) => {
field.onChange(values.floatValue);
}}
Expand Down
Loading

0 comments on commit 7bf0332

Please sign in to comment.