Visit the site angloeastern-fe-challenge
Tech Stack for this mini App:
Frontend:
- React with TypeScript: For building the user interface
- Vite: For faster development
- Chakra UI: For ready-made components
- React Query: For getting and managing data
Backend:
- Express.js: For creating the API
Database:
- JSON file: For storing data
Deployment:
- Digital Ocean: I put the app on my own server at Digital Ocean
Why I chose these:
- Vite: It's fast and easy to set up. It makes the development process quicker.
- Chakra UI: I know how to use it well. It has many components I can use to build the app quickly.
- React Query: It makes it easy to get data from the server and keep it updated. It also helps make the app faster.
- Express.js: It's simple to use and can create an API quickly.
- JSON file for data: For a small app like this, it's simple and good enough. We don't need a complex database.
- Digital Ocean: I chose to deploy on my own server because it gives me more control. It's also a good way to show I can set up and manage a server.
Things to think about:
- Using a JSON file for data works for this small app, but it might not be good for bigger apps.
- This setup is good for making the app quickly, which is important for a take-home test. For a real app that many people would use, we might need to add more things.
- Deploying on my own server means I'm responsible for keeping it running and secure. This takes more work but shows I can handle the whole process of making an app work online.
To improve performance and reduce unnecessary file reads, I implemented a simple in-memory caching system for the issues data. Here's how it works:
- The first time the data is requested, it's read from the file and stored in memory.
- For subsequent requests, the system checks if the file has been modified since the last read.
- If the file hasn't changed, the cached data is used, avoiding a file read operation.
- If the file has been modified, the system reads the new data from the file and updates the cache.
This approach balances performance and data freshness. It speeds up response times for frequent requests while ensuring that any changes to the data file are reflected in the application. The cache is stored in the server's memory, so it's fast to access but doesn't persist between server restarts.
This caching method is particularly effective for our use case, where the data doesn't change very often but is read frequently. It significantly reduces the number of file system operations, which can be slow compared to memory access.
- View past issue
- Create new issue
- Update issue
- Delete issue
- Search issue by title
- Support multiple languages
- Switch between grid and list view
- Clone this repo
- run
npm install
- run
npm run dev:client
To run server
cd server
npm install
npm run dev
To run test
npm run test
.
├── server
│ ├── db
│ │ └── db.json
│ ├── src
│ │ ├── index.ts
│ │ ├── controllers
│ │ │ └── issues.ts
│ │ ├── models
│ │ │ └── types.ts
│ │ └── routes
│ │ └── index.ts
├── src
│ ├── components
│ │ ├── ExpandableSearch.tsx
│ │ ├── IssueComposer.tsx
│ │ ├── IssueList.tsx
│ │ └── IssueListItem.tsx
│ ├── config
│ │ └── index.ts
│ ├── hooks
│ │ └── useCreateNewIssue.ts
│ ├── pages
│ │ ├── Issues.tsx
│ │ └── index.tsx
- Get all issues
- Response
- Status: 200
- Body
{ "issues": [ { "id": "1", "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 1", "issueNumber": 1, "issueDate": "2023-07-01" }, { "id": "2", "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 2", "issueNumber": 2, "issueDate": "2023-07-02" } ] }
- Get issue by id
- Response
- Status: 200
- Body
{ "id": "1", "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 1", "issueNumber": 1, "issueDate": "2023-07-01" }
- Create new issue
- Request
- Body
{ "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 1", "issueNumber": 1, "issueDate": "2023-07-01" }
- Body
- Response
- Status: 201
- Body
{ "issues": [ { "id": "1", "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 1", "issueNumber": 1, "issueDate": "2023-07-01" } ] }
- Update issue
- Request
- Body
{ "id": "1", "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 1", "issueNumber": 1, "issueDate": "2023-07-01" }
- Body
- Response
- Status: 200
- Body
{ "issues": [ { "id": "1", "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 1", "issueNumber": 1, "issueDate": "2023-07-01" } ] }
- Delete issue by id
- Response
- Status: 200
- Body
{ "issues": [ { "id": "1", "imageUri": "https://github.com/github/explore/blob/main/topics/javascript/javascript.png?raw=true", "title": "Issue 1", "issueNumber": 1, "issueDate": "2023-07-01" } ] }