Zlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i
zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7
zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG
z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S
zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr
z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S
zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er
zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa
zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc-
zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V
zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I
zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc
z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E(
zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef
LrJugUA?W`A8`#=m
literal 0
HcmV?d00001
diff --git a/example/nextjs-typescript/public/vercel.svg b/example/nextjs-typescript/public/vercel.svg
new file mode 100644
index 0000000..fbf0e25
--- /dev/null
+++ b/example/nextjs-typescript/public/vercel.svg
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/example/nextjs-typescript/src/@types/auth.type.ts b/example/nextjs-typescript/src/@types/auth.type.ts
new file mode 100644
index 0000000..79712db
--- /dev/null
+++ b/example/nextjs-typescript/src/@types/auth.type.ts
@@ -0,0 +1,4 @@
+export type SdkToken = {
+ expires_at: string;
+ sdk_token: string;
+};
diff --git a/example/nextjs-typescript/src/@types/user.type.ts b/example/nextjs-typescript/src/@types/user.type.ts
new file mode 100644
index 0000000..3688eec
--- /dev/null
+++ b/example/nextjs-typescript/src/@types/user.type.ts
@@ -0,0 +1,8 @@
+export type User = {
+ created_at: string;
+ external_id: string;
+ id: string;
+ name: string;
+ status: string;
+ updated_at: string;
+}
\ No newline at end of file
diff --git a/example/nextjs-typescript/src/config/index.ts b/example/nextjs-typescript/src/config/index.ts
new file mode 100644
index 0000000..b7540e5
--- /dev/null
+++ b/example/nextjs-typescript/src/config/index.ts
@@ -0,0 +1,4 @@
+export const PHYLLO_ENVIRONMENTS = {
+ SANDBOX: 'sandbox',
+ PRODUCTION: 'production'
+};
\ No newline at end of file
diff --git a/example/nextjs-typescript/src/controller/phyllo.ts b/example/nextjs-typescript/src/controller/phyllo.ts
new file mode 100644
index 0000000..4762c0e
--- /dev/null
+++ b/example/nextjs-typescript/src/controller/phyllo.ts
@@ -0,0 +1,112 @@
+import axios from "axios";
+import { SdkToken } from "../@types/auth.type";
+import { User } from "../@types/user.type";
+
+export enum PHYLLO_FLOW_TYPES {
+ POPUP = "POPUP",
+ REDIRECT = "REDIRECT",
+}
+
+type PHYLLO_INTIALIZE_PROPS = {
+ flowType: PHYLLO_FLOW_TYPES;
+ clientDisplayName: string;
+ workPlatformId?: string;
+ userId: string;
+};
+
+export class PhylloController {
+ private createConfig = async (
+ userId: string,
+ clientDisplayName: string,
+ workPlatformId?: string,
+ flowType: string
+ ) => {
+ //creating user
+ const user: User = await axios
+ .post("/api/users", { name: "Phyllo", externalId: userId })
+ .then((r) => r.data)
+ .catch(async (e) => {
+ if (e.response.data.error_code == "user_exists_with_external_id") {
+ return await axios
+ .get("/api/users/", { params: { externalId: userId } })
+ .then((r) => r.data);
+ }
+ });
+
+ //creating a token
+ const token: SdkToken = await axios
+ .post("/api/sdk-token", { userId: user.id })
+ .then((r) => r.data)
+ .catch((e) => {
+ throw new Error("Unable to create sdk token");
+ });
+
+ console.log(flowType, "Flow type")
+ return {
+ clientDisplayName: clientDisplayName,
+ environment: process.env.NEXT_PUBLIC_ENV,
+ userId: user.id,
+ token: token.sdk_token,
+ ...(flowType === PHYLLO_FLOW_TYPES.REDIRECT && { redirectURL: process.env.NEXT_PUBLIC_REDIRECT_URL }),
+ redirect: flowType === PHYLLO_FLOW_TYPES.POPUP ? false : true,
+ workPlatformId: workPlatformId,
+ };
+ };
+
+ public initialize = async ({
+ flowType,
+ clientDisplayName,
+ workPlatformId,
+ userId,
+ }: PHYLLO_INTIALIZE_PROPS) => {
+ const config = await this.createConfig(
+ userId,
+ clientDisplayName,
+ workPlatformId,
+ flowType
+ );
+
+ console.log(config)
+
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore
+ const phylloConnect = PhylloConnect.initialize(config);
+ if(flowType === PHYLLO_FLOW_TYPES.POPUP){
+ this.registerCallbacks(phylloConnect);
+ }
+ phylloConnect.open();
+ };
+
+ private registerCallbacks = (handler: any) => {
+ handler.on(
+ "accountConnected",
+ (accountId: string, workplatformId: string, userId: string) => {
+ // gives the successfully connected account ID and work platform ID for the given user ID
+ console.log(
+ `onAccountConnected: ${accountId}, ${workplatformId}, ${userId}`
+ );
+ }
+ );
+ handler.on(
+ "accountDisconnected",
+ (accountId: string, workplatformId: string, userId: string) => {
+ // gives the successfully disconnected account ID and work platform ID for the given user ID
+ console.log(
+ `onAccountDisconnected: ${accountId}, ${workplatformId}, ${userId}`
+ );
+ }
+ );
+ handler.on("tokenExpired", (userId: string) => {
+ // gives the user ID for which the token has expired
+ console.log(`onTokenExpired: ${userId}`); // the SDK closes automatically in case the token has expired, and you need to handle this by showing an appropriate UI and messaging to the users
+ });
+ handler.on("exit", (reason: string, userId: string) => {
+ // indicated that the user with given user ID has closed the SDK and gives an appropriate reason for it
+ console.log(`onExit: ${reason}, ${userId}`);
+ });
+ };
+
+ public fetchWorkPlatforms = async () => {
+ return await axios.get("/api/work-platforms").then(r=>r.data);
+ };
+}
diff --git a/example/nextjs-typescript/src/pages/_app.tsx b/example/nextjs-typescript/src/pages/_app.tsx
new file mode 100644
index 0000000..3f5c9d5
--- /dev/null
+++ b/example/nextjs-typescript/src/pages/_app.tsx
@@ -0,0 +1,8 @@
+import '../styles/globals.css'
+import type { AppProps } from 'next/app'
+
+function MyApp({ Component, pageProps }: AppProps) {
+ return
+}
+
+export default MyApp
diff --git a/example/nextjs-typescript/src/pages/api/sdk-token.ts b/example/nextjs-typescript/src/pages/api/sdk-token.ts
new file mode 100644
index 0000000..0e23ff9
--- /dev/null
+++ b/example/nextjs-typescript/src/pages/api/sdk-token.ts
@@ -0,0 +1,16 @@
+import type { NextApiRequest, NextApiResponse } from "next";
+import { SdkToken } from "../../@types/auth.type";
+import { BaseApi } from "../../repository/api";
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ const { userId } = req.body;
+ const apiCient = new BaseApi();
+ const workPlatforms = await apiCient.postRequest("/sdk-tokens", {
+ products: ["IDENTITY", "ENGAGEMENT"],
+ user_id: userId,
+ });
+ res.status(200).json({ ...workPlatforms });
+}
diff --git a/example/nextjs-typescript/src/pages/api/users/index.ts b/example/nextjs-typescript/src/pages/api/users/index.ts
new file mode 100644
index 0000000..ee7f2e6
--- /dev/null
+++ b/example/nextjs-typescript/src/pages/api/users/index.ts
@@ -0,0 +1,33 @@
+import axios from "axios";
+import type { NextApiRequest, NextApiResponse } from "next";
+import { User } from "../../../@types/user.type";
+import { BaseApi } from "../../../repository/api";
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ const apiCient = new BaseApi();
+ switch (req.method) {
+ case "POST": {
+ const { name, externalId } = req.body;
+ apiCient
+ .postRequest(`/users`, {
+ name: name,
+ external_id: externalId,
+ })
+ .then((r) => res.status(200).json({ ...r }))
+ .catch((e) => {
+ res.status(400).json(e);
+ });
+ break;
+ }
+ case "GET": {
+ const { externalId } = req.query;
+ const user = await apiCient.getRequest(
+ `/users/external_id/${externalId}`
+ );
+ res.status(200).json({ ...user });
+ }
+ }
+}
diff --git a/example/nextjs-typescript/src/pages/api/work-platforms/[id].ts b/example/nextjs-typescript/src/pages/api/work-platforms/[id].ts
new file mode 100644
index 0000000..cb0ea1e
--- /dev/null
+++ b/example/nextjs-typescript/src/pages/api/work-platforms/[id].ts
@@ -0,0 +1,14 @@
+import type { NextApiRequest, NextApiResponse } from "next";
+import { BaseApi } from "../../../repository/api";
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ const workPlatformId = req.query.id;
+ const apiCient = new BaseApi();
+ const workPlatforms = await apiCient.getRequest(
+ `/work-platforms/${workPlatformId}`
+ );
+ res.status(200).json({ ...workPlatforms });
+}
diff --git a/example/nextjs-typescript/src/pages/api/work-platforms/index.ts b/example/nextjs-typescript/src/pages/api/work-platforms/index.ts
new file mode 100644
index 0000000..6dc9184
--- /dev/null
+++ b/example/nextjs-typescript/src/pages/api/work-platforms/index.ts
@@ -0,0 +1,14 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+import type { NextApiRequest, NextApiResponse } from 'next'
+import { BaseApi } from '../../../repository/api'
+
+
+
+export default async function handler(
+ req: NextApiRequest,
+ res: NextApiResponse
+) {
+ const apiCient = new BaseApi();
+ const workPlatforms = await apiCient.getRequest('/work-platforms');
+ res.status(200).json({ ...workPlatforms })
+}
diff --git a/example/nextjs-typescript/src/pages/index.tsx b/example/nextjs-typescript/src/pages/index.tsx
new file mode 100644
index 0000000..e4114e0
--- /dev/null
+++ b/example/nextjs-typescript/src/pages/index.tsx
@@ -0,0 +1,71 @@
+import type { NextPage } from 'next'
+import Head from 'next/head'
+import { useEffect, useState } from 'react';
+import { PhylloController, PHYLLO_FLOW_TYPES } from '../controller/phyllo'
+
+const Home: NextPage = () => {
+
+ const [workPlatforms, setWorkPlatforms] = useState([]);
+
+ const phylloController = new PhylloController();
+
+
+ const fetchWorkPlatforms = () => {
+ phylloController.fetchWorkPlatforms().then((r => {
+ setWorkPlatforms(r.data);
+ }));
+ }
+
+
+ const initializeAllWorkPlatforms = (workPlatformId: string = '') => {
+
+ phylloController.initialize({
+ flowType: document.querySelector('input[name="flow-type"]:checked')?.value,
+ clientDisplayName: 'Jelly',
+ workPlatformId: workPlatformId,
+ userId: Math.random().toString()
+ });
+ }
+
+
+ useEffect(() => {
+ fetchWorkPlatforms();
+ }, [])
+
+ return (
+
+
+ NextJs - Phyllo sample app
+
+
+
+
+
+
+
+
+ Phyllo Sample App - NextJs
+
+
+
+
+ )
+}
+
+export default Home
diff --git a/example/nextjs-typescript/src/repository/api.ts b/example/nextjs-typescript/src/repository/api.ts
new file mode 100644
index 0000000..f39c19a
--- /dev/null
+++ b/example/nextjs-typescript/src/repository/api.ts
@@ -0,0 +1,43 @@
+import axios, { AxiosInstance } from "axios";
+import { PHYLLO_ENVIRONMENTS } from "../config";
+
+export class BaseApi {
+ private api: AxiosInstance;
+ private environment = process.env.NEXT_PUBLIC_ENV;
+
+ constructor() {
+ this.api = axios.create({
+ baseURL: this.getApiUrl(),
+ auth: {
+ username: process.env.PHYLLO_CLIENT_ID ?? "",
+ password: process.env.PHYLLO_SECRET_ID ?? "",
+ },
+ });
+ }
+
+ public getApiUrl = () => {
+ if (this.environment == PHYLLO_ENVIRONMENTS.SANDBOX) {
+ return "https://api.sandbox.getphyllo.com/v1";
+ } else if (this.environment == PHYLLO_ENVIRONMENTS.PRODUCTION) {
+ return "https://api.getphyllo.com/v1";
+ }
+ };
+
+ public getRequest = async (url: string, params?: object) => {
+ try {
+ const response = await this.api.get(url, { params: params });
+ return response.data;
+ } catch (error) {
+ throw error.response.data.error;
+ }
+ };
+
+ public postRequest = async (url: string, data: object) => {
+ try {
+ const response = await this.api.post(url, { ...data });
+ return response.data;
+ } catch (error) {
+ throw error.response.data.error;
+ }
+ };
+}
diff --git a/example/nextjs-typescript/src/styles/globals.css b/example/nextjs-typescript/src/styles/globals.css
new file mode 100644
index 0000000..faf391a
--- /dev/null
+++ b/example/nextjs-typescript/src/styles/globals.css
@@ -0,0 +1,79 @@
+*{
+ margin: 0;
+ padding: 0;
+}
+body{
+ font-family: 'Inter', sans-serif;;
+}
+.screen_box{
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%,-50%);
+ width:420px;
+ height: auto;
+ background-color:#fff;
+ box-shadow: 0px 18px 36px -18px rgba(0, 0, 0, 0.3), 0px 30px 59.9999px -12px rgba(50, 50, 93, 0.25);
+ border-radius: 10px;
+}
+.top_navbar{
+ background-color: #524fa1;
+ color: #fff;
+ padding: 0.75rem 1.25rem;
+ border-radius: 0px;
+ font-size: 14px;
+}
+.content_text_box{
+ height: 600px;
+ position: relative;
+ margin: 0px 2rem;
+}
+.content_data{
+ width: 100%;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%,-50%);
+}
+.btn_group{
+ display: flex;
+ flex-direction: column;
+ overflow: scroll;
+ max-height: 500px;
+ gap: 30px;
+}
+
+.platform-icon{
+ height: 20px;
+ width: 20px;
+}
+
+
+.btn_group button{
+ outline: none;
+ border-style: none;
+ padding: 1rem;
+ font-size: 16px;
+ font-weight:bold;
+ letter-spacing: 1px;
+ color: #fff;
+ background-color: #524fa1;
+ border-radius: 5px;
+}
+.check_box{
+ display: flex;
+ align-items: center;
+ font-size: 15px;
+ font-weight: bold;
+}
+.check_box input{
+ width: 20px;
+ height: 20px;
+ margin-right: 10px;
+}
+@media (max-width: 450px) {
+ .screen_box{
+ width: 100%;
+ height: 100%;
+ }
+}
\ No newline at end of file
diff --git a/example/nextjs-typescript/tsconfig.json b/example/nextjs-typescript/tsconfig.json
new file mode 100644
index 0000000..99710e8
--- /dev/null
+++ b/example/nextjs-typescript/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/index.html b/index.html
index 415070b..86eed51 100644
--- a/index.html
+++ b/index.html
@@ -5,7 +5,7 @@
-
+
From facec190937fb926078bee80b5349e7422896d1a Mon Sep 17 00:00:00 2001
From: admin-mybytecode <45875826+mybytecode@users.noreply.github.com>
Date: Sun, 10 Apr 2022 22:37:20 +0530
Subject: [PATCH 2/3] untracking .env
---
example/nextjs-typescript/.env | 7 -------
example/nextjs-typescript/.gitignore | 2 ++
2 files changed, 2 insertions(+), 7 deletions(-)
delete mode 100644 example/nextjs-typescript/.env
diff --git a/example/nextjs-typescript/.env b/example/nextjs-typescript/.env
deleted file mode 100644
index ef66fe9..0000000
--- a/example/nextjs-typescript/.env
+++ /dev/null
@@ -1,7 +0,0 @@
-PHYLLO_CLIENT_ID=bde0466a-1b46-4ac8-bfff-326a39b2eae2
-
-PHYLLO_SECRET_ID=ceaed0ed-d2ba-4688-9872-2bba24dfbd43
-
-
-NEXT_PUBLIC_ENV=sandbox
-NEXT_PUBLIC_REDIRECT_URL=http://google.com
\ No newline at end of file
diff --git a/example/nextjs-typescript/.gitignore b/example/nextjs-typescript/.gitignore
index 737d872..1804805 100644
--- a/example/nextjs-typescript/.gitignore
+++ b/example/nextjs-typescript/.gitignore
@@ -28,6 +28,8 @@ yarn-error.log*
# local env files
.env*.local
+.env
+
# vercel
.vercel
From 4f9b5802e20379d21b55dd546675716086cf5e61 Mon Sep 17 00:00:00 2001
From: admin-mybytecode <45875826+mybytecode@users.noreply.github.com>
Date: Sun, 10 Apr 2022 22:38:12 +0530
Subject: [PATCH 3/3] Create .env.example
---
example/nextjs-typescript/.env.example | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 example/nextjs-typescript/.env.example
diff --git a/example/nextjs-typescript/.env.example b/example/nextjs-typescript/.env.example
new file mode 100644
index 0000000..9cab995
--- /dev/null
+++ b/example/nextjs-typescript/.env.example
@@ -0,0 +1,5 @@
+PHYLLO_CLIENT_ID=
+PHYLLO_SECRET_ID=
+
+NEXT_PUBLIC_ENV=
+NEXT_PUBLIC_REDIRECT_URL=
\ No newline at end of file
|