Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Components - teach_n_go #14331

Merged
merged 4 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions components/teach_n_go/actions/create-prospect/create-prospect.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import app from "../../teach_n_go.app.mjs";

export default {
key: "teach_n_go-create-prospect",
name: "Create Prospect",
description: "Creates a new prospect inside Teach 'n Go. [See the documentation](https://intercom.help/teach-n-go/en/articles/5750592-prospect-registration-api)",
version: "0.0.1",
type: "action",
props: {
app,
firstName: {
propDefinition: [
app,
"firstName",
],
},
lastName: {
propDefinition: [
app,
"lastName",
],
},
mobilePhone: {
type: "integer",
label: "Mobile Phone",
description: "The prospect's contact number.",
optional: true,
},
Comment on lines +24 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Change mobilePhone type from integer to string

Phone numbers may include characters like '+', '-', or have leading zeros, which are not supported by the integer type. It's recommended to use type: "string" for mobilePhone to accurately capture the prospect's contact number.

Apply this diff to fix the issue:

 mobilePhone: {
-  type: "integer",
+  type: "string",
   label: "Mobile Phone",
   description: "The prospect's contact number.",
   optional: true,
 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type: "integer",
label: "Mobile Phone",
description: "The prospect's contact number.",
optional: true,
},
mobilePhone: {
type: "string",
label: "Mobile Phone",
description: "The prospect's contact number.",
optional: true,
},

emailAddress: {
propDefinition: [
app,
"emailAddress",
],
optional: true,
},
description: {
type: "string",
label: "Description",
description: "General information you wish to capture.",
optional: true,
},
gender: {
propDefinition: [
app,
"gender",
],
optional: true,
},
dateOfBirth: {
propDefinition: [
app,
"dateOfBirth",
],
optional: true,
},
courseSubject: {
type: "string",
label: "Course Subject",
description: "The students chosen subject.",
optional: true,
},
courseLevel: {
type: "string",
label: "Course Level",
description: "The students chosen level.",
optional: true,
},
Comment on lines +11 to +67
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consistency in using propDefinition for property definitions

Some properties like mobilePhone, description, courseSubject, and courseLevel are defined directly, while others use propDefinition. For consistency and maintainability, consider using propDefinition for all properties where possible.

If these properties have common definitions elsewhere in the codebase, you can define them using propDefinition:

 mobilePhone: {
-  type: "string",
-  label: "Mobile Phone",
-  description: "The prospect's contact number.",
-  optional: true,
+  propDefinition: [
+    app,
+    "mobilePhone",
+  ],
 },
 description: {
-  type: "string",
-  label: "Description",
-  description: "General information you wish to capture.",
-  optional: true,
+  propDefinition: [
+    app,
+    "description",
+  ],
 },
 courseSubject: {
-  type: "string",
-  label: "Course Subject",
-  description: "The student's chosen subject.",
-  optional: true,
+  propDefinition: [
+    app,
+    "courseSubject",
+  ],
 },
 courseLevel: {
-  type: "string",
-  label: "Course Level",
-  description: "The student's chosen level.",
-  optional: true,
+  propDefinition: [
+    app,
+    "courseLevel",
+  ],
 },

This helps in maintaining consistency and reusability across the codebase.

Committable suggestion was skipped due to low confidence.

},
async run({ $ }) {
const response = await this.app.createProspect({
$,
data: {
"fname": this.firstName,
"lname": this.lastName,
"mobile_phone": this.mobilePhone,
"email_address": this.emailAddress,
"description": this.description,
"gender": this.gender,
"date_of_birth": this.dateOfBirth,
"course_subject": this.courseSubject,
"course_level": this.courseLevel,
},
});
$.export("$summary", `Successfully created prospect with ID: ${response.data.id}`);
return response;
},
Comment on lines +70 to +86
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for the API call in the run method

Currently, if the createProspect API call fails, the error is not handled, which may lead to unhandled promise rejections or obscure errors. It's advisable to wrap the API call in a try-catch block to handle potential errors gracefully.

Refactor the run method to include error handling:

 async run({ $ }) {
+  try {
     const response = await this.app.createProspect({
       $,
       data: {
         "fname": this.firstName,
         "lname": this.lastName,
         "mobile_phone": this.mobilePhone,
         "email_address": this.emailAddress,
         "description": this.description,
         "gender": this.gender,
         "date_of_birth": this.dateOfBirth,
         "course_subject": this.courseSubject,
         "course_level": this.courseLevel,
       },
     });
     $.export("$summary", `Successfully created prospect with ID: ${response.data.id}`);
     return response;
+  } catch (error) {
+    $.export("$summary", `Failed to create prospect: ${error.message}`);
+    throw error;
+  }
 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const response = await this.app.createProspect({
$,
data: {
"fname": this.firstName,
"lname": this.lastName,
"mobile_phone": this.mobilePhone,
"email_address": this.emailAddress,
"description": this.description,
"gender": this.gender,
"date_of_birth": this.dateOfBirth,
"course_subject": this.courseSubject,
"course_level": this.courseLevel,
},
});
$.export("$summary", `Successfully created prospect with ID: ${response.data.id}`);
return response;
},
async run({ $ }) {
try {
const response = await this.app.createProspect({
$,
data: {
"fname": this.firstName,
"lname": this.lastName,
"mobile_phone": this.mobilePhone,
"email_address": this.emailAddress,
"description": this.description,
"gender": this.gender,
"date_of_birth": this.dateOfBirth,
"course_subject": this.courseSubject,
"course_level": this.courseLevel,
},
});
$.export("$summary", `Successfully created prospect with ID: ${response.data.id}`);
return response;
} catch (error) {
$.export("$summary", `Failed to create prospect: ${error.message}`);
throw error;
}
},

};
194 changes: 194 additions & 0 deletions components/teach_n_go/actions/create-student/create-student.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
import { PAYMENT_METHOD_OPTIONS } from "../../common/constants.mjs";
import app from "../../teach_n_go.app.mjs";

