0% found this document useful (0 votes)
61 views48 pages

App Management System: React Typescript Vite Tailwind Css Postcss Eslint Node - Js & NPM

The document outlines the significance of an App Management System in efficiently managing the lifecycle of applications, enhancing deployment, monitoring, and maintenance processes. It highlights core functionalities such as automated deployment, real-time analytics, and robust security measures, aimed at optimizing workflows and user satisfaction. The project utilizes modern technologies like React, TypeScript, and Node.js to create a user-friendly interface and comprehensive reporting tools for informed decision-making.

Uploaded by

saivijay270205
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
61 views48 pages

App Management System: React Typescript Vite Tailwind Css Postcss Eslint Node - Js & NPM

The document outlines the significance of an App Management System in efficiently managing the lifecycle of applications, enhancing deployment, monitoring, and maintenance processes. It highlights core functionalities such as automated deployment, real-time analytics, and robust security measures, aimed at optimizing workflows and user satisfaction. The project utilizes modern technologies like React, TypeScript, and Node.js to create a user-friendly interface and comprehensive reporting tools for informed decision-making.

Uploaded by

saivijay270205
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 48

INTRODUCTION

In today’s fast-paced digital world, applications play a critical role in


enabling businesses to operate efficiently and connect with users
effectively. However, managing the complete lifecycle of an
application—from development and deployment to monitoring,
maintenance, and updates—can be a complex and resource-intensive
task. This is where an App Management System proves to be
indispensable.

An App Management System provides a unified platform to oversee


all aspects of application management. It empowers developers and
organizations with tools for seamless deployment, real-time
performance tracking, error detection, and security management. By
automating repetitive tasks and offering valuable analytics, it
minimizes operational overhead while maximizing efficiency.

The system is designed to meet the needs of modern businesses,


ensuring that applications remain secure, scalable, and responsive to
user demands. Whether it’s simplifying workflows, resolving issues
proactively, or providing insights for strategic decision-making, an
App Management System equips organizations with the capabilities
they need to thrive in a competitive app-driven ecosystem.

PROJECT STACK :

 React (Frontend Framework)


 TypeScript (Static Typing)
 Vite (Frontend Build Tool)
 Tailwind CSS (Utility-first CSS)
 PostCSS (CSS Processing)
 ESLint (Linting)
 Node.js & NPM (Environment & Package Manager)
Index
1. INTRODUCTION
2. PROJECT STACK
3. ABSTRACT
4. OVERVIEW
5. CODING
6. CONCLUSION
APP MANAGEMENT SYSTEM
Abstract:

In the rapidly evolving landscape of digital applications, efficient


management and optimization have become essential for sustaining
high performance, scalability, and security. The App Management
System is a comprehensive solution designed to centralize and
streamline the lifecycle of application development, deployment,
monitoring, and maintenance. By incorporating cutting-edge
technologies, the system ensures seamless integration with diverse
platforms and third-party tools, enabling developers and organizations
to address complex challenges effectively.

Core functionalities include automated deployment, real-time


performance analytics, and proactive error tracking, all of which
contribute to minimizing downtime and maximizing user satisfaction.
Additionally, robust user access control mechanisms ensure data
security and controlled access to application resources. The system
provides an intuitive interface tailored for easy navigation,
empowering users with varying levels of technical expertise.
Enhanced reporting capabilities and visualized analytics offer
actionable insights, facilitating informed decision-making and
strategic planning.This App Management System is an indispensable
tool for businesses and developers aiming to optimize application
workflows, ensure reliability, and elevate user experiences in an
increasingly app-driven world.

Overview:

An elaborated overview of the App Management System outlines


its advanced functionalities and strategic importance in simplifying
and enhancing the app lifecycle:
The App Management System serves as a versatile, centralized
platform that streamlines the processes of app deployment,
monitoring, maintenance, and optimization. It empowers developers
and businesses to efficiently manage applications, ensuring seamless
functionality and adaptability in dynamic digital environments.

The system's automation features facilitate error-free and swift app


deployments, reducing the operational workload. Real-time
performance analytics and monitoring tools provide instant insights
into user behavior and app health, enabling proactive issue resolution.
Error tracking mechanisms are integrated to detect and resolve
bottlenecks and crashes, ensuring minimal disruption to the end-user
experience.

Security remains a top priority, with robust user access control and
authentication systems to safeguard sensitive data and app resources.
The system is designed to be scalable, allowing applications to grow
alongside increasing demands without compromising performance.

A highly customizable and user-friendly interface ensures that the


system caters to users with varying levels of technical expertise.
Additionally, its integration capabilities with third-party tools and
platforms enhance flexibility and streamline workflows.
Comprehensive reporting and analytics functionalities provide
actionable insights to inform decision-making and support continuous
improvement.

Overall, the App Management System is an essential tool for


businesses and developers striving to achieve operational efficiency,
scalability, and superior user satisfaction in the competitive world of
applications.

CODING :

import { Toaster } from "@/components/ui/toaster";


