Local Development - liferesearchapp/life-research-members-portal GitHub Wiki
Requirements
- Node.js (includes node package manager)
- Any web browser
Recommended Environment
VS Code with the following extensions:
- ESLint linter - this will give helpful warnings using the dev dependencies
eslint
andeslint-config-next
already included inpackage.json
. - Prettier code formatter - set this as your default formatter and enable format on save
- Prisma syntax highlighting for prisma schema files
- SCSS Intellisense Intellisense for SCSS files (code completion, hover tooltips, signature help)
- CSS Variable Autocomplete Autocomplete for CSS variables like
var(--volcano-5)
, useful for browsing colors fromsrc/styles/_antd-colors.scss
Microsoft SQL Server (Developer) For creating a localhost server (See Prisma SQL Server on Windows (Local) for setup intructions). SQL Server Management Studio (SSMS) For editing the database.
A minimum of two desktop browsers and one mobile browser, for manual testing.
Recommended Documentation
Hosting Locally
1. Fork this repo, then clone it onto your own machine.
2. In the root directory of the application, run npm i
to install dependencies.
3. Get the database connection string. In the Azure Portal you can find the connection string under the SQL database -> connection strings -> JDBC -> JDBC (SQL authentication). Just remove the "jdbc:" prefix and insert the database password.
4. Add a file named .env
to the root directory that contains DATABASE_URL=<database connection string>
.
Example .env
file:
DATABASE_URL="sqlserver://life-server.database.windows.net:1433;database=life-database;user=chami033@life-server;password={your_password_here};encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;"
Localhost example:
DATABASE_URL_TEST="sqlserver://localhost:1433;database={your_test_database_name_here};integratedSecurity=true;trustServerCertificate=true;"
5. Localhost Testing Database Setup:
- Insert at least 1 entry into tables: event_type, faculty, level, member_type, org_scope, org_type, product_type, source, status, target and topic (See Database for relations).
- (Single-Institute Only) Insert a admin account entry into the account table.
- (Multi-Institute Only) Insert a super admin account entry into the account table and the initial/first institute into the institute table. Establish membership between the two by adding a related entry into the member, memberInstitute and instituteAdmin (so that the "at least 1 admin per institute" condition is fulfilled, though super admins can self-assign to the admin role of the selected institute through their account profile) tables.
6. To run in development mode (automatic reloads on change): npm run dev
The app can be found at http://localhost:3000
in a web browser.
Optional: To test a production build:
npm run build
npm run start
Steps to Add a Feature
Some of these steps may not be necessary depending on the feature, and many steps can be done in different orders.
Database Modification
- Design new database relationships
- Add new relationships to the database schema via SSMS
- Pull the new schema using
npx prisma db pull
- Generate the new Prisma client using
npx prisma generate
Backend API Route
- Create the API route by adding a file to
src/pages/api
- Add the API route to
src/routing/api-routes
- Add a function that extracts the relevant data from the database using Prisma
- Export the return type and parameter types of the function (may be able to reuse the return type of another function)
- Export a default function that handles the HTTP request and checks the correct permissions
Frontend Service and Interface
- Add a service function under
src/services
that calls the new route, handles errors and notifications, and has the correct parameter and return type imported from the backend - Add a new frontend page route under
src/pages
with appropriate auth guards if necessary - Add the new route to
src/routing/page-routes
- Add a way to navigate to the new page
- Add React components to the new page
Try to break it 🔨
Creating and Integrating a New Page
This will guide you through creating a new page and integrating it into the Portal. We will cover the following steps:
- Create a new page and its components
- Add the page to the navigation menu
- Create and organize components for the new module
- Add context providers and API routes
Create a new page and its components
To create a new page, follow these steps:
- Under src/pages, create a folder with the name of the desired page and add an index.tsx file.
Example: For a grants page, create pages/grants/index.tsx that exports a React component:
const GrantsPage: NextPage = () => {
return <AllGrants />;
};
export default GrantsPage;
-
Later on in that same folder, create a register.tsx file to add new items to the database, and an [id] folder to access either private or public profile of that same module.
-
API functions are defined in src/pages/api and handle HTTP requests and execute queries on the database. More details can be found in the backend documentation.
Add the page to the navigation menu
To access the new page in the navigation menu, edit src/components/navbar/nav-menu.tsx and add it to either generalItems for the public, registeredItems for registered users, or adminItems for admin only.
- Example: To access grants in the navigation:
const generalItems = [
{ label: en ? "Grants" : "Subvention", href: PageRoutes.allGrants },
];
- Navigate to src/routes/page-routes to add the corresponding page routes:
const PageRoutes = {
allGrants: "/grants",
} as const;
Create and organize components for the new module
Create a folder in src/components for all the components that will be used for the new module. For example, see components/grants. Components are organized as shown in the table below:
Name | File | Description |
---|---|---|
AllGrants | all-grants.tsx | Displays a table of grants, with filters to filter the grants based on name, status and source |
DeleteGrantButton | delete-grant-button.tsx | A button that opens a modal to delete a grant |
PrivateGrantProfile | grant-private-profile.tsx | A detailed view of a private grant's profile |
PublicGrantDescription | grant-public-description.tsx | Displays the public information of a grant in a table format |
PublicGrantForm | grant-public-form.tsx | Displays a form for updating public information of a grant. |
PublicGrantProfile | grant-public-profile.tsx | Displays the public grant profile information for a specific grant id. |
RegisterGrant | grant-register.tsx | Provides a form for registering a grant |
Filters are implemented in components/filters
. Filters are components that provide a dropdown list for selecting multiple items. For example:
- GrantNameFilter from "../filters/grant-name-filter";
- GrantStatusFilter from "../filters/grant-status-filter";
- GrantSourceFilter from "../filters/grant-source-filter";
Duplicate existing styles, and add the new styles in _globals.scss
.
Add context providers and API routes
To add the corresponding context provider, navigate to services/context/
. Context providers are used to store the list of the corresponding items and manage the state for loading, refreshing, and updating this information.
- Example:
{ AllGrantsCtx }
from "../../services/context/all-grants-ctx"; (it usesGrantPublicInfo
andapiRoutes
)'
Note that GrantPublicInfo
is added to /services/_types
, a service that imports all the required types from the API routes and uses NonNullable
to remove nullability from the imported types.
apiRoutes
are located in routing/api-routes.ts
. This file defines a constant object ApiRoutes
containing the URLs of all the API endpoints in the application. The URLs are stored as properties of the object. For example, ApiRoutes.allGrants
is the URL for retrieving all grants.
With these steps, you should be able to create and integrate a new page into the Portal successfully. Remember to follow best practices for React and Next.js development and to organize your components and files in a modular manner.
Testing and debugging tips
Once you have completed the steps above, it's essential to test the new page and its components to ensure that they function as expected.
- Run the development server with
npm run dev
oryarn dev
. - Visit the new page in your browser by navigating to the corresponding URL (e.g., http://localhost:3000/grants for the
grants
page). - Verify that the components are rendering correctly and that the filters, forms, and other functionality are working as intended.
- Test the new page and components with different user roles (public, registered user, admin) to ensure proper access control and functionality.
Debugging with Chrome
Chrome Developer Tools (also known as Chrome DevTools) is a powerful way to identify and fix issues in your web applications. Here's how you can debug using the Chrome console:
- Open Chrome DevTools: Right-click on your web page and select "Inspect" or use the keyboard shortcut
Ctrl + Shift + I
(Windows/Linux) orCmd + Option + I
(Mac). - Navigate to the Console tab: In the DevTools window, click on the "Console" tab to access the console. Here, you can see logged messages, errors, and warnings.
- Use console.log(): In your code, add
console.log()
statements to print out the values of variables, objects, or any other information that will help you understand the state of your application at various points. - Debug JavaScript: Navigate to the "Sources" tab in DevTools to debug your JavaScript code. You can set breakpoints, step through code execution, and inspect variables and their values. To set a breakpoint, click on the line number in the source code where you want to pause execution. You can also use the
debugger
; statement in your code to create a breakpoint programmatically. - Monitor network activity: Use the "Network" tab in DevTools to inspect network requests and responses. This can help you identify issues related to API calls, loading of resources, or other network-related issues.