Technical Blog Article — App 57: Enterprise Project Management Dashboard with React, Fluent UI, TypeScript, and Vite

Introduction

Modern enterprise systems are heavily centered around dashboards. Whether inside Microsoft ecosystems, CRMs, PMO portals, SharePoint intranets, analytics systems, or administrative panels, dashboards are the primary interface for monitoring information, visualizing metrics, tracking workflows, and organizing operational data.

In App 57 — Project Management Dashboard, we build a Microsoft-style enterprise project dashboard using:

  • React
  • TypeScript
  • Vite
  • Fluent UI

This application belongs to Block 3 — Professional Fluent UI Applications, where the ReactLab roadmap transitions from basic rendering and state exercises into enterprise-grade UI composition and scalable architecture.

The main purpose of this app is to teach:

  • dashboard architecture
  • reusable enterprise components
  • project visualization
  • responsive card grids
  • Fluent UI composition
  • data-driven rendering
  • component isolation
  • Microsoft design system patterns

The most important architectural principle introduced is:

Enterprise UI should be composed from reusable data-driven components.

This app intentionally avoids:

  • APIs
  • authentication
  • useEffect
  • reducers
  • async operations

The goal is mastering enterprise rendering architecture before introducing external systems in Block 4.


Understanding the Purpose of a Dashboard

A dashboard is not simply “a page with cards.”

In enterprise systems, dashboards are responsible for:

  • organizing information hierarchically
  • exposing operational status
  • surfacing KPIs
  • displaying workflow progress
  • summarizing business operations
  • improving decision visibility

Examples include:

  • Azure DevOps boards
  • Microsoft Planner
  • Power BI dashboards
  • SharePoint project portals
  • Service management systems
  • ticketing dashboards
  • ERP project management modules

The dashboard pattern is one of the most repeated enterprise UI architectures in frontend engineering.


React Mental Model Introduced

This application reinforces the core React principle:

UI = function(data)

The dashboard is not manually constructed element-by-element.

Instead:

  • project data exists
  • React maps the data
  • components render the UI
  • Fluent UI styles the interface

This is declarative rendering.

React is NOT:

  • manual DOM manipulation
  • imperative UI programming
  • jQuery-style updates

React IS:

  • component composition
  • declarative rendering
  • predictable UI architecture
  • state/data-driven interfaces

Official React guidance:


Creating the Project

PowerShell Commands

mkdir bloco03
cd bloco03
npm create vite@latest app57-project-management-dashboard -- --template react-ts
cd app57-project-management-dashboard
npm install
npm install @fluentui/react-components @fluentui/react-icons

Why Vite Is Used

The project uses Vite because modern React development requires:

  • fast startup
  • instant hot reload
  • modern ES Modules
  • optimized builds
  • simplified tooling

Unlike older systems like Create React App, Vite serves files using native ES Modules during development.

Advantages:

  • near-instant startup
  • faster rebuilds
  • lightweight configuration
  • excellent TypeScript support

Official documentation:


Creating the Folder Structure

PowerShell

mkdir src\components
mkdir src\data
mkdir src\models
mkdir src\styles

Create files:

New-Item src\models\Project.ts -ItemType File
New-Item src\data\projects.ts -ItemType File
New-Item src\components\DashboardHeader.tsx -ItemType File
New-Item src\components\ProjectCard.tsx -ItemType File
New-Item src\components\ProjectGrid.tsx -ItemType File
New-Item artigo.md -ItemType File

Final Project Structure

app57-project-management-dashboard/
src/
components/
DashboardHeader.tsx
ProjectCard.tsx
ProjectGrid.tsx
data/
projects.ts
models/
Project.ts
styles/
App.tsx
main.tsx
index.css

This structure follows the ReactLab architecture philosophy:

  • separation of concerns
  • reusable components
  • scalable organization
  • predictable growth

Understanding the Model Layer

src\models\Project.ts

export type ProjectStatus =
| "Completed"
| "In Progress"
| "Pending";
export interface Project {
id: number;
title: string;
manager: string;
department: string;
progress: number;
status: ProjectStatus;
}

Why TypeScript Models Matter

This file defines the shape of the dashboard data.

Without models:

  • objects become inconsistent
  • refactoring becomes dangerous
  • enterprise systems become harder to scale

TypeScript guarantees:

  • all projects share the same structure
  • invalid data is caught early
  • autocomplete works correctly
  • architecture becomes predictable

This is one of the reasons TypeScript dominates enterprise React ecosystems.