import { Toaster as Sonner } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { QueryClient, QueryClientProvider } from "@tanstack/react-
query";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Index from "./pages/Index";
import ApplicationDetail from "./pages/ApplicationDetail";
import AddApplication from "./pages/AddApplication";
import NotFound from "./pages/NotFound";

const queryClient = new QueryClient();

const App = () => (


<QueryClientProvider client={queryClient}>
<TooltipProvider>
<Toaster />
<Sonner />
<BrowserRouter>
<Routes>
<Route path="/" element={<Index />} />
<Route path="/app/:id" element={<ApplicationDetail />} />
<Route path="/add-application" element={<AddApplication
/>} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
</TooltipProvider>
</QueryClientProvider>
);

export default App;


export type AppStatus = 'online' | 'offline' | 'maintenance' |
'warning';

export interface AppMetrics {


cpuUsage: number;
memoryUsage: number;
uptimePercentage: number;
responseTime: number;
}

export interface AppResource {


id: string;
name: string;
type: 'database' | 'storage' | 'compute' | 'api';
status: AppStatus;
}

export interface Application {


id: string;
name: string;
description: string;
status: AppStatus;
environment: 'production' | 'staging' | 'development';
owner: string;
createdAt: string;
updatedAt: string;
version: string;
url?: string;
logoUrl?: string;
tags: string[];
metrics: AppMetrics;
resources: AppResource[];
}
import { Application } from "@/types/app";

export const applications: Application[] = [


{
id: "app-1",
name: "Customer Portal",
description: "Main customer-facing web application",
status: "online",
environment: "production",
owner: "Frontend Team",
createdAt: "2023-01-15T08:30:00Z",
updatedAt: "2023-10-22T14:45:00Z",
version: "2.4.1",
url: "https://customer.example.com",
tags: ["frontend", "react", "critical"],
metrics: {
cpuUsage: 24,
memoryUsage: 45,
uptimePercentage: 99.98,
responseTime: 230,
},
resources: [
{
id: "res-1",
name: "Customer Database",
type: "database",
status: "online",
},
{
id: "res-2",
name: "S3 Storage",
type: "storage",
status: "online",
},
],
},
{
id: "app-2",
name: "Admin Dashboard",
description: "Administrative dashboard for internal use",
status: "online",
environment: "production",
owner: "Admin Team",
createdAt: "2023-02-10T10:15:00Z",
updatedAt: "2023-10-20T11:30:00Z",
version: "1.8.5",
url: "https://admin.example.com",
tags: ["frontend", "vue", "internal"],
metrics: {
cpuUsage: 18,
memoryUsage: 32,
uptimePercentage: 99.95,
responseTime: 180,
},
resources: [
{
id: "res-3",
name: "Admin Database",
type: "database",
status: "online",
},
],
},
{
id: "app-3",
name: "Payment Service",
description: "Microservice handling payment processing",
status: "warning",
environment: "production",
owner: "Backend Team",
createdAt: "2023-03-05T14:20:00Z",
updatedAt: "2023-10-21T09:10:00Z",
version: "3.2.0",
tags: ["backend", "node", "critical"],
metrics: {
cpuUsage: 67,
memoryUsage: 72,
uptimePercentage: 98.76,
responseTime: 450,
},
resources: [
{
id: "res-4",
name: "Payment Database",
type: "database",
status: "online",
},
{
id: "res-5",
name: "Payment API",
type: "api",
status: "warning",
},
],
},
{
id: "app-4",
name: "Analytics Platform",
description: "Data analytics and reporting platform",
status: "offline",
environment: "staging",
owner: "Data Team",
createdAt: "2023-04-12T09:45:00Z",
updatedAt: "2023-10-19T16:20:00Z",
version: "0.9.2",
url: "https://analytics-staging.example.com",
tags: ["frontend", "react", "data"],
metrics: {
cpuUsage: 0,
memoryUsage: 0,
uptimePercentage: 0,
responseTime: 0,
},
resources: [
{
id: "res-6",
name: "Analytics Database",
type: "database",
status: "offline",
},
{
id: "res-7",
name: "Analytics Compute",
type: "compute",
status: "offline",
},
],
},
{
id: "app-5",
name: "Inventory API",
description: "RESTful API for inventory management",
status: "maintenance",
environment: "development",
owner: "Backend Team",
createdAt: "2023-05-20T11:30:00Z",
updatedAt: "2023-10-18T13:40:00Z",
version: "0.5.1",
tags: ["backend", "java", "api"],
metrics: {
cpuUsage: 5,
memoryUsage: 12,
uptimePercentage: 92.30,
responseTime: 350,
},
resources: [
{
id: "res-8",
name: "Inventory Database",
type: "database",
status: "maintenance",
},
],
},
{
id: "app-6",
name: "Marketing Website",
description: "Company marketing website",
status: "online",
environment: "production",
owner: "Marketing Team",
createdAt: "2023-06-01T15:00:00Z",
updatedAt: "2023-10-17T10:15:00Z",
version: "4.2.3",
url: "https://www.example.com",
tags: ["frontend", "static", "public"],
metrics: {
cpuUsage: 12,
memoryUsage: 25,
uptimePercentage: 99.99,
responseTime: 120,
},
resources: [
{
id: "res-9",
name: "CDN",
type: "storage",
status: "online",
},
],
},
];

