This project demonstrates key features using data endpoints enabled through ServiceNow, built on top of provided boilerplates. The focus is on creating a course subscription platform with drag-and-drop capabilities.
- Fetch and display a list of available courses from the backend (ServiceNow or custom backend).
- Display course details (Title, Description, Duration).
- Use a traditional "Subscribe" button.
- (Opitional) Implement a drag-and-drop mechanism where learners can drag courses into a subscription basket.
- Clicking the "Subscribe" button or dropping a course into the basket should create a new subscription record.
- Display the subscribed course in the learner's "My Courses"
- Optional (Advanced): Provide feedback such as visual highlight when using drag-and- drop.
- Optional (Advanced): Provide feedback (e.g., visual highlights) when using drag-and- drop.
- (Optional) Provide a way to unsubscribe from courses.
Hosting
- Fully hosting the application on ServiceNow
Due to the time constraint, most tech stacks were chosen to promote the fast implementation.
- Vite: Chosen for its fast build times and modern bundling capabilities.
- JavaScript: While I prefer TypeScript for catching errors at compile time, JavaScript was selected as it aligns with the DCM team's tech stack.
- Axios: Used for handling HTTP requests and simplifying response handling.
- TanStack Query: Integrated to enhance user experience by caching subscription data. Full optimization was limited due to time constraints.
- Styled-Components: Used for creating dynamic styles, particularly for drag-and-drop visual highlights.
- React Router: Set up routing for the main course page and "My Courses" page.
x_quo_coursehub
└── app/
├── ...
└── src/
└── api/
├── axiosInstance.js: Sets up Axios with BaseURL and common headers.
├── constant.js: Stores commonly used API variables
├── course.js: API for course-related requests.
├── subscription.js: API for subscription-related requests.
├── components/
│ ├── CourseCard.jsx: Displays course details and handles subscribe/unsubscribe actions.
│ ├── Layout.tsx: Common layout component for rendering the header and page content.
│ ├── ShoppingBasket.jsx: Place to drop <CourseCard/> to subscribe a course
│ └── ...
├── context/
│ └── UIDataContext.js: Stores UI data for drag-and-drop functionality.
├── hooks/ hooks to use Tanstack Query and UIData Context
│ ├── ...
├── pages/
│ ├── HomePage.jsx: Displays available courses and allows users to subscribe.
│ ├── MyCoursePage.jsx: Displays subscribed courses and enables unsubscribing.
│ └── ...
├── utils/
│ └── formatDuration.js: Converts epoch date-time to display course duration correctly.
├── App.jsx: Set up the frontend routes
└── ...
- Project planning and familiarization with ServiceNow.
- Created a Personal Developer Instance in ServiceNow.
- Set up tables in ServiceNow Studio using the provided boilerplates.
- Explored ServiceNow Table API and configured API calls.
- Refined query parameters to retrieve required data.
- Integrated TanStack Query for data caching.
- UI implementation:
- Set up routing.
- Implemented layout structure.
- Learned drag-and-drop implementation in React.
- Developed components and context, integrating them into the UI.
- Checked the requests and implementation. Added missing features.
- Documented the project on README.md
- Deploy the app on Github page
When displaying subscribed courses, fetching records from the x_quo_coursehub_course_subscription
table returned only reference links instead of the full course details (title, description, duration). It was challenging to retrieve data from populated reference fields, but this was eventually solved through further query refinement.
ServiceNow’s Table API returned the duration data as a date string (YYYY-MM-DD HH:MM:SS
) instead of the expected format. After investigation, I realized the system was using Unix Epoch timestamps. A conversion utility (/utils/formatDuration.js
) was implemented to transform these values into readable duration strings.
- Add automated testing
- Improve caching data for better user experience
- You need to enable PDI in ServiceNow. Then you need to set up tables using the boiler plate and insert data into each table.
- Create
./app/.env
and copy and paste variables from./app/.env.example
. Replace values accordingly.
Go to /app directory and install packages
npm install
Run the project
npm run dev