export default {
key: "teach_n_go-create-student",
name: "Create Student",
description: "Registers a new student in Teach 'n Go. [See the documentation](https://intercom.help/teach-n-go/en/articles/6807235-new-student-and-class-registration-api)",
version: "0.0.1",
type: "action",
props: {
app,
firstName: {
propDefinition: [
app,
"firstName",
],
description: "The student's first name.",
},
lastName: {
propDefinition: [
app,
"lastName",
],
description: "The student's last name.",
},
gender: {
propDefinition: [
app,
"gender",
],
description: "The student's gender.",
optional: true,
},
registrationDate: {
type: "string",
label: "Registration Date",
description: "The student's registration date. **Format: YYYY-MM-DD**",
optional: true,
},
dateOfBirth: {
propDefinition: [
app,
"dateOfBirth",
],
description: "The student's date of birth. **Format: YYYY-MM-DD**",
optional: true,
},
identificationNumber: {
type: "string",
label: "Identification Number",
description: "The external number to identify the student.",
optional: true,
},
preferredPaymentMethod: {
type: "integer",
label: "Preferred Payment Method",
description: "The payment method the student want to use.",
options: PAYMENT_METHOD_OPTIONS,
optional: true,
},
discountPercentage: {
type: "string",
label: "Discount Percentage",
description: "The discount percentage on the payment amount.",
optional: true,
},
mobilePhoneCode: {
type: "integer",
label: "Mobile Phone Code",
description: "The region code of the mobile phone. Min length: 2, Max length: 4",
optional: true,
},
mobilePhone: {
type: "integer",
label: "Mobile Phone",
description: "The student's mobile phone",
optional: true,
},
homePhoneCode: {
type: "integer",
label: "Home Phone Code",
description: "The region code of the home phone. Min length: 2, Max length: 4",
optional: true,
},
homePhone: {
type: "integer",
label: "Home Phone",
description: "The student's home phone",
optional: true,
},
Comment on lines +67 to +90
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Consider changing phone number fields from integer to string

Phone numbers and phone codes may contain leading zeros and can exceed the maximum safe integer size in JavaScript. Using string type ensures accurate representation and handling of these values.

Apply this diff to change the type of phone number fields to string:

-   type: "integer",
+   type: "string",
    label: "Mobile Phone Code",
    description: "The region code of the mobile phone. Min length: 2, Max length: 4",
    optional: true,
  },
-   type: "integer",
+   type: "string",
    label: "Mobile Phone",
    description: "The student's mobile phone",
    optional: true,
  },
-   type: "integer",
+   type: "string",
    label: "Home Phone Code",
    description: "The region code of the home phone. Min length: 2, Max length: 4",
    optional: true,
  },
-   type: "integer",
+   type: "string",
    label: "Home Phone",
    description: "The student's home phone",
    optional: true,
  },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mobilePhoneCode: {
type: "integer",
label: "Mobile Phone Code",
description: "The region code of the mobile phone. Min length: 2, Max length: 4",
optional: true,
},
mobilePhone: {
type: "integer",
label: "Mobile Phone",
description: "The student's mobile phone",
optional: true,
},
homePhoneCode: {
type: "integer",
label: "Home Phone Code",
description: "The region code of the home phone. Min length: 2, Max length: 4",
optional: true,
},
homePhone: {
type: "integer",
label: "Home Phone",
description: "The student's home phone",
optional: true,
},
mobilePhoneCode: {
type: "string",
label: "Mobile Phone Code",
description: "The region code of the mobile phone. Min length: 2, Max length: 4",
optional: true,
},
mobilePhone: {
type: "string",
label: "Mobile Phone",
description: "The student's mobile phone",
optional: true,
},
homePhoneCode: {
type: "string",
label: "Home Phone Code",
description: "The region code of the home phone. Min length: 2, Max length: 4",
optional: true,
},
homePhone: {
type: "string",
label: "Home Phone",
description: "The student's home phone",
optional: true,
},

emailAddress: {
propDefinition: [
app,
"emailAddress",
],
description: "The student's email address.",
optional: true,
},
streetNameAndNumber: {
type: "string",
label: "Street Name And Number",
description: "The student's full address.",
optional: true,
},
flatFloor: {
type: "string",
label: "Flat Floor",
description: "The student's address flat floor if it exists.",
optional: true,
},
area: {
type: "string",
label: "Area",
description: "The student's address area.",
optional: true,
},
city: {
type: "string",
label: "City",
description: "The student's city.",
optional: true,
},
postcode: {
type: "string",
label: "Postcode",
description: "The student's postcode.",
optional: true,
},
countryCode: {
type: "string",
label: "Country Code",
description: "The student's ISO 2 letter country code, e.g. (US, UK, IN).",
optional: true,
},
generalNotes: {
type: "string",
label: "General Notes",
description: "Some student's additional notes.",
optional: true,
},
medicalNotes: {
type: "string",
label: "Medical Notes",
description: "Some student's additional medical notes.",
optional: true,
},
courses: {
propDefinition: [
app,
"courses",
],
optional: true,
},
enrolmentDate: {
type: "string",
label: "Enrolment Date",
description: "The date of the student's enrolment.",
optional: true,
},
},
async run({ $ }) {
const response = await this.app.registerStudent({
$,
data: {
fname: this.firstName,
lname: this.lastName,
gender: this.gender,
registration_date: this.registrationDate,
date_of_birth: this.dateOfBirth,
identification_number: this.identificationNumber,
preferred_payment_method: this.preferredPaymentMethod,
discount_percentage: this.discountPercentage && parseFloat(this.discountPercentage),
mobile_phone_code: this.mobilePhoneCode,
mobile_phone: this.mobilePhone,
home_phone_code: this.homePhoneCode,
home_phone: this.homePhone,
email_address: this.emailAddress,
street_name_and_number: this.streetNameAndNumber,
flat_floor: this.flatFloor,
area: this.area,
city: this.city,
postcode: this.postcode,
country_code: this.countryCode,
general_notes: this.generalNotes,
medical_notes: this.medicalNotes,
courses: this.courses,
enrolment_date: this.enrolmentDate,
},
});

$.export("$summary", `Successfully registered student with ID: ${response.data.id}`);
return response;
},
};
30 changes: 30 additions & 0 deletions components/teach_n_go/common/constants.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const LIMIT = 100;

export const GENDER_OPTIONS = [
"Female",
"Male",
"Not Specified",
];

export const PAYMENT_METHOD_OPTIONS = [
{
label: "Cash",
value: 1,
},
{
label: "Cheque",
value: 2,
},
{
label: "Credit Card",
value: 3,
},
{
label: "Bank Transfer",
value: 4,
},
{
label: "Direct Debit",
value: 5,
},
];
24 changes: 24 additions & 0 deletions components/teach_n_go/common/utils.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export const parseObject = (obj) => {
if (!obj) return undefined;

if (Array.isArray(obj)) {
return obj.map((item) => {
if (typeof item === "string") {
try {
return JSON.parse(item);
} catch (e) {
return item;
}
}
return item;
});
}
if (typeof obj === "string") {
try {
return JSON.parse(obj);
} catch (e) {
return obj;
}
}
return obj;
};
7 changes: 5 additions & 2 deletions components/teach_n_go/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/teach_n_go",
"version": "0.0.1",
"version": "0.1.0",
"description": "Pipedream Teach 'n Go Components",
"main": "teach_n_go.app.mjs",
"keywords": [
Expand All @@ -11,5 +11,8 @@
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@pipedream/platform": "^3.0.3"
}
}
}
Loading
Loading