export const getApplicationById = (id: string): Application |


undefined => {
return applications.find(app => app.id === id);
};

import { cn } from "@/lib/utils";


import { AppStatus } from "@/types/app";

interface StatusBadgeProps {
status: AppStatus;
showText?: boolean;
className?: string;
}

const StatusBadge = ({ status, showText = true, className }:


StatusBadgeProps) => {
const statusConfig = {
online: {
color: "bg-emerald-500",
text: "Online",
},
offline: {
color: "bg-red-500",
text: "Offline",
},
maintenance: {
color: "bg-amber-500",
text: "Maintenance",
},
warning: {
color: "bg-orange-500",
text: "Warning",
},
};

const config = statusConfig[status];

return (
<div className={cn("flex items-center gap-2", className)}>
<div className={cn("h-2.5 w-2.5 rounded-full", config.color)} />
{showText && <span className="text-sm font-
medium">{config.text}</span>}
</div>
);
};

export default StatusBadge;

import { Card, CardContent, CardHeader, CardTitle } from


"@/components/ui/card";
import { AppMetrics } from "@/types/app";
import { Activity, Clock, Cpu, Memory } from "lucide-react";
import { Progress } from "@/components/ui/progress";

interface MetricsCardProps {
metrics: AppMetrics;
className?: string;
}
const MetricsCard = ({ metrics, className }: MetricsCardProps) => {
return (
<Card className={className}>
<CardHeader>
<CardTitle className="text-lg">Performance
Metrics</CardTitle>
</CardHeader>
<CardContent className="grid gap-4 md:grid-cols-2">
<div className="flex items-start space-x-3">
<Cpu className="h-5 w-5 text-muted-foreground" />
<div className="space-y-1.5">
<h4 className="text-sm font-medium">CPU Usage</h4>
<div className="space-y-2">
<Progress value={metrics.cpuUsage} className="h-1.5" />
<span className="text-xs text-muted-
foreground">{metrics.cpuUsage}%</span>
</div>
</div>
</div>

<div className="flex items-start space-x-3">


<Memory className="h-5 w-5 text-muted-foreground" />
<div className="space-y-1.5">
<h4 className="text-sm font-medium">Memory Usage</h4>
<div className="space-y-2">
<Progress value={metrics.memoryUsage} className="h-
1.5" />
<span className="text-xs text-muted-
foreground">{metrics.memoryUsage}%</span>
</div>
</div>
</div>

<div className="flex items-start space-x-3">


<Activity className="h-5 w-5 text-muted-foreground" />
<div className="space-y-1.5">
<h4 className="text-sm font-medium">Uptime</h4>
<div className="space-y-2">
<Progress value={metrics.uptimePercentage} className="h-
1.5" />
<span className="text-xs text-muted-
foreground">{metrics.uptimePercentage.toFixed(2)}%</span>
</div>
</div>
</div>

<div className="flex items-start space-x-3">


<Clock className="h-5 w-5 text-muted-foreground" />
<div className="space-y-1.5">
<h4 className="text-sm font-medium">Response Time</h4>
<div className="space-y-2">
<Progress value={Math.min(metrics.responseTime / 10, 100)}
className="h-1.5" />
<span className="text-xs text-muted-
foreground">{metrics.responseTime} ms</span>
</div>
</div>
</div>
</CardContent>
</Card>
);
};

export default MetricsCard;

import { Application } from "@/types/app";


import { Card, CardContent, CardFooter, CardHeader } from
"@/components/ui/card";
import StatusBadge from "./StatusBadge";
import { Badge } from "@/components/ui/badge";
import { Link } from "react-router-dom";
import { ArrowUpRight, Server } from "lucide-react";

interface AppCardProps {
app: Application;
}

const AppCard = ({ app }: AppCardProps) => {


const getEnvironmentColor = (env: string) => {
switch (env) {
case "production":
return "bg-blue-100 text-blue-800";
case "staging":
return "bg-purple-100 text-purple-800";
case "development":
return "bg-green-100 text-green-800";
default:
return "bg-gray-100 text-gray-800";
}
};

return (
<Card className="overflow-hidden transition-all hover:shadow-
md">
<CardHeader className="flex flex-row items-center justify-
between pb-2 pt-4">
<div className="flex items-center space-x-2">
{app.logoUrl ? (
<img src={app.logoUrl} alt={app.name} className="h-6 w-
6" />
):(
<Server className="h-6 w-6 text-muted-foreground" />
)}
<h3 className="font-semibold">{app.name}</h3>
</div>
<StatusBadge status={app.status} />
</CardHeader>
<CardContent className="pb-3">
<p className="mb-3 text-sm text-muted-foreground line-
clamp-2">{app.description}</p>
<div className="space-y-2">
<div className="flex items-center justify-between text-sm">
<span className="text-muted-foreground">Version:</span>
<span>{app.version}</span>
</div>
<div className="flex items-center justify-between text-sm">
<span
className="text-muted-foreground">Environment:</span>
<Badge variant="outline"
className={getEnvironmentColor(app.environment)}>
{app.environment}
</Badge>
</div>
</div>
</CardContent>
<CardFooter className="flex justify-between pt-0">
<div className="flex flex-wrap gap-1">
{app.tags.slice(0, 2).map((tag) => (
<Badge key={tag} variant="secondary" className="text-xs">
{tag}
</Badge>
))}
{app.tags.length > 2 && (
<Badge variant="secondary" className="text-xs">
+{app.tags.length - 2}
</Badge>
)}
</div>
<Link
to={`/app/${app.id}`}
className="inline-flex items-center text-sm font-medium text-
primary hover:underline"
>
Details
<ArrowUpRight className="ml-1 h-4 w-4" />
</Link>
</CardFooter>
</Card>
);
};

export default AppCard;

import { Input } from "@/components/ui/input";


import { Button } from "@/components/ui/button";
import { Search, X } from "lucide-react";
import { useEffect, useState } from "react";

interface SearchBarProps {
onSearch: (term: string) => void;
initialValue?: string;
placeholder?: string;
className?: string;
}

const SearchBar = ({
onSearch,
initialValue = "",
placeholder = "Search applications...",
className,
}: SearchBarProps) => {
const [searchTerm, setSearchTerm] = useState(initialValue);

useEffect(() => {
setSearchTerm(initialValue);
}, [initialValue]);

const handleSearch = (e: React.FormEvent) => {


e.preventDefault();
onSearch(searchTerm);
};

const clearSearch = () => {


setSearchTerm("");
onSearch("");
};

return (
<form onSubmit={handleSearch} className={`relative $
{className}`}>
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-
1/2 text-muted-foreground" />
<Input
type="text"
placeholder={placeholder}
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-10 pr-12"
/>
{searchTerm && (
<Button
type="button"
variant="ghost"
size="icon"
className="absolute right-10 top-1/2 h-6 w-6 -translate-y-1/2
text-muted-foreground"
onClick={clearSearch}
>
<X className="h-4 w-4" />
</Button>
)}
<Button type="submit" size="icon" className="absolute right-1
top-1/2 h-7 w-7 -translate-y-1/2">
<Search className="h-4 w-4" />
</Button>
</form>
);
};

export default SearchBar;

import { Button } from "@/components/ui/button";


import { Link } from "react-router-dom";
import { Plus, Settings, Bell, User } from "lucide-react";
import { DropdownMenu, DropdownMenuContent,
DropdownMenuItem, DropdownMenuTrigger } from
"@/components/ui/dropdown-menu";

const Navbar = () => {


return (
<nav className="fixed left-0 right-0 top-0 z-10 flex h-16 items-
center justify-between border-b bg-background px-4 md:px-6">
<div className="flex items-center">
<Link to="/" className="text-xl font-bold text-primary mr-
6">AppNexus</Link>
<div className="hidden md:flex space-x-1">
<Link to="/">
<Button variant="ghost" size="sm">Dashboard</Button>
</Link>
<Link to="/add-application">
<Button variant="ghost" size="sm">Add App</Button>
</Link>
</div>
</div>

<div className="flex items-center space-x-2">


<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon" className="relative">
<Bell className="h-5 w-5" />
<span className="absolute -right-1 -top-1 flex h-4 w-4
items-center justify-center rounded-full bg-red-500 text-xs text-
white">
3
</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
<DropdownMenuItem>App 'Payment Service' has
issues</DropdownMenuItem>
<DropdownMenuItem>New version available for 'Admin
Dashboard'</DropdownMenuItem>
<DropdownMenuItem>Weekly report is ready to
view</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Settings className="h-5 w-5" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Settings</DropdownMenuItem>
<DropdownMenuItem>Preferences</DropdownMenuItem>
<DropdownMenuItem>Help &
Support</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<User className="h-5 w-5" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Account</DropdownMenuItem>
<DropdownMenuItem>Sign out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

<Link to="/add-application" className="md:hidden">


<Button size="icon">
<Plus className="h-5 w-5" />
</Button>
</Link>
<Link to="/add-application" className="hidden md:inline-flex">
<Button>
<Plus className="mr-2 h-4 w-4" />
Add App
</Button>
</Link>
</div>
</nav>
);
};

export default Navbar;

import { useParams, Link, useNavigate } from "react-router-dom";


import { useEffect } from "react";
import { getApplicationById } from "@/data/apps";
import Navbar from "@/components/Navbar";
import StatusBadge from "@/components/StatusBadge";
import MetricsCard from "@/components/MetricsCard";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from
"@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";
import {
ArrowLeft,
Calendar,
Clock,
Edit,
ExternalLink,
Globe,
MoreVertical,
Server,
Trash2,
User
} from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger
} from "@/components/ui/dropdown-menu";
import { useToast } from "@/hooks/use-toast";

