Skip to content

skillwork-mdimitrov/hr-admin-panel-challenge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

27 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Candidate List Admin Panel

A coding challenge solution demonstrating best practices in code organization, readability, and maintainability through a production-ready recruitment platform.

🎯 Challenge Overview

Objective: Create an admin page that displays a list of job candidates with the ability to filter by first and last name.

This solution showcases:

  • Clean, maintainable code architecture
  • Scalable system design aligned with product goals
  • Integration with AWS AppSync GraphQL API
  • Production-ready deployment with Docker

Prerequisites

  • Node.js 18+
  • Docker Desktop (for containerized development)

πŸš€ Tech Stack

Challenge Requirements

  • βœ… React 19 - Modern component-based architecture with hooks
  • βœ… Apollo Client 4 - GraphQL integration with AWS AppSync endpoint
  • βœ… AWS AppSync - Managed GraphQL API with introspection enabled
  • βœ… Table Display - Responsive candidate list with clean UI
  • βœ… Search Functionality - Real-time filtering by first and last name

Enhanced Implementation

  • Next.js 15 - React framework with App Router and Server Components for improved performance
  • TypeScript 5.8 - Strict mode enabled for type safety and maintainability
  • @apollo/client-integration-nextjs - Official Next.js 13+ integration for SSR support
  • Tailwind CSS 4 + shadcn/ui - Production-ready styling with accessible component library
  • NextAuth.js v5 + PostgreSQL + Drizzle ORM - Secure admin panel with role-based access control
  • ESLint 9 + Prettier - Enforced code standards and consistent formatting
  • Docker - Containerized development and production deployment

πŸ“Έ Imagery

main-screen.png

sign-in-screen.png

admin-panel-screen.png


sign-up-screen.png

admin-panel-mobile-filtered.png

✨ Key Features

Challenge Requirements βœ…

  • πŸ“‹ Table Display - Clean, responsive candidate list with sortable columns
  • πŸ” Search Filter - Real-time filtering by first and last name with debouncing (case-sensitive)
  • 🌐 GraphQL Integration - AWS AppSync endpoint with proper authorization
  • βš›οΈ React Implementation - Modern hooks-based architecture

Additional Production Features

  • πŸ” Authentication System - Secure login with NextAuth.js and session management
  • 🐳 Docker Deployment - Production-ready containerized setup
  • πŸ”’ Secure API Keys - GraphQL API keys concealed server-side with Next.js SSR, never exposed to client

πŸš€ Installation

Quick Start (Docker - Recommended)

  1. Clone the repository

    git clone https://github.com/skillwork-mdimitrov/hr-admin-panel-challenge.git
    cd hr-admin-panel-challenge
  2. Install Docker Desktop

  3. Set up environment variables

    cd frontend
    cp .env-example .env
  4. Generate authentication secret

    npx auth secret
    • Copy the generated secret from the newly created .env.local file
    • Paste it into .env as AUTH_SECRET="your-secret-here"
    • ⚠️ Remove any extra newlines in the .env file if needed
  5. Replace API_KEY with the Doppler shared secret

    • Open the .env file
    • Replace the API_KEY value with the Doppler shared secret
  6. Start Docker Desktop

    • Make sure Docker Desktop is running before proceeding
    • You should see the Docker icon in your system tray
  7. Build and start containers

    docker compose build --no-cache frontend
    docker compose up -d frontend
  8. Seed the database (creates default admin user)

    docker compose exec frontend pnpm exec tsx scripts/seed-runner.ts
  9. Access the application

  10. Install dependencies locally (for IDE IntelliSense and ESLint)

npm install -g pnpm@latest-10
pnpm install

Docker Management Commands

Available as npm scripts in frontend/package.json:

# Stop containers (preserves data)
docker compose rm -s -f frontend

# Stop and remove all data (⚠️ DESTRUCTIVE)
docker compose down -v

# Rebuild containers
docker compose build --no-cache frontend

# Force recreate containers
docker compose up -d --force-recreate frontend

# Seed database
docker compose exec frontend pnpm exec tsx scripts/seed-runner.ts

Optional: Database Connection (PHPStorm/IntelliJ)

Connect to PostgreSQL for direct database access:

  • Host: localhost
  • Port: 5434
  • Database: frontend
  • User: postgres
  • Password: (from .env file)

PHPStorm-database.png

PHPStorm-show-db.png

Troubleshooting

  • Docker errors on Windows: Ensure line endings are set to CRLF
  • Port conflicts: Make sure ports 3000 and 5434 are available
  • Auth secret issues: Ensure no extra newlines in .env file

πŸ—οΈ Architecture & Code Quality

Code Organization Highlights

  • Single Responsibility: Each component has one clear purpose
  • DRY Principle: Shared logic extracted into hooks and utilities
  • Readable Code: Clear naming conventions and inline documentation
  • Maintainable: Logical file structure and consistent patterns

API Configuration

  • Endpoint: AWS AppSync GraphQL endpoint (configured via environment variables)
  • Authorization: x-api-key header authentication
  • Introspection: Enabled for type-safe development

Query Implementation

query GetCandidates($filter: ModelCandidateFilterInput) {
  listCandidates(filter: $filter) {
    items {
      id
      firstName
      lastName
      email
      phoneNumber
      status
      score
      createdAt
      updatedAt
    }
    nextToken
  }
}

Search Filter Logic

The search functionality leverages GraphQL's filtering capabilities:

// Debounced search input (500ms delay)
const debouncedSearch = useDebounce(searchInput, 500);

// Build GraphQL filter with OR condition
const filter = debouncedSearch.trim()
  ? {
      or: [
        { firstName: { contains: debouncedSearch.trim() } },
        { lastName: { contains: debouncedSearch.trim() } }
      ]
    }
  : undefined;

// Apollo Client query with variables
const { data, error, networkStatus } = useQuery(GET_CANDIDATES, {
  variables: { filter },
  notifyOnNetworkStatusChange: true,
});

Type Safety with Apollo Client

All GraphQL operations are fully typed using TypedDocumentNode:

export const GET_CANDIDATES: TypedDocumentNode<
  CandidatesData,
  GetCandidatesQueryVariables
> = gql`...`;

πŸ“š Full API Documentation: frontend/docs/graphql-schema.md

πŸ“š Resources

πŸš€ Deployment

This project is configured for Docker deployment with the standalone output mode.

Docker Production Build

# Build production image
docker compose build --no-cache frontend

# Run in production mode
# (Comment out 'target: dev' in docker-compose.yaml first)
docker compose up -d frontend

πŸ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


Built with attention to code quality, user experience, and scalability πŸš€

About

React 19 + GraphQL admin panel

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published