Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed Mar 6, 2024
1 parent 715e5ab commit e0cb34a
Show file tree
Hide file tree
Showing 34 changed files with 258 additions and 156 deletions.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
3 changes: 3 additions & 0 deletions apps/dashboard/src/actions/banks/get-accounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type GetAccountParams = {
id: string;
countryCode?: string;
accessToken?: string;
institutionId?: string; // Plaid
provider: "gocardless" | "teller" | "plaid";
};

Expand All @@ -14,13 +15,15 @@ export async function getAccounts({
countryCode,
provider,
accessToken,
institutionId,
}: GetAccountParams) {
const api = new Provider({ provider });

const data = await api.getAccounts({
id,
countryCode,
accessToken,
institutionId,
});

return data;
Expand Down
23 changes: 21 additions & 2 deletions apps/dashboard/src/app/api/plaid/create-link-token/route.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
export async function POST(req: Request) {
return Response.json({ success: true });
import { PlaidApi } from "@midday/providers/src/plaid/plaid-api";
import { createClient } from "@midday/supabase/server";
import { NextResponse } from "next/server";

export async function POST() {
try {
const supabase = createClient();
const api = new PlaidApi();

const {
data: { session },
} = await supabase.auth.getSession();

const response = await api.linkTokenCreate({
userId: session.user.id,
});

return NextResponse.json(response.data);
} catch (error) {
// handle error
}
}
17 changes: 17 additions & 0 deletions apps/dashboard/src/app/api/plaid/exchange-public-token/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { PlaidApi } from "@midday/providers/src/plaid/plaid-api";
import { NextResponse } from "next/server";

export async function POST(req: Request) {
try {
const res = await req.json();
const api = new PlaidApi();

const response = await api.itemPublicTokenExchange({
publicToken: res.public_token,
});

return NextResponse.json(response.data);
} catch (error) {
// handle error
}
}
3 changes: 0 additions & 3 deletions apps/dashboard/src/app/api/plaid/set-access-token/route.ts

This file was deleted.

8 changes: 4 additions & 4 deletions apps/dashboard/src/components/empty-state-invoice/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import { cn } from "@midday/ui/utils";
import Image from "next/image";
import Invoice1Light from "public/assets/invoice-1-light.png";
import Invoice1 from "public/assets/invoice-1.png";
import Invoice2Light from "public/assets/invoice-2-light.png";
import Invoice2 from "public/assets/invoice-2.png";
import { Fragment, useState } from "react";
import Invoice1Light from "./invoice-1-light.png";
import Invoice1 from "./invoice-1.png";
import Invoice2Light from "./invoice-2-light.png";
import Invoice2 from "./invoice-2.png";

const images = [
{ id: 1, src: Invoice1, src2: Invoice1Light },
Expand Down
93 changes: 57 additions & 36 deletions apps/dashboard/src/components/modals/connect-transactions-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ import {
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@midday/ui/tabs";
import Image from "next/image";
import { parseAsString, parseAsStringEnum, useQueryStates } from "nuqs";
import CsvLogo from "public/assets/csv.png";
import GoCardLessLogo from "public/assets/gocardless.png";
import PlaidLogo from "public/assets/plaid.png";
import TellerLogo from "public/assets/teller.png";
import ZapierLogo from "public/assets/zapier.png";
import { useEffect, useState } from "react";
import { usePlaidLink } from "react-plaid-link";
import { TellerConnectOptions, useTellerConnect } from "teller-connect-react";
import CsvLogo from "./csv.png";
import GoCardLessLogo from "./gocardless.png";
import PlaidLogo from "./plaid.png";
import TellerLogo from "./teller.png";
import ZapierLogo from "./zapier.png";

const imports = [
{
Expand All @@ -42,13 +43,15 @@ const imports = [

export function ConnectTransactionsModal() {
const { track } = useLogSnag();
const [token, setToken] = useState();

const [params, setParams] = useQueryStates(
{
step: parseAsStringEnum(["connect", "account", "gocardless"]),
ref: parseAsString,
token: parseAsString,
enrollment_id: parseAsString,
institution_id: parseAsString,
provider: parseAsStringEnum(["teller", "plaid", "gocardless"]),
},
{
Expand All @@ -58,25 +61,25 @@ export function ConnectTransactionsModal() {

const isOpen = params.step === "connect";

useEffect(() => {
async function createLinkToken() {
const response = await fetch("/api/plaid/create-link-token", {
method: "POST",
});
const { link_token } = await response.json();
setToken(link_token);
}

if (isOpen) {
createLinkToken();
}
}, [isOpen]);

const { open: openTeller, ready: tellerReady } = useTellerConnect({
applicationId: process.env.NEXT_PUBLIC_TELLER_APPLICATION_ID!,
environment: process.env
.NEXT_PUBLIC_TELLER_ENVIRONMENT as TellerConnectOptions["environment"],
appearance: "system",
onExit: () => {
setParams({ step: "connect" });

track({
event: LogEvents.ConnectBankCanceled.name,
icon: LogEvents.ConnectBankCanceled.icon,
channel: LogEvents.ConnectBankCanceled.channel,
tags: {
provider: "teller",
},
});

setParams({ step: "connect" });
},
onSuccess: (authorization) => {
setParams({
step: "account",
Expand All @@ -94,21 +97,45 @@ export function ConnectTransactionsModal() {
},
});
},
onExit: () => {
setParams({ step: "connect" });

track({
event: LogEvents.ConnectBankCanceled.name,
icon: LogEvents.ConnectBankCanceled.icon,
channel: LogEvents.ConnectBankCanceled.channel,
tags: {
provider: "teller",
},
});

setParams({ step: "connect" });
},
onFailure: () => {
setParams({ step: "connect" });
},
});

const { open: openPlaid, ready: plaidReady } = usePlaidLink({
token: "",
token,
publicKey: process.env.NEXT_PUBLIC_PLAID_PUBLIC_KEY!,
env: process.env.NEXT_PUBLIC_PLAID_ENVIRONMENT!,
clientName: "Midday",
product: ["transactions"],
onSuccess: (public_token, metadata) => {
console.log(public_token, metadata);
onSuccess: async (public_token, metadata) => {
const response = await fetch("/api/plaid/exchange-public-token", {
method: "POST",
body: JSON.stringify({ public_token }),
});

setParams({ step: "account" });
const { access_token } = await response.json();

setParams({
step: "account",
provider: "plaid",
token: access_token,
institution_id: metadata.institution?.institution_id,
});

track({
event: LogEvents.ConnectBankAuthorized.name,
Expand Down Expand Up @@ -136,7 +163,7 @@ export function ConnectTransactionsModal() {
const banks = [
{
id: "gocardless",
name: "GoCardless (Europe)",
name: "GoCardless (EU, UK)",
description:
"More than 2,500 connected banks in 31 countries across the UK and Europe.",
logo: GoCardLessLogo,
Expand Down Expand Up @@ -176,7 +203,7 @@ export function ConnectTransactionsModal() {
},
{
id: "plaid",
name: "Plaid (US, Canada, UK)",
name: "Plaid (US, Canada, UK, EU)",
description: `12,000+ financial institutions across the US, Canada, UK, and Europe are covered by Plaid's network`,
logo: PlaidLogo,
onClick: () => {
Expand All @@ -190,8 +217,9 @@ export function ConnectTransactionsModal() {
});

openPlaid();
setParams({ step: null });
},
disabled: !plaidReady,
disabled: !plaidReady || !token,
},
];

Expand Down Expand Up @@ -251,17 +279,10 @@ export function ConnectTransactionsModal() {
/>

<CardHeader className="p-4 pl-2">
<div className="flex space-x-2">
<CardTitle className="text-md mb-0">
{bank.name}
</CardTitle>
<CardTitle className="text-md mb-0">
{bank.name}
</CardTitle>

{bank.disabled && (
<div className="text-[#878787] rounded-md py-1 px-2 border text-[10px]">
Coming soon
</div>
)}
</div>
<CardDescription className="text-sm">
{bank.description}
</CardDescription>
Expand Down
8 changes: 4 additions & 4 deletions apps/dashboard/src/components/modals/overview-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { ConnectBankButton } from "@/components/connect-bank-button";
import { cn } from "@midday/ui/utils";
import Image from "next/image";
import { useQueryState } from "nuqs";
import OverViewScreenOneLight from "public/assets/overview-1-light.png";
import OverViewScreenOne from "public/assets/overview-1.png";
import OverViewScreenTwoLight from "public/assets/overview-2-light.png";
import OverViewScreenTwo from "public/assets/overview-2.png";
import { Fragment, useState } from "react";
import OverViewScreenOneLight from "./overview-1-light.png";
import OverViewScreenOne from "./overview-1.png";
import OverViewScreenTwoLight from "./overview-2-light.png";
import OverViewScreenTwo from "./overview-2.png";

const images = [
{ id: 1, src: OverViewScreenOne, src2: OverViewScreenOneLight },
Expand Down
24 changes: 15 additions & 9 deletions apps/dashboard/src/components/modals/select-bank-accounts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,13 @@ export function SelectBankAccountsModal({ countryCode }) {
ref: parseAsString,
token: parseAsString,
enrollment_id: parseAsString,
institution_id: parseAsString,
provider: parseAsStringEnum(["teller", "plaid", "gocardless"]),
});

const { provider, step, error, token, ref, enrollment_id } = params;
const { provider, step, error, token, ref, enrollment_id, institution_id } =
params;

const isOpen = step === "account" && !error;

const onClose = () => {
Expand Down Expand Up @@ -119,6 +122,7 @@ export function SelectBankAccountsModal({ countryCode }) {
id: ref,
countryCode,
accessToken: token,
institutionId: institution_id,
});

setAccounts(data);
Expand All @@ -137,7 +141,7 @@ export function SelectBankAccountsModal({ countryCode }) {
name: account.name,
institution_id: account.institution.id,
logo_url: account.institution?.logo,
enabled: true,
enabled: false,
})),
});
}
Expand Down Expand Up @@ -171,7 +175,7 @@ export function SelectBankAccountsModal({ countryCode }) {
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-6"
className="space-y-6 max-h-[320px] overflow-auto pb-[60px] relative scrollbar-hide"
>
{loading && <RowsSkeleton />}

Expand All @@ -186,15 +190,15 @@ export function SelectBankAccountsModal({ countryCode }) {
key={account.id}
className="flex justify-between"
>
<FormLabel className="flex items-between">
<Image
<FormLabel className="flex items-between space-x-4">
{/* <Image
src={account.institution?.logo}
alt={account?.institution?.name}
width={34}
height={34}
className="rounded-full overflow-hidden border"
/>
<div className="ml-4 space-y-1">
/> */}
<div className="space-y-1">
<p className="text-sm font-medium leading-none mb-1">
{account.name}
</p>
Expand Down Expand Up @@ -237,11 +241,13 @@ export function SelectBankAccountsModal({ countryCode }) {
/>
))}

<div className="pt-4">
<div className="fixed bottom-6 left-6 right-6 z-10 bg-background pt-4">
<Button
className="w-full"
type="submit"
disabled={connectBankAction.status === "executing"}
// disabled={connectBankAction.status === "executing"}
// Check for atleast one enabled account
disabled
>
{connectBankAction.status === "executing" ? (
<Loader2 className="w-4 h-4 animate-spin pointer-events-none" />
Expand Down
8 changes: 4 additions & 4 deletions apps/dashboard/src/components/modals/transactions-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import { ConnectBankButton } from "@/components/connect-bank-button";
import { cn } from "@midday/ui/utils";
import Image from "next/image";
import { useQueryState } from "nuqs";
import TransactionsScreenOneLight from "public/assets/transactions-1-light.png";
import TransactionsScreenOne from "public/assets/transactions-1.png";
import TransactionsScreenTwoLight from "public/assets/transactions-2-light.png";
import TransactionsScreenTwo from "public/assets/transactions-2.png";
import { Fragment, useState } from "react";
import TransactionsScreenOneLight from "./transactions-1-light.png";
import TransactionsScreenOne from "./transactions-1.png";
import TransactionsScreenTwoLight from "./transactions-2-light.png";
import TransactionsScreenTwo from "./transactions-2.png";

const images = [
{ id: 1, src: TransactionsScreenOne, src2: TransactionsScreenOneLight },
Expand Down
1 change: 0 additions & 1 deletion packages/providers/src/plaid/index.ts

This file was deleted.

Loading

0 comments on commit e0cb34a

Please sign in to comment.