const ApplicationDetail = () => {


const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const { toast } = useToast();

const app = getApplicationById(id || "");

useEffect(() => {
if (!app) {
toast({
title: "Application not found",
description: "The application you're looking for doesn't exist.",
variant: "destructive",
});
navigate("/");
}
}, [app, navigate, toast]);

if (!app) {
return null;
}

const formatDate = (dateString: string) => {


const date = new Date(dateString);
return new Intl.DateTimeFormat("en-US", {
day: "numeric",
month: "short",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
}).format(date);
};

const getStatusColor = (status: string) => {


switch (status) {
case "online":
return "bg-emerald-500";
case "offline":
return "bg-red-500";
case "maintenance":
return "bg-amber-500";
case "warning":
return "bg-orange-500";
default:
return "bg-gray-500";
}
};

return (
<div className="min-h-screen bg-background pb-8">
<Navbar />

<main className="container mx-auto max-w-7xl pt-24 px-4">


{/* Header */}
<div className="mb-6">
<Button variant="ghost" size="sm" onClick={() => navigate(-1)}
className="mb-4">
<ArrowLeft className="mr-2 h-4 w-4" />
Back
</Button>

<div className="flex flex-col md:flex-row md:items-center


md:justify-between gap-4">
<div className="flex items-center gap-3">
<div className="flex h-12 w-12 items-center justify-center
rounded-lg bg-primary/10">
{app.logoUrl ? (
<img src={app.logoUrl} alt={app.name} className="h-8 w-
8" />
):(
<Server className="h-8 w-8 text-primary" />
)}
</div>
<div>
<div className="flex items-center gap-3">
<h1 className="text-2xl font-bold">{app.name}</h1>
<StatusBadge status={app.status} />
</div>
<p className="text-muted-
foreground">{app.description}</p>
</div>
</div>

<div className="flex gap-2">


{app.url && (
<Button variant="outline" size="sm" asChild>
<a href={app.url} target="_blank" rel="noopener
noreferrer">
<Globe className="mr-2 h-4 w-4" />
Visit App
</a>
</Button>
)}

<Button variant="outline" size="sm">


<Edit className="mr-2 h-4 w-4" />
Edit
</Button>

<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon" className="h-9 w-
9">
<MoreVertical className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>Restart
Application</DropdownMenuItem>
<DropdownMenuItem>Set Maintenance
Mode</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem className="text-red-600">
<Trash2 className="mr-2 h-4 w-4" />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</div>

{/* Info and Metrics */}


<div className="grid gap-6 md:grid-cols-3 mb-8">
<div className="md:col-span-2">
<MetricsCard metrics={app.metrics} />
</div>

<Card>
<CardHeader>
<CardTitle className="text-lg">Application Info</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
<div>
<div className="flex items-center text-sm text-muted-
foreground">
<Calendar className="mr-2 h-4 w-4" />
Created
</div>
<p className="font-
medium">{formatDate(app.createdAt)}</p>
</div>

<div>
<div className="flex items-center text-sm text-muted-
foreground">
<Clock className="mr-2 h-4 w-4" />
Last updated
</div>
<p className="font-
medium">{formatDate(app.updatedAt)}</p>
</div>

<div>
<div className="flex items-center text-sm text-muted-
foreground">
<User className="mr-2 h-4 w-4" />
Owner
</div>
<p className="font-medium">{app.owner}</p>
</div>

<div>
<div className="text-sm text-muted-foreground mb-
1.5">Tags</div>
<div className="flex flex-wrap gap-1.5">
{app.tags.map((tag) => (
<Badge key={tag} variant="secondary" className="text-
xs">
{tag}
</Badge>
))}
</div>
</div>
</CardContent>
</Card>
</div>

{/* Resources */}


<div className="mb-8">
<h2 className="text-xl font-semibold mb-4">Resources</h2>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{app.resources.map((resource) => (
<Card key={resource.id}>
<CardHeader className="flex flex-row items-center justify-
between pb-2 pt-4">
<h3 className="font-medium">{resource.name}</h3>
<StatusBadge status={resource.status} />
</CardHeader>
<CardContent className="pb-4 pt-0">
<Badge variant="outline">{resource.type}</Badge>
</CardContent>
</Card>
))}

<Card className="flex flex-col items-center justify-center


border-dashed p-6 text-center">
<Server className="mb-2 h-6 w-6 text-muted-
foreground" />
<p className="mb-2 text-sm font-medium">Add
Resource</p>
<p className="mb-4 text-sm text-muted-foreground">
Connect a new database, API, or other resource
</p>
<Button variant="outline" size="sm">
Add Resource
</Button>
</Card>
</div>
</div>

{/* Activity and Logs (Placeholder) */}


<div>
<h2 className="text-xl font-semibold mb-4">Recent
Activity</h2>
<Card>
<CardContent className="p-6">
<div className="space-y-4">
<div className="flex items-start gap-3">
<div className={`mt-0.5 h-2.5 w-2.5 rounded-full $
{getStatusColor("online")}`} />
<div>
<p className="font-medium">Application restarted</p>
<p className="text-sm text-muted-foreground">
{formatDate(new Date(Date.now() - 2 * 60 * 60 *
1000).toISOString())}
</p>
</div>
</div>

<Separator />

<div className="flex items-start gap-3">


<div className={`mt-0.5 h-2.5 w-2.5 rounded-full $
{getStatusColor("warning")}`} />
<div>
<p className="font-medium">High memory usage
detected</p>
<p className="text-sm text-muted-foreground">
{formatDate(new Date(Date.now() - 5 * 60 * 60 *
1000).toISOString())}
</p>
</div>
</div>

<Separator />

<div className="flex items-start gap-3">


<div className={`mt-0.5 h-2.5 w-2.5 rounded-full $
{getStatusColor("online")}`} />
<div>
<p className="font-medium">Version updated to
{app.version}</p>
<p className="text-sm text-muted-foreground">
{formatDate(app.updatedAt)}
</p>
</div>
</div>
</div>

<div className="mt-4 flex justify-center">


<Button variant="outline" size="sm">
View All Activity
</Button>
</div>
</CardContent>
</Card>
</div>
</main>
</div>
);
};

