Microsoft 365 calendar interface displaying Sarah Jenkins' scheduled meetings on October 26, 2024, with tasks and events list

Technical Blog Article — App 55: Corporate Calendar with React, Fluent UI, TypeScript, and Vite

Introduction

Modern enterprise systems rely heavily on scheduling, meetings, event coordination, project timelines, approval sessions, operational planning, and collaborative workflows. Because of this, one of the most common interface patterns inside enterprise software is the corporate calendar dashboard.

Enterprise dashboards are data transformed into reusable UI.

  • React
  • TypeScript
  • Vite
  • Fluent UI

Enterprise dashboards are data transformed into reusable UI.

Enterprise dashboards are data transformed into reusable UI.

  • enterprise dashboard composition
  • reusable event cards
  • responsive grid layouts
  • typed data models
  • Fluent UI visual systems
  • badge-based status rendering
  • component-driven architecture
  • data-driven UI rendering

Although visually simple, this app introduces the architectural foundation behind:

  • Outlook-style dashboards
  • Microsoft Teams scheduling systems
  • SharePoint event pages
  • CRM scheduling panels
  • ERP planning systems
  • administrative calendar modules

The key React mental model remains:

Data
→ React rendering
→ Component composition
→ Enterprise interface

React applications are not built by manually manipulating HTML elements. Instead, React transforms structured data into predictable UI through declarative rendering.


1. What This App Teaches

ConceptExplanation
TypeScript interfacesPredictable event structures
Static enterprise dataData-driven rendering
Reusable componentsEvent cards reused dynamically
React propsParent passes event data
List renderingUI generated with map()
Fluent UI CardsMicrosoft-style enterprise containers
Badge appearanceVisual event state indicators
CSS GridResponsive enterprise layouts
Declarative UIInterface derived from data

This app is important because it reinforces one of the most critical React concepts:

UI should be generated from structured data.

2. Creating the Project

Create the project using Vite with the React TypeScript template.

mkdir bloco03
cd bloco03
npm create vite@latest app55-corporate-calendar -- --template react-ts
cd app55-corporate-calendar
npm install

Install Fluent UI:

npm install @fluentui/react-components @fluentui/react-icons

Why Vite?

Vite provides:

  • instant startup
  • fast Hot Module Replacement
  • optimized production builds
  • modern ES Module architecture
  • simplified React development

Official documentation:


3. Creating the Folder Structure

Create the folders:

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

Create the files:

New-Item src\models\CalendarEvent.ts -ItemType File
New-Item src\data\calendarEvents.ts -ItemType File
New-Item src\components\EventCard.tsx -ItemType File
New-Item src\components\CalendarBoard.tsx -ItemType File
New-Item artigo.md -ItemType File

Final structure:

src/
components/
EventCard.tsx
CalendarBoard.tsx
data/
calendarEvents.ts
models/
CalendarEvent.ts
styles/
App.tsx
main.tsx
index.css

This structure follows the ReactLab architectural philosophy.


4. Understanding the Model Layer

src\models\CalendarEvent.ts

export type EventStatus =
| "Confirmed"
| "Pending"
| "Canceled";
export interface CalendarEvent {
id: number;
title: string;
date: string;
time: string;
organizer: string;
location: string;
status: EventStatus;
}

This file defines the shape of every event object.

Each event must contain:

  • identifier
  • title
  • date
  • time
  • organizer
  • location
  • status

TypeScript interfaces are extremely important because they:

  • improve maintainability
  • prevent invalid data
  • improve autocomplete
  • make refactoring safer
  • scale better in enterprise projects

Without interfaces, React applications become unpredictable as they grow.

Official TypeScript documentation:


5. Understanding Static Data Rendering

src\data\calendarEvents.ts

import type { CalendarEvent }
from "../models/CalendarEvent";
export const calendarEvents: CalendarEvent[] = [
{
id: 1,
title: "Executive Strategy Meeting",
date: "Monday, May 25",
time: "09:00 AM",
organizer: "Corporate Management",
location: "Conference Room A",
status: "Confirmed",
},
{
id: 2,
title: "SharePoint Architecture Review",
date: "Tuesday, May 26",
time: "11:30 AM",
organizer: "Platform Team",
location: "Microsoft Teams",
status: "Pending",
},
];

This app intentionally uses static data.

Why?

Because the focus is:

  • rendering architecture
  • composition
  • reusable UI
  • declarative rendering

NOT:

  • APIs
  • effects
  • backend synchronization

Those topics belong to later roadmap blocks.


6. Understanding React Rendering

One of the most important ideas in React is:

React transforms data into UI.

The calendar events are not manually written as HTML.

