feat: Initialize monorepo structure and comprehensive documentation

This commit establishes the new monorepo architecture for the KROW Workforce platform.

Key changes include:
- Reorganized project into `frontend-web`, `mobile-apps`, `firebase`, `scripts`, and `secrets` directories.
- Updated `Makefile` to support the new monorepo layout and automate Base44 export integration.
- Fixed `scripts/prepare-export.js` for ES module compatibility and global component import resolution.
- Created and updated `CONTRIBUTING.md` for developer onboarding.
- Restructured, renamed, and translated all `docs/` files for clarity and consistency.
- Implemented an interactive internal launchpad with diagram viewing capabilities.
- Configured base Firebase project files (`firebase.json`, security rules).
- Updated `README.md` to reflect the new project structure and documentation overview.
This commit is contained in:
bwnyasse
2025-11-12 12:50:55 -05:00
parent 92fd0118be
commit 554dc9f9e3
203 changed files with 1414 additions and 732 deletions

View File

@@ -0,0 +1,292 @@
import React, { useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Save, X } from "lucide-react";
export default function CreateBusinessModal({ open, onOpenChange, onSubmit, isSubmitting }) {
const [formData, setFormData] = useState({
business_name: "",
company_logo: "", // Added company_logo field
contact_name: "",
phone: "",
email: "",
hub_building: "",
address: "",
city: "",
area: "Bay Area",
sector: "",
rate_group: "",
status: "Active",
notes: ""
});
const handleChange = (field, value) => {
setFormData(prev => ({ ...prev, [field]: value }));
};
const handleSubmit = (e) => {
e.preventDefault();
onSubmit(formData);
// Reset form after submission
setFormData({
business_name: "",
company_logo: "", // Reset company_logo field
contact_name: "",
phone: "",
email: "",
hub_building: "",
address: "",
city: "",
area: "Bay Area",
sector: "",
rate_group: "",
status: "Active",
notes: ""
});
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle className="text-2xl font-bold text-[#1C323E]">
Create New Business
</DialogTitle>
</DialogHeader>
<form onSubmit={handleSubmit} className="space-y-6 mt-4">
{/* Business Name & Company Logo */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="business_name" className="text-slate-700 font-medium">
Business Name <span className="text-red-500">*</span>
</Label>
<Input
id="business_name"
value={formData.business_name}
onChange={(e) => handleChange('business_name', e.target.value)}
placeholder="Enter business name"
required
className="border-slate-300"
/>
</div>
<div className="space-y-2">
<Label htmlFor="company_logo" className="text-slate-700 font-medium">
Company Logo URL
</Label>
<Input
id="company_logo"
value={formData.company_logo}
onChange={(e) => handleChange('company_logo', e.target.value)}
placeholder="https://example.com/logo.png"
className="border-slate-300"
/>
<p className="text-xs text-slate-500">Optional: URL to company logo image</p>
</div>
</div>
{/* Primary Contact (Moved from first grid to its own section) */}
<div className="space-y-2">
<Label htmlFor="contact_name" className="text-slate-700 font-medium">
Primary Contact <span className="text-red-500">*</span>
</Label>
<Input
id="contact_name"
value={formData.contact_name}
onChange={(e) => handleChange('contact_name', e.target.value)}
placeholder="Contact name"
required
className="border-slate-300"
/>
</div>
{/* Contact Number & Email */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="phone" className="text-slate-700 font-medium">
Contact Number
</Label>
<Input
id="phone"
type="tel"
value={formData.phone}
onChange={(e) => handleChange('phone', e.target.value)}
placeholder="(555) 123-4567"
className="border-slate-300"
/>
</div>
<div className="space-y-2">
<Label htmlFor="email" className="text-slate-700 font-medium">
Email
</Label>
<Input
id="email"
type="email"
value={formData.email}
onChange={(e) => handleChange('email', e.target.value)}
placeholder="business@example.com"
className="border-slate-300"
/>
</div>
</div>
{/* Hub / Building */}
<div className="space-y-2">
<Label htmlFor="hub_building" className="text-slate-700 font-medium">
Hub / Building
</Label>
<Input
id="hub_building"
value={formData.hub_building}
onChange={(e) => handleChange('hub_building', e.target.value)}
placeholder="Building name or location"
className="border-slate-300"
/>
</div>
{/* Address */}
<div className="space-y-2">
<Label htmlFor="address" className="text-slate-700 font-medium">
Address
</Label>
<Input
id="address"
value={formData.address}
onChange={(e) => handleChange('address', e.target.value)}
placeholder="Street address"
className="border-slate-300"
/>
</div>
{/* City & Area */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="city" className="text-slate-700 font-medium">
City
</Label>
<Input
id="city"
value={formData.city}
onChange={(e) => handleChange('city', e.target.value)}
placeholder="City"
className="border-slate-300"
/>
</div>
<div className="space-y-2">
<Label htmlFor="area" className="text-slate-700 font-medium">
Area
</Label>
<Select value={formData.area} onValueChange={(value) => handleChange('area', value)}>
<SelectTrigger className="border-slate-300">
<SelectValue placeholder="Select area" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Bay Area">Bay Area</SelectItem>
<SelectItem value="Southern California">Southern California</SelectItem>
<SelectItem value="Northern California">Northern California</SelectItem>
<SelectItem value="Central Valley">Central Valley</SelectItem>
<SelectItem value="Other">Other</SelectItem>
</SelectContent>
</Select>
</div>
</div>
{/* Sector & Rate Group */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="space-y-2">
<Label htmlFor="sector" className="text-slate-700 font-medium">
Sector
</Label>
<Select value={formData.sector} onValueChange={(value) => handleChange('sector', value)}>
<SelectTrigger className="border-slate-300">
<SelectValue placeholder="Select sector" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Bon Appétit">Bon Appétit</SelectItem>
<SelectItem value="Eurest">Eurest</SelectItem>
<SelectItem value="Aramark">Aramark</SelectItem>
<SelectItem value="Epicurean Group">Epicurean Group</SelectItem>
<SelectItem value="Chartwells">Chartwells</SelectItem>
<SelectItem value="Other">Other</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="rate_group" className="text-slate-700 font-medium">
Rate Group <span className="text-red-500">*</span>
</Label>
<Select value={formData.rate_group} onValueChange={(value) => handleChange('rate_group', value)} required>
<SelectTrigger className="border-slate-300">
<SelectValue placeholder="Select pricing tier" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Standard">Standard</SelectItem>
<SelectItem value="Premium">Premium</SelectItem>
<SelectItem value="Enterprise">Enterprise</SelectItem>
<SelectItem value="Custom">Custom</SelectItem>
</SelectContent>
</Select>
</div>
</div>
{/* Status */}
<div className="space-y-2">
<Label htmlFor="status" className="text-slate-700 font-medium">
Status
</Label>
<Select value={formData.status} onValueChange={(value) => handleChange('status', value)}>
<SelectTrigger className="border-slate-300">
<SelectValue placeholder="Select status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="Active">Active</SelectItem>
<SelectItem value="Inactive">Inactive</SelectItem>
<SelectItem value="Pending">Pending</SelectItem>
</SelectContent>
</Select>
</div>
{/* Action Buttons */}
<div className="flex justify-end gap-3 pt-4 border-t border-slate-200">
<Button
type="button"
variant="outline"
onClick={() => onOpenChange(false)}
className="border-slate-300"
disabled={isSubmitting}
>
Cancel
</Button>
<Button
type="submit"
disabled={isSubmitting}
className="bg-[#0A39DF] hover:bg-[#0A39DF]/90 text-white"
>
<Save className="w-4 h-4 mr-2" />
{isSubmitting ? "Creating..." : "Create Business"}
</Button>
</div>
</form>
</DialogContent>
</Dialog>
);
}