export default ApplicationDetail;


import { useState } from "react";
import { useNavigate } from "react-router-dom";
import Navbar from "@/components/Navbar";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger,
SelectValue } from "@/components/ui/select";
import { Card, CardContent, CardDescription, CardFooter,
CardHeader, CardTitle } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { ArrowLeft, Loader2 } from "lucide-react";
import { useToast } from "@/hooks/use-toast";

const AddApplication = () => {


const navigate = useNavigate();
const { toast } = useToast();
const [isSubmitting, setIsSubmitting] = useState(false);

const [formData, setFormData] = useState({


name: "",
description: "",
environment: "development",
owner: "",
version: "",
url: "",
tags: "",
});
const handleChange = (e: React.ChangeEvent<HTMLInputElement |
HTMLTextAreaElement>) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
};

const handleSelectChange = (name: string, value: string) => {


setFormData((prev) => ({ ...prev, [name]: value }));
};

const handleSubmit = (e: React.FormEvent) => {


e.preventDefault();
setIsSubmitting(true);

// Validate form
if (!formData.name || !formData.description || !formData.owner)
{
toast({
title: "Validation Error",
description: "Please fill in all required fields.",
variant: "destructive",
});
setIsSubmitting(false);
return;
}

// Simulate API call


setTimeout(() => {
toast({
title: "Application Added",
description: `${formData.name} has been successfully added.`,
});
setIsSubmitting(false);
navigate("/");
}, 1000);
};
return (
<div className="min-h-screen bg-background pb-8">
<Navbar />

<main className="container mx-auto max-w-3xl pt-24 px-4">


<Button variant="ghost" size="sm" onClick={() => navigate(-1)}
className="mb-4">
<ArrowLeft className="mr-2 h-4 w-4" />
Back
</Button>

<Card>
<CardHeader>
<CardTitle className="text-2xl">Add New
Application</CardTitle>
<CardDescription>Enter the details for your new
application.</CardDescription>
</CardHeader>

<form onSubmit={handleSubmit}>
<CardContent className="space-y-6">
<div className="space-y-4">
<div className="grid gap-2">
<Label htmlFor="name">
Application Name <span
className="text-red-500">*</span>
</Label>
<Input
id="name"
name="name"
value={formData.name}
onChange={handleChange}
placeholder="E.g., Customer Portal"
required
/>
</div>

<div className="grid gap-2">


<Label htmlFor="description">
Description <span className="text-red-500">*</span>
</Label>
<Textarea
id="description"
name="description"
value={formData.description}
onChange={handleChange}
placeholder="Briefly describe the application and its
purpose"
rows={3}
required
/>
</div>

<div className="grid gap-2">


<Label htmlFor="environment">
Environment <span className="text-red-500">*</span>
</Label>
<Select
value={formData.environment}
onValueChange={(value) =>
handleSelectChange("environment", value)}
>
<SelectTrigger id="environment">
<SelectValue placeholder="Select environment" />
</SelectTrigger>
<SelectContent>
<SelectItem
value="development">Development</SelectItem>
<SelectItem value="staging">Staging</SelectItem>
<SelectItem
value="production">Production</SelectItem>
</SelectContent>
</Select>
</div>

<div className="grid gap-2">


<Label htmlFor="owner">
Owner <span className="text-red-500">*</span>
</Label>
<Input
id="owner"
name="owner"
value={formData.owner}
onChange={handleChange}
placeholder="Team or person responsible"
required
/>
</div>

<div className="grid gap-2">


<Label htmlFor="version">Version</Label>
<Input
id="version"
name="version"
value={formData.version}
onChange={handleChange}
placeholder="E.g., 1.0.0"
/>
</div>

<div className="grid gap-2">


<Label htmlFor="url">URL (Optional)</Label>
<Input
id="url"
name="url"
value={formData.url}
onChange={handleChange}
placeholder="https://example.com"
type="url"
/>
</div>

<div className="grid gap-2">


<Label htmlFor="tags">Tags (Comma separated)</Label>
<Input
id="tags"
name="tags"
value={formData.tags}
onChange={handleChange}
placeholder="frontend, react, api"
/>
</div>
</div>
</CardContent>

<CardFooter className="flex justify-between">


<Button variant="outline" type="button" onClick={() =>
navigate("/")}>
Cancel
</Button>
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
Adding...
</>
):(
"Add Application"
)}
</Button>
</CardFooter>
</form>
</Card>
</main>
</div>
);
};