Instead:

  • the data exists in an array
  • React loops through the array
  • components are generated dynamically

This is declarative rendering.

Official React documentation:


7. Creating the EventCard Component

src\components\EventCard.tsx

import {
Badge,
Body1,
Card,
Caption1,
Text,
Title3,
} from "@fluentui/react-components";
import type {
CalendarEvent,
} from "../models/CalendarEvent";
interface EventCardProps {
event: CalendarEvent;
}
export function EventCard({
event,
}: EventCardProps) {
return (
<Card
style={{
padding: "24px",
display: "flex",
flexDirection: "column",
gap: "16px",
}}
>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<Title3>{event.title}</Title3>
<Badge appearance="filled">
{event.status}
</Badge>
</div>
<Body1>
Enterprise scheduling event.
</Body1>
<Text>Date: {event.date}</Text>
<Text>Time: {event.time}</Text>
<Text>Organizer: {event.organizer}</Text>
<Caption1>
Location: {event.location}
</Caption1>
</Card>
);
}

8. Understanding Props

The component receives:

event: CalendarEvent;

through props.

This follows the React architecture model:

Parent component
→ passes data
→ child component renders UI

Props are the inputs of React components.

This allows:

  • reusability
  • composition
  • predictable rendering
  • isolated responsibilities

Official documentation:


9. Why Components Matter

EventCard has exactly one responsibility:

Render one event.

Good React architecture is built around responsibility separation.

A component should answer:

What UI am I responsible for?

This app uses:

  • EventCard → one event
  • CalendarBoard → event collection
  • App → page layout

This architecture scales much better than giant monolithic files.


10. Understanding Fluent UI Cards

The app uses Fluent UI cards:

<Card>

Fluent UI provides:

  • Microsoft visual identity
  • spacing systems
  • accessibility
  • typography consistency
  • enterprise styling
  • keyboard support

Official documentation:


11. Understanding Badge Rendering

The app uses:

<Badge>

to display event status.

Enterprise applications frequently use badges for:

  • workflow state
  • approvals
  • priorities
  • alerts
  • progress
  • scheduling state

This small UI pattern is extremely common in:

  • SharePoint systems
  • CRMs
  • ticket systems
  • admin portals

12. Creating the Calendar Grid

src\components\CalendarBoard.tsx

import { calendarEvents }
from "../data/calendarEvents";
import { EventCard }
from "./EventCard";
export function CalendarBoard() {
return (
<section
style={{
display: "grid",
gridTemplateColumns:
"repeat(auto-fit, minmax(320px, 1fr))",
gap: "24px",
marginTop: "32px",
}}
>
{calendarEvents.map((event) => (
<EventCard
key={event.id}
event={event}
/>
))}
</section>
);
}

13. Understanding map()

This line is critical:

calendarEvents.map(...)

React transforms arrays into UI.

Conceptually:

event 1 → EventCard
event 2 → EventCard
event 3 → EventCard

This is one of the core React mental models.

You do not manually create HTML repeatedly.

You describe:

  • how data should become UI

React handles:

  • DOM generation
  • updates
  • reconciliation

14. Understanding React Keys

key={event.id}

Keys help React identify elements efficiently.

Without stable keys:

  • rendering becomes inefficient
  • React warnings appear
  • updates become less predictable

Keys are mandatory in dynamic lists.

Official documentation:


15. Understanding CSS Grid

The layout uses:

display: "grid"

combined with:

gridTemplateColumns:
"repeat(auto-fit, minmax(320px, 1fr))"

This creates a responsive enterprise layout.

Meaning:

  • each card must be at least 320px
  • the grid automatically adjusts columns
  • extra space is distributed equally

This pattern is extremely common in:

  • dashboards
  • analytics portals
  • SharePoint layouts
  • admin systems

16. Creating the Root App

src\App.tsx

import {
Text,
Title1,
} from "@fluentui/react-components";
import { CalendarBoard }
from "./components/CalendarBoard";
function App() {
return (
<main
style={{
minHeight: "100vh",
backgroundColor: "#f5f5f5",
padding: "48px",
}}
>
<section
style={{
maxWidth: "1400px",
margin: "0 auto",
}}
>
<Title1>
Corporate Calendar
</Title1>
<Text>
Enterprise scheduling dashboard.
</Text>
<CalendarBoard />
</section>
</main>
);
}
export default App;

17. Understanding Layout Composition

This structure creates:

Page
Header
Description
Event Grid

This composition style mirrors real enterprise systems.

Professional React applications are:

  • composed
  • modular
  • hierarchical

NOT:

  • giant files
  • manually duplicated HTML

18. Understanding main.tsx

src\main.tsx

import React from "react";
import ReactDOM from "react-dom/client";
import {
FluentProvider,
webLightTheme,
} from "@fluentui/react-components";
import App from "./App";
import "./index.css";
ReactDOM.createRoot(
document.getElementById("root")!
).render(
<React.StrictMode>
<FluentProvider
theme={webLightTheme}
>
<App />
</FluentProvider>
</React.StrictMode>
);

This file:

  • connects React to HTML
  • activates Fluent UI theming
  • mounts the application

The critical line is:

<FluentProvider theme={webLightTheme}>

This enables:

  • Microsoft styling
  • typography
  • spacing
  • Fluent UI themes
  • accessibility behavior

19. Understanding Why There Is No State

This app intentionally does NOT use:

  • useState
  • useEffect

Why?

Because the UI is static.

According to React Learn:

Only introduce state when the UI must change dynamically.

Official documentation:

This is important because beginners often add unnecessary state.

Good React architecture avoids unnecessary complexity.


20. Running the App

Development:

npm run dev

Production validation:

npm run build

Preview production build:

npm run preview

21. Technical Summary

ConceptExplanation
TypeScript InterfacePredictable event data
PropsParent-to-child communication
map()Declarative list rendering
Fluent UI CardEnterprise UI container
BadgeEvent state visualization
CSS GridResponsive dashboard layout
Component CompositionUI split into responsibilities
Static RenderingUI derived from fixed data
FluentProviderMicrosoft design system

22. Concept Table

ConceptFileResponsibility
Event modelCalendarEvent.tsDefines event structure
Event datacalendarEvents.tsStores scheduling data
Reusable cardEventCard.tsxRenders one event
Grid rendererCalendarBoard.tsxOrganizes event cards
Root pageApp.tsxMain layout
React entry pointmain.tsxMounts the app
Global CSSindex.cssResets layout

23. Official Documentation

React

Fluent UI

Tooling


Final Architectural Insight

The most important lesson from App 55 is:

Enterprise dashboards are data transformed into reusable UI.

Professional React applications scale because:

  • components are isolated
  • data is structured
  • rendering is declarative
  • UI is composed from reusable pieces

This same architecture later evolves into:

  • Outlook dashboards
  • SharePoint portals
  • CRM systems
  • scheduling platforms
  • Microsoft 365 enterprise applications

Current Project Progress

BlockAppNameStatus
Block 101Hello React FluentCompleted
Block 102Profile CardCompleted
Block 103Product ListCompleted
Block 104Microsoft Style User CardCompleted
Block 105Static DashboardCompleted
Block 106Corporate Sidebar MenuCompleted
Block 107Visual Task ListCompleted
Block 108Timeline EventsCompleted
Block 109Employee TableCompleted
Block 110Email ListCompleted
Block 111Grid of CardsCompleted
Block 112Image GalleryCompleted
Block 113Movie CatalogCompleted
Block 114Football TeamsCompleted
Block 115News PageCompleted
Block 116Financial DashboardCompleted
Block 117SharePoint Style LayoutCompleted
Block 118File ExplorerCompleted
Block 119Corporate PortalCompleted
Block 120Microsoft Style Landing PageCompleted
Block 221Modern CounterCompleted
Block 222Toggle ThemeCompleted
Block 223React CalculatorCompleted
Block 224Login FormCompleted
Block 225User RegistrationCompleted
Block 226Complete ToDo ListCompleted
Block 227Shopping ListCompleted
Block 228Product FilterCompleted
Block 229Employee SearchCompleted
Block 230Shopping CartCompleted
Block 231Grade SimulatorCompleted
Block 232Inventory ControlCompleted
Block 233Contact AgendaCompleted
Block 234Currency ConverterCompleted
Block 235BMI CalculatorCompleted
Block 236Installment SimulatorCompleted
Block 237Voting PanelCompleted
Block 238Interactive QuizCompleted
Block 239Team ManagerCompleted
Block 240Dynamic DashboardCompleted
Block 341Microsoft Style LoginCompleted
Block 342Corporate FormCompleted
Block 343Tabs NavigationCompleted
Block 344Dialog ManagerCompleted
Block 345Executive DashboardCompleted
Block 346DataGrid CatalogCompleted
Block 347Enterprise User ListCompleted
Block 348Sidebar NavigationCompleted
Block 349Corporate HeaderCompleted
Block 350Professional ToolbarCompleted
Block 351Notification CenterCompleted
Block 352Administrative PanelCompleted
Block 353Ticket ManagerCompleted
Block 354Approval SystemCompleted
Block 355Corporate CalendarCurrent
Block 356SharePoint Inspired DashboardNext

Edvaldo Guimrães Filho Avatar

Published by