Official documentation:


Creating the Dashboard Data

src\data\projects.ts

import type { Project } from "../models/Project";
export const projects: Project[] = [
{
id: 1,
title: "SharePoint Migration",
manager: "Enterprise Team",
department: "Infrastructure",
progress: 85,
status: "In Progress",
},
{
id: 2,
title: "CRM Modernization",
manager: "Business Solutions",
department: "Sales",
progress: 100,
status: "Completed",
},
{
id: 3,
title: "Power BI Analytics",
manager: "Analytics Team",
department: "Finance",
progress: 45,
status: "In Progress",
},
{
id: 4,
title: "HR Self-Service Portal",
manager: "Internal Systems",
department: "Human Resources",
progress: 15,
status: "Pending",
},
];

Why Static Data Is Important First

This application intentionally uses static data.

Why?

Because React rendering must be understood BEFORE introducing:

  • APIs
  • fetch
  • async loading
  • useEffect
  • server synchronization

The rendering pipeline becomes:

Data
→ React components
→ Dashboard UI

This is foundational React architecture.


Creating the Dashboard Header

src\components\DashboardHeader.tsx

import {
Card,
Text,
Title1,
} from "@fluentui/react-components";
export function DashboardHeader() {
return (
<Card
style={{
padding: "32px",
marginBottom: "32px",
}}
>
<Title1>
Enterprise Project Dashboard
</Title1>
<Text>
Microsoft-style project management dashboard built with
React, TypeScript, Vite, and Fluent UI.
</Text>
</Card>
);
}

Why Enterprise Headers Matter

Large applications should never place everything in one file.

The header becomes:

  • reusable
  • isolated
  • maintainable
  • independently scalable

This is React composition.

Instead of:

  • giant monolithic pages

React encourages:

  • small focused components

Official React documentation:


Creating the Project Card

src\components\ProjectCard.tsx

import {
Badge,
Card,
ProgressBar,
Text,
Title3,
} from "@fluentui/react-components";
import type { Project } from "../models/Project";
interface ProjectCardProps {
project: Project;
}
function getBadgeAppearance(status: Project["status"]) {
if (status === "Completed") {
return "filled" as const;
}
if (status === "In Progress") {
return "tint" as const;
}
return "outline" as const;
}
export function ProjectCard({
project,
}: ProjectCardProps) {
return (
<Card
style={{
padding: "24px",
display: "flex",
flexDirection: "column",
gap: "16px",
}}
>
<Title3>{project.title}</Title3>
<Text>
Manager: {project.manager}
</Text>
<Text>
Department: {project.department}
</Text>
<Badge appearance={getBadgeAppearance(project.status)}>
{project.status}
</Badge>
<ProgressBar
value={project.progress / 100}
/>
<Text>
Progress: {project.progress}%
</Text>
</Card>
);
}

Understanding Derived UI

This section is extremely important:

getBadgeAppearance(project.status)

The UI appearance derives from project data.

This is declarative rendering.

We are NOT manually changing colors with imperative DOM logic.

Instead:

  • status changes
  • React re-renders
  • UI updates automatically

This is one of React’s most important concepts.


Understanding the ProgressBar

<ProgressBar value={project.progress / 100} />

The Fluent UI ProgressBar expects values between:

  • 0
  • 1

So:

85%

becomes:

0.85

This is normalized rendering.

Official Fluent UI docs:


Creating the Dashboard Grid

src\components\ProjectGrid.tsx

import { projects } from "../data/projects";
import { ProjectCard } from "./ProjectCard";
export function ProjectGrid() {
return (
<div
style={{
display: "grid",
gridTemplateColumns:
"repeat(auto-fit, minmax(320px, 1fr))",
gap: "24px",
}}
>
{projects.map((project) => (
<ProjectCard
key={project.id}
project={project}
/>
))}
</div>
);
}

Why map() Is Fundamental in React

This line is one of the most important lines in the entire application:

