App Management System: React Typescript Vite Tailwind Css Postcss Eslint Node - Js & NPM
App Management System: React Typescript Vite Tailwind Css Postcss Eslint Node - Js & NPM
PROJECT STACK :
Overview:
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.
CODING :
interface StatusBadgeProps {
status: AppStatus;
showText?: boolean;
className?: string;
}
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>
);
};
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>
interface AppCardProps {
app: Application;
}
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>
);
};
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]);
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>
);
};
<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>
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;
}
return (
<div className="min-h-screen bg-background pb-8">
<Navbar />
<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>
<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>
<Separator />
<Separator />
// 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;
}
<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>
app.description.toLowerCase().includes(searchTerm.toLowerCase())
||
app.tags.some(tag =>
tag.toLowerCase().includes(searchTerm.toLowerCase()));
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>
<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>
<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>
{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>
)}
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!