Preview: https://uni-search.mdluo.com.
This is a full-stack web app developed with PostGraphile and Next.js, featuring NextAuth for email and 3rd party account login, Apollo Client as the React GraphQL client, and BlueprintJS and Tailwind CSS as the UI framework.
This app is inspired by Graphile Starter, please refer to it for more features and integration examples.
- Realtime fuzzy university name search with country filter.
- University icons for easier identification.
- Results infinite scrolling.
- Log in (and sign up) with Email, GitHub and Google accounts.
- Cookie-based JWT tokens for user identification.
- Cursor-based pagination (Relay style).
- Automatic hook and types generation with graphql-codegen.
__tests__: Jest unit tests filescomponentsavatar: The university's icon, load with Google favicons API and avatar.tobi.sh as the fallback image.country-select: A dropdown menu to select a country, with a quick text filter. And the country data comes from https://github.com/dr5hn/countries-states-cities-database.nav: Navigation header with a logo, a link to the bookmarks page and a dropdown menu with user's avatar, name and a link for the user to sign out.search: The main search input, with a clear button and thecountry-selectcomponent on the right hand side.sort: A dropdown button menu to allow user to sort the results by name or country and A-Z or Z-A respectively.university: The university item in the search and bookmark list, with theavatar, the university name, the state/province and country (and emoji), the link to the website, and a bookmark button.
data: The source files of the university data and country data.graphqlgenerated: Hooks and types generated with graphql-codegen.*.graphql: Client-side graphql schemas, add new Queries, Mutations here.
hooks: Reusable React hooks.libs: Reusable JS functions and utilities.migrations: SQL files containing database table, function and trigger schemas to be used by graphile-migrate.mocks: Mock API handlers to be used by MSW.pagesapi/auth: User authentication related APIs, with NextAuth configuration and callbacks._app.tsx: A Next.js custom App component to wrap the web pages with NextAuth Provider, ApolloClient Provider, etc.bookmarks.tsx: The Bookmarks page to load and show user's bookmarked universities, user sign-in required.index.tsx: The home page, to allow visitors to search, filer and sort universities, guest mode available.
public: Static files.scripts: Node.js (ts-node) scripts.servers: The entry point of the whole web app, comes with an Express.js server to bootstrap both Next.js app and PostGraphile-as-a-library.styles: Global CSS.
Requirements:
- GitHub OAuth App and/or Google OAuth 2.0 Client ID
- SMTP service, Gmail or SendGrid.
- Docker machine and docker-compose (for running PostgreSQL, optional if you installed PostgreSQL natively).
- Node.js (recommend >= 16) and npm (recommend >= 8) or yarn.
docker-compose up -dnpm cicp .env.example .envAnd edit the .env file to ensure all the missing variables are set. Tip: you can use openssl rand -base64 30 | tr '+/' '-_' to generate a random string for passwords and secrets.
npm run db:init
npm run db:migrateOpen a new terminal tab and run
npm run db:seednpm run devAnd got the http://localhost:3000
npm run codegenThis is to watch any schema changes on the server side, as well as graphql code changes in graphql/*.graphql files and generate new types and hooks into graphql/generated/index.tsx.
- Fix the stale data issue when switching the pages.
- Fine-tune the styles and UX on mobile browsers.
- Add more actual unit test cases to improve the coverage rate.
- Create custom NextAuth adapter to use Postgres database to store the email verification token, and get rid of the in-memory SQLite adapter.
- Add Virtuoso to the result list to make it virtualised.
- Add code-splitting to some of the larger components, and apply tree-shaking to the BlueprintJS components.
- Fix the
loadingstate returned by ApolloClient hooks not working issue. - Add GiST index to the universities table to optimise the text search speed: https://alexklibisz.com/2022/02/18/optimizing-postgres-trigram-search.html, as well as sort the result by match ranking.
- Add an extra tsvector column the universities table for full text search to work together with the current fuzzy search.
- Unify the country data on
country-selectand the country field from the universities data source. - Set up monorepo with Turborepo.
- Add CI/CD pipelines to build and deploy the app automatically.