Skip to content

Repository files navigation

Mingle people directory

A responsive Next.js dashboard for browsing and discovering people across a team. The interface is inspired by the people-search shape in the supplied Slack request, but it intentionally uses safe local sample data and does not include or call Slack with browser session credentials.

Features

  • Search by name, role, skill, department, or location
  • Department quick filters
  • Detailed department, location, status, and work-style filters
  • Name, department, and recently-added sorting
  • Responsive profile-card grid with pagination
  • Detailed profile modal with contact information, skills, projects, and local time
  • Keyboard-friendly modal closing and reduced-motion support
  • Useful empty states and mobile layouts

Run locally

npm install
npm run dev

Open http://localhost:3000.

Authentication and approvals

Copy the Supabase and initial administrator variables from .env.example into the git-ignored .env. Then run supabase/auth-setup.sql once in that Supabase project's SQL Editor and bootstrap the first approved administrator:

npm run auth:bootstrap

New users request access from /auth/sign-up. They remain on the pending screen until an approved administrator accepts them at /admin. Rejected and pending accounts cannot access the dashboard or its API routes.

Run supabase/sent-users.sql in the same Supabase SQL Editor to enable shared sent-user tracking. Approved users can mark or unmark a Slack member from the profile modal, and the status is shown on directory cards. The table stores the stable Slack user ID, the app user who marked it, and the timestamp.

The development Compose service reads .env through env_file. Environment or dependency changes require a one-time container recreation; ordinary source and CSS changes continue to hot reload.

Publish real directory data for Vercel

Vercel cannot access the git-ignored local .data files. Publish the current sanitized directory snapshot and profile-filter index to the private Supabase Storage bucket:

npm run publish:directory

The command gzip-compresses the directory, filter index, and detailed-profile snapshots before upload. The server-side directory API reads and decompresses these private objects with SUPABASE_SECRET_KEY when local files are unavailable. Add SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY, SUPABASE_SECRET_KEY, and optionally SUPABASE_DIRECTORY_BUCKET to the Vercel project environment. The bucket is never made public. Run the publish command again after refreshing or re-indexing Slack data.

For detailed CSV exports, build the private profile-detail snapshot before publishing:

npm run sync:profile-details
npm run publish:directory

The sync walks Slack people-search pages with retry and rate-limit handling, then fills any missing members through the direct profile endpoint. It stores standard fields such as email and phone plus every completed custom profile field in .data/slack-profile-details.json. The file is git-ignored and uploaded only to the private Storage bucket. CSV downloads join this snapshot to the current filtered directory instead of making thousands of live Slack requests inside a Vercel function.

Live modal enrichment additionally requires the server-only SLACK_ORIGIN, SLACK_TOKEN, and SLACK_COOKIE Vercel environment variables. Use the values from the git-ignored .slack/session.json; never prefix them with NEXT_PUBLIC_. These browser-session credentials expire, so replace them when Slack begins returning an authorization error. Without them, the real directory still works and the modal displays a neutral unavailable state instead of exposing a configuration error.

Run with Docker and hot reload

Build and start the development container once:

docker compose up --build

The project is bind-mounted into the container and filesystem polling is enabled, so changes under src/, public/, and other source files appear automatically through Next.js Fast Refresh. You do not need to restart Docker or rerun Compose for normal code and CSS edits.

Later starts only need:

docker compose up

Changes to package.json, package-lock.json, Dockerfile.dev, or compose.yaml still require rebuilding the container because they change dependencies or the runtime itself.

Verify

npm run lint
npm run build

The Windows scripts use Next.js with Webpack because this machine's native SWC/Turbopack binary is unavailable; Next's WASM compiler is used automatically.

Data

The dashboard reads the git-ignored .data/slack-users.json cache through the server-side /api/people route. The browser receives only the requested page, not the complete dataset.

To refresh the directory from a newly copied Slack curl request:

npm run sync:slack -- "C:\path\to\pasted-text.txt"

The importer extracts the supplied session in memory, traverses Slack's cursor-based users.list endpoint, removes deleted accounts and bots, and writes sanitized dashboard fields to the local cache. The Slack token and cookie are never written to the cache or client bundle. Because .data is bind-mounted in the development Compose setup, a completed sync is picked up without rebuilding the image.

To enable live, complete profile details when a user card is opened, import the current Slack session into the local git-ignored secret file:

npm run session:slack -- "C:\path\to\pasted-text.txt"

The server-side profile route uses .slack/session.json to request users.profile.get, users.profile.getSections, users.profile.getExtras, and the workspace profile schema. The secret file is available to the bind-mounted development container but is excluded from Git and Docker image builds. Re-import it when the Slack session expires.

After a directory refresh, rebuild the Profile details filter index:

npm run seed:profile-index
npm run index:profiles

The search seeder quickly covers most members, then the resumable direct index fills any remaining IDs. The resulting git-ignored .data/slack-profile-index.json stores only hasTitle, hasEmail, hasPhone, and hasPhoto booleans—not profile values or credentials. Multiple selected checkboxes use AND logic.

The curl payload still contains reusable Slack session credentials. Keep it outside the repository and revoke/rotate those credentials if the file has been shared.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages