// GetVisaServices Corporate Travel Portal
// Single-file React component (Tailwind CSS required)
// Instructions:
// 1. Create a React app (Vite or Create React App).
// 2. Configure TailwindCSS (https://tailwindcss.com/docs/guides/create-react-app).
// 3. Save this file as src/App.jsx and run the app.
// 4. This is a UI prototype: replace mock data and wire up real APIs (booking, auth, payments) as needed.
import React, { useState } from "react";
const mockBookings = [
{ id: 1, employee: "Asha Singh", type: "Flight", from: "DEL", to: "BOM", date: "2025-11-10", status: "Pending", cost: 12000 },
{ id: 2, employee: "Rahul Verma", type: "Hotel", from: "DEL", to: "GUR", date: "2025-10-25", status: "Approved", cost: 6000 },
{ id: 3, employee: "Priya Mehta", type: "Visa", from: "DEL", to: "DXB", date: "2025-12-02", status: "Pending", cost: 8500 },
];
const mockEmployees = [
{ id: 1, name: "Asha Singh", email: "asha@getvisaservices.in", role: "Employee" },
{ id: 2, name: "Rahul Verma", email: "rahul@getvisaservices.in", role: "Manager" },
{ id: 3, name: "Priya Mehta", email: "priya@getvisaservices.in", role: "Employee" },
];
export default function App() {
const [active, setActive] = useState("dashboard");
const [bookings, setBookings] = useState(mockBookings);
const [employees] = useState(mockEmployees);
const [search, setSearch] = useState("");
function approveBooking(id) {
setBookings((prev) => prev.map(b => b.id === id ? { ...b, status: "Approved" } : b));
}
function rejectBooking(id) {
setBookings((prev) => prev.map(b => b.id === id ? { ...b, status: "Rejected" } : b));
}
const pendingCount = bookings.filter(b => b.status === "Pending").length;
const totalCost = bookings.reduce((s, b) => s + b.cost, 0);
return (
{/* Sidebar */}
{/* Main content */}
{active === "dashboard" && (
)}
{active === "bookings" && (
)}
{active === "approvals" && (
)}
{active === "employees" &&
}
{active === "reports" &&
}
{active === "settings" &&
}
);
}
function SidebarItem({ label, id, active, setActive }) {
const isActive = active === id;
return (
);
}
function TopBar({ pendingCount, totalCost, search, setSearch }) {
return (
Welcome, Admin
Pending: {pendingCount}
Monthly Spend: ₹{totalCost}
setSearch(e.target.value)} placeholder="Search bookings or employees" className="px-3 py-2 border rounded w-72 bg-white" />
);
}
function Dashboard({ bookings, pendingCount, totalCost, setActive }) {
const recent = bookings.slice(0, 5);
return (
Dashboard
Recent Bookings
| Emp |
Type |
Date |
Status |
Cost |
{recent.map(r => (
| {r.employee} |
{r.type} |
{r.date} |
{statusBadge(r.status)} |
₹{r.cost} |
))}
);
}
function StatCard({ title, value }) {
return (
);
}
function Bookings({ bookings, approveBooking, rejectBooking }) {
return (
Bookings
| Emp |
Type |
Route |
Date |
Status |
Cost |
Action |
{bookings.map(b => (
| {b.employee} |
{b.type} |
{b.from} → {b.to} |
{b.date} |
{statusBadge(b.status)} |
₹{b.cost} |
{b.status === 'Pending' && (
<>
>
)}
|
))}
);
}
function Approvals({ bookings, approveBooking, rejectBooking }) {
const pending = bookings.filter(b => b.status === 'Pending');
return (
Approvals
{pending.length === 0 ? (
No pending approvals.
) : (
{pending.map(p => (
-
{p.employee} — {p.type}
{p.from} → {p.to} on {p.date}
₹{p.cost}
))}
)}
);
}
function Employees({ employees }) {
return (
Employees
| Name |
Email |
Role |
{employees.map(e => (
| {e.name} |
{e.email} |
{e.role} |
))}
);
}
function Reports({ bookings }) {
const total = bookings.length;
const totalCost = bookings.reduce((s, b) => s + b.cost, 0);
return (
Reports
Total Spend (₹)
{totalCost}
Booking Breakdown
{['Flight', 'Hotel', 'Visa'].map((t) => (
- {t} {bookings.filter(b => b.type === t).length}
))}
);
}
function Settings() {
return (
Settings
GetVisaServices Pvt. Ltd.
Budget limits and approval rules
);
}
function statusBadge(status) {
const map = {
Approved: 'bg-green-100 text-green-700',
Pending: 'bg-yellow-100 text-yellow-700',
Rejected: 'bg-red-100 text-red-700'
};
return
{status};
}