projects.map((project) => (

React converts arrays into UI.

Conceptually:

Project object
→ React component
→ Dashboard card

This is declarative rendering.

Official documentation:


Why key={project.id} Matters

key={project.id}

Keys help React identify list elements efficiently.

Without stable keys:

  • rendering becomes inefficient
  • DOM updates become unpredictable
  • React warnings appear

Keys are essential in dynamic rendering.


Creating the Root App

src\App.tsx

import {
FluentProvider,
webLightTheme,
} from "@fluentui/react-components";
import { DashboardHeader } from "./components/DashboardHeader";
import { ProjectGrid } from "./components/ProjectGrid";
function App() {
return (
<FluentProvider theme={webLightTheme}>
<main
style={{
minHeight: "100vh",
backgroundColor: "#f5f5f5",
padding: "48px",
boxSizing: "border-box",
}}
>
<section
style={{
maxWidth: "1400px",
margin: "0 auto",
}}
>
<DashboardHeader />
<ProjectGrid />
</section>
</main>
</FluentProvider>
);
}
export default App;

Why FluentProvider Is Critical

<FluentProvider theme={webLightTheme}>

This activates:

  • Microsoft design tokens
  • Fluent UI typography
  • spacing system
  • accessibility behavior
  • theme consistency

Without it:

  • Fluent UI components lose correct styling

Official documentation:


Creating main.tsx

src\main.tsx

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
ReactDOM.createRoot(
document.getElementById("root")!
).render(
<React.StrictMode>
<App />
</React.StrictMode>
);

Creating index.css

src\index.css

body {
margin: 0;
font-family: "Segoe UI", Arial, sans-serif;
}
* {
box-sizing: border-box;
}

Running the Application

Development server:

npm run dev

Production validation:

npm run build

Preview production build:

npm run preview

Complete Rendering Flow

main.tsx
→ renders App
App
→ renders DashboardHeader
→ renders ProjectGrid
ProjectGrid
→ loops through project data
projects.map(...)
→ renders ProjectCard components
ProjectCard
→ renders Fluent UI enterprise cards

This is enterprise React architecture.


Why There Is No useEffect

This app intentionally avoids:

  • APIs
  • timers
  • subscriptions
  • browser synchronization

According to:

Effects should synchronize with external systems.

This dashboard is purely derived from local data.

Therefore:

  • useEffect would be unnecessary
  • direct rendering is correct

Enterprise Architecture Introduced

This app introduces the architecture used in real enterprise dashboards:

Dashboard
Header
Grid
Cards
Metrics
Status
Progress

This later evolves into:

  • PMO systems
  • analytics dashboards
  • SharePoint portals
  • admin systems
  • workflow dashboards
  • reporting platforms

Technical Summary

ConceptExplanation
TypeScript modelPredictable project structure
Static dataDashboard source
map() renderingData transformed into UI
Fluent UI CardEnterprise visual container
ProgressBarProgress visualization
BadgeStatus representation
CSS GridResponsive layout
Component compositionSmall reusable UI pieces
Declarative renderingUI derived from data
Pure componentsStateless enterprise rendering

Concept Table

ConceptFilePurpose
Project modelProject.tsDefines project structure
Dashboard dataprojects.tsProvides UI content
Header componentDashboardHeader.tsxEnterprise dashboard header
Project cardProjectCard.tsxReusable project visualization
Grid componentProjectGrid.tsxResponsive dashboard layout
FluentProviderApp.tsxGlobal Fluent UI theme
ProgressBarProjectCard.tsxProject progress visualization
Badge renderingProjectCard.tsxStatus UI

Official Documentation

React

Fluent UI

Tooling


Final Architectural Insight

The most important lesson from App 57 is:

Enterprise dashboards are reusable component trees driven by data.

Professional React applications should never be:

  • giant pages
  • duplicated HTML
  • manually manipulated UI

Instead:

Data
→ reusable components
→ declarative rendering
→ enterprise architecture

This is the foundation of:

  • Microsoft dashboards
  • SharePoint-style portals
  • PMO systems
  • analytics applications
  • enterprise React ecosystems

Current Project Progress

BlockAppNameStatus
Block 101–20Fundamentals and UICompleted
Block 221–40Interactivity and StateCompleted
Block 341Microsoft Style LoginCompleted
Block 342Corporate FormCompleted
Block 343Tabs NavigationCompleted
Block 344Dialog ManagerCompleted
Block 345Executive DashboardCompleted
Block 346DataGrid CatalogCompleted
Block 347Enterprise User ListCompleted
Block 348Navigable SidebarCompleted
Block 349Corporate HeaderCompleted
Block 350Professional ToolbarCompleted
Block 351Notification SystemCompleted
Block 352Administrative PanelCompleted
Block 353Ticket ManagerCompleted
Block 354Approval SystemCompleted
Block 355Corporate CalendarCompleted
Block 356SharePoint Inspired DashboardCompleted
Block 357Enterprise Project Management DashboardCurrent
Block 358Support Ticket ControlNext
Edvaldo Guimrães Filho Avatar

Published by