export default AddApplication;

import { useState } from "react";


import { applications } from "@/data/apps";
import Navbar from "@/components/Navbar";
import SearchBar from "@/components/SearchBar";
import AppCard from "@/components/AppCard";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from
"@/components/ui/card";
import { AppStatus } from "@/types/app";
import { Badge } from "@/components/ui/badge";
import { DropdownMenu, DropdownMenuContent,
DropdownMenuItem, DropdownMenuTrigger } from
"@/components/ui/dropdown-menu";
import { AlertTriangle, CheckCircle, Clock, FilterIcon, Grid3X3,
LayoutList, PowerOff, Plus, X } from "lucide-react";
import { Link } from "react-router-dom";

const Index = () => {


const [searchTerm, setSearchTerm] = useState("");
const [statusFilter, setStatusFilter] = useState<AppStatus |
"all">("all");
const [environmentFilter, setEnvironmentFilter] =
useState<string>("all");
const [viewMode, setViewMode] = useState<"grid" | "list">("grid");

// Filter applications based on search, status, and environment


const filteredApps = applications.filter((app) => {
const matchesSearch =
app.name.toLowerCase().includes(searchTerm.toLowerCase()) ||

app.description.toLowerCase().includes(searchTerm.toLowerCase())
||
app.tags.some(tag =>
tag.toLowerCase().includes(searchTerm.toLowerCase()));

const matchesStatus = statusFilter === "all" || app.status ===


statusFilter;
const matchesEnvironment = environmentFilter === "all" ||
app.environment === environmentFilter;

return matchesSearch && matchesStatus &&


matchesEnvironment;
});

// Count apps by status


const statusCounts = {
online: applications.filter(app => app.status === "online").length,
warning: applications.filter(app => app.status ===
"warning").length,
maintenance: applications.filter(app => app.status ===
"maintenance").length,
offline: applications.filter(app => app.status === "offline").length,
total: applications.length
};

return (
<div className="min-h-screen bg-background pb-8">
<Navbar />
<main className="container mx-auto max-w-7xl pt-24 px-4">
<div className="mb-6 flex flex-col md:flex-row md:items-center
md:justify-between">
<h1 className="text-3xl font-bold tracking-tight mb-2 md:mb-
0">Application Dashboard</h1>
<Link to="/add-application">
<Button>
<Plus className="mr-2 h-4 w-4" />
Add New Application
</Button>
</Link>
</div>

{/* Status Summary */}


<div className="grid gap-4 md:grid-cols-4 mb-8">
<Card>
<CardHeader className="flex flex-row items-center justify-
between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">Total
Apps</CardTitle>
<div className="h-4 w-4 text-muted-foreground" />
</CardHeader>
<CardContent>
<div className="text-2xl
font-bold">{statusCounts.total}</div>
</CardContent>
</Card>

<Card>
<CardHeader className="flex flex-row items-center justify-
between space-y-0 pb-2">
<CardTitle className="text-sm
font-medium">Online</CardTitle>
<CheckCircle className="h-4 w-4 text-emerald-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-
bold">{statusCounts.online}</div>
</CardContent>
</Card>

<Card>
<CardHeader className="flex flex-row items-center justify-
between space-y-0 pb-2">
<CardTitle className="text-sm
font-medium">Warning</CardTitle>
<AlertTriangle className="h-4 w-4 text-orange-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-
bold">{statusCounts.warning}</div>
</CardContent>
</Card>

<Card>
<CardHeader className="flex flex-row items-center justify-
between space-y-0 pb-2">
<CardTitle className="text-sm
font-medium">Offline</CardTitle>
<PowerOff className="h-4 w-4 text-red-500" />
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{statusCounts.offline +
statusCounts.maintenance}</div>
</CardContent>
</Card>
</div>

{/* Filters and Search */}


<div className="flex flex-col md:flex-row md:items-center
justify-between gap-4 mb-6">
<SearchBar
onSearch={setSearchTerm}
className="w-full md:max-w-sm"
/>

<div className="flex items-center gap-2 flex-wrap">


<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" className="h-10">
<FilterIcon className="mr-2 h-4 w-4" />
Status: {statusFilter === "all" ? "All" : statusFilter}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={() =>
setStatusFilter("all")}>All</DropdownMenuItem>
<DropdownMenuItem onClick={() =>
setStatusFilter("online")}>Online</DropdownMenuItem>
<DropdownMenuItem onClick={() =>
setStatusFilter("warning")}>Warning</DropdownMenuItem>
<DropdownMenuItem onClick={() =>
setStatusFilter("maintenance")}>Maintenance</DropdownMenuIte
m>
<DropdownMenuItem onClick={() =>
setStatusFilter("offline")}>Offline</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>

<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="sm" className="h-10">
<FilterIcon className="mr-2 h-4 w-4" />
Environment: {environmentFilter === "all" ? "All" :
environmentFilter}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem onClick={() =>
setEnvironmentFilter("all")}>All</DropdownMenuItem>
<DropdownMenuItem onClick={() =>
setEnvironmentFilter("production")}>Production</DropdownMenuIt
em>
<DropdownMenuItem onClick={() =>
setEnvironmentFilter("staging")}>Staging</DropdownMenuItem>
<DropdownMenuItem onClick={() =>
setEnvironmentFilter("development")}>Development</DropdownM
enuItem>
</DropdownMenuContent>
</DropdownMenu>

<div className="flex items-center rounded-md border bg-


muted/50 p-1">
<Button
variant={viewMode === "grid" ? "default" : "ghost"}
size="sm"
className="h-8 w-8 p-0"
onClick={() => setViewMode("grid")}
>
<Grid3X3 className="h-4 w-4" />
</Button>
<Button
variant={viewMode === "list" ? "default" : "ghost"}
size="sm"
className="h-8 w-8 p-0"
onClick={() => setViewMode("list")}
>
<LayoutList className="h-4 w-4" />
</Button>
</div>
</div>
</div>

{/* Active filters display */}


{(statusFilter !== "all" || environmentFilter !== "all" ||
searchTerm) && (
<div className="flex flex-wrap gap-2 mb-4">
{statusFilter !== "all" && (
<Badge variant="secondary" className="flex items-center
gap-1">
Status: {statusFilter}
<Button
variant="ghost"
size="icon"
className="h-4 w-4 ml-1 p-0"
onClick={() => setStatusFilter("all")}
>
<X className="h-3 w-3" />
</Button>
</Badge>
)}

{environmentFilter !== "all" && (


<Badge variant="secondary" className="flex items-center
gap-1">
Environment: {environmentFilter}
<Button
variant="ghost"
size="icon"
className="h-4 w-4 ml-1 p-0"
onClick={() => setEnvironmentFilter("all")}
>
<X className="h-3 w-3" />
</Button>
</Badge>
)}

{searchTerm && (
<Badge variant="secondary" className="flex items-center
gap-1">
Search: "{searchTerm}"
<Button
variant="ghost"
size="icon"
className="h-4 w-4 ml-1 p-0"
onClick={() => setSearchTerm("")}
>
<X className="h-3 w-3" />
</Button>
</Badge>
)}

<Button
variant="ghost"
size="sm"
className="h-7 text-xs"
onClick={() => {
setStatusFilter("all");
setEnvironmentFilter("all");
setSearchTerm("");
}}
>
Clear All
</Button>
</div>
)}

{/* Applications grid */}


{filteredApps.length > 0 ? (
<div className={viewMode === "grid"
? "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
: "space-y-4"
}>
{filteredApps.map((app) => (
<AppCard key={app.id} app={app} />
))}
</div>
):(
<div className="flex flex-col items-center justify-center py-12
text-center">
<div className="rounded-full bg-muted p-3 mb-4">
<Clock className="h-6 w-6 text-muted-foreground" />
</div>
<h3 className="mb-2 text-xl font-semibold">No applications
found</h3>
<p className="mb-6 text-muted-foreground">
Try adjusting your search or filter to find what you're looking
for.
</p>
<Button onClick={() => {
setStatusFilter("all");
setEnvironmentFilter("all");
setSearchTerm("");
}}>
Reset Filters
</Button>
</div>
)}
</main>
</div>
);
};

export default Index;


Conclusion

The App Management System provides a comprehensive and efficient solution for creating,
organizing, and managing applications. By leveraging cutting-edge technologies such as
React.js for the frontend, Node.js for the backend, and MongoDB for database management,
the system ensures reliability, scalability, and a user-friendly experience.

With features like secure user authentication, role-based access control, and real-time
notifications, the system addresses the diverse needs of users, whether they are developers,
administrators, or end-users. Its modular architecture ensures ease of maintenance and
flexibility for adding new features in the future.

Through detailed planning, robust implementation, and thorough testing, the App
Management System exemplifies how modern software can streamline processes while
fostering a seamless and intuitive user experience. Moving forward, this system can be
expanded to include advanced analytics, AI-driven recommendations, and deeper integrations
with other tools, paving the way for innovation and increased productivity.

This concludes the documentation for the App Management System. Thank you for reading!

You might also like