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:
0
firebase/dataconnect/connector/.keep
Normal file
0
firebase/dataconnect/connector/.keep
Normal file
0
firebase/dataconnect/schema/.keep
Normal file
0
firebase/dataconnect/schema/.keep
Normal file
12
firebase/firestore.rules
Normal file
12
firebase/firestore.rules
Normal file
@@ -0,0 +1,12 @@
|
||||
rules_version = '2';
|
||||
|
||||
service cloud.firestore {
|
||||
match /databases/{database}/documents {
|
||||
// Base rules: By default, lock down all access.
|
||||
// Data Connect will operate with admin privileges from the backend
|
||||
// and will not be subject to these client-side rules.
|
||||
match /{document=**} {
|
||||
allow read, write: if false;
|
||||
}
|
||||
}
|
||||
}
|
||||
0
firebase/functions/.keep
Normal file
0
firebase/functions/.keep
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 300 KiB |
102
firebase/internal-launchpad/assets/diagrams/invoice-workflow.svg
Normal file
102
firebase/internal-launchpad/assets/diagrams/invoice-workflow.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 164 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.6 MiB |
246
firebase/internal-launchpad/launchpad.html
Normal file
246
firebase/internal-launchpad/launchpad.html
Normal file
@@ -0,0 +1,246 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>KROW Launchpad</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- Bootstrap Icons -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.8.1/font/bootstrap-icons.css">
|
||||
<!-- Custom CSS -->
|
||||
<style>
|
||||
body {
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
.main-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-color: #ffffff;
|
||||
border-right: 1px solid #dee2e6;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
color: #495057;
|
||||
font-weight: 500;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
transition: color 0.2s, background-color 0.2s;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active,
|
||||
.sidebar .nav-link:hover {
|
||||
color: #0d6efd;
|
||||
background-color: #e9ecef;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: #6c757d;
|
||||
text-transform: uppercase;
|
||||
padding: 0 1rem;
|
||||
margin-top: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.content-area {
|
||||
padding: 2rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#diagram-viewer {
|
||||
display: none; /* Hidden by default */
|
||||
height: calc(100vh - 4rem); /* Full height minus padding */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#diagram-container {
|
||||
cursor: grab;
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
background-color: #ffffff;
|
||||
border-radius: 0.5rem;
|
||||
border: 1px solid #dee2e6;
|
||||
}
|
||||
#diagram-container:focus { outline: none; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="main-layout">
|
||||
<!-- Sidebar -->
|
||||
<nav class="sidebar">
|
||||
<div class="d-flex justify-content-center align-items-center mb-4">
|
||||
<img src="logo.svg" alt="Krow Logo" style="height: 60px;">
|
||||
</div>
|
||||
<div class="nav flex-column nav-pills">
|
||||
<a class="nav-link active" href="#" id="nav-home" onclick="showView('home', this)">
|
||||
<i class="bi bi-house-door"></i>Home
|
||||
</a>
|
||||
|
||||
<div class="sidebar-heading">Diagrams</div>
|
||||
|
||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/high-level-overview.svg', 'Apps High-Level Overview')">
|
||||
<i class="bi bi-diagram-3"></i>High-Level Overview
|
||||
</a>
|
||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/shift-lifecycle-workflow.svg', 'Core Workflow - Shift Lifecycle')">
|
||||
<i class="bi bi-arrow-repeat"></i>Shift Lifecycle
|
||||
</a>
|
||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/invoice-workflow.svg', 'Invoice Workflow - Complete')">
|
||||
<i class="bi bi-receipt"></i>Invoice Workflow
|
||||
</a>
|
||||
<a class="nav-link" href="#" onclick="showView('diagram', this, './assets/diagrams/complete-workflow.svg', 'Complete Workflow')">
|
||||
<i class="bi bi-infinity"></i>Complete Workflow
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Main Content Area -->
|
||||
<main class="content-area">
|
||||
<!-- View 1: Home Content -->
|
||||
<div id="home-view">
|
||||
<h2 class="mb-4">Welcome to the Project Launchpad</h2>
|
||||
<div class="row">
|
||||
<div class="col-lg-6">
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-header"><h3>Applications</h3></div>
|
||||
<div class="card-body">
|
||||
<ul class="list-group list-group-flush">
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<a target="_blank" href="#">Control Tower (Dev)</a>
|
||||
<span class="badge bg-primary rounded-pill">Dev</span>
|
||||
</li>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<a target="_blank" href="#">Control Tower (Staging)</a>
|
||||
<span class="badge bg-warning text-dark rounded-pill">Staging</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="card shadow-sm mb-4">
|
||||
<div class="card-header"><h3>Access & Resources</h3></div>
|
||||
<div class="card-body">
|
||||
<div class="list-group list-group-flush">
|
||||
<a href="https://github.com/Oloodi/krow-workforce" target="_blank" class="list-group-item list-group-item-action">
|
||||
<div class="fw-bold">GitHub Repository</div>
|
||||
</a>
|
||||
<a href="https://chat.google.com/" target="_blank" class="list-group-item list-group-item-action">
|
||||
<div class="fw-bold">Team Communication</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- View 2: Diagram Viewer -->
|
||||
<div id="diagram-viewer">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3 id="diagram-title" class="mb-0"></h3>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-outline-secondary" id="zoomInBtn" title="Zoom In"><i class="bi bi-zoom-in"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary" id="zoomOutBtn" title="Zoom Out"><i class="bi bi-zoom-out"></i></button>
|
||||
<button type="button" class="btn btn-outline-secondary" id="resetBtn" title="Reset View"><i class="bi bi-aspect-ratio"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="diagram-container" tabindex="-1">
|
||||
<!-- SVG will be loaded here -->
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- JS -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@panzoom/panzoom@4.5.1/dist/panzoom.min.js"></script>
|
||||
|
||||
<script>
|
||||
const homeView = document.getElementById('home-view');
|
||||
const diagramViewer = document.getElementById('diagram-viewer');
|
||||
const diagramContainer = document.getElementById('diagram-container');
|
||||
const diagramTitle = document.getElementById('diagram-title');
|
||||
|
||||
const zoomInBtn = document.getElementById('zoomInBtn');
|
||||
const zoomOutBtn = document.getElementById('zoomOutBtn');
|
||||
const resetBtn = document.getElementById('resetBtn');
|
||||
|
||||
let panzoomInstance = null;
|
||||
|
||||
function setActiveNav(activeLink) {
|
||||
document.querySelectorAll('.sidebar .nav-link').forEach(link => {
|
||||
link.classList.remove('active');
|
||||
});
|
||||
activeLink.classList.add('active');
|
||||
}
|
||||
|
||||
async function showView(viewName, navLink, svgPath, title) {
|
||||
setActiveNav(navLink);
|
||||
if (panzoomInstance) panzoomInstance.destroy();
|
||||
diagramContainer.innerHTML = '';
|
||||
|
||||
if (viewName === 'home') {
|
||||
homeView.style.display = 'block';
|
||||
diagramViewer.style.display = 'none';
|
||||
} else if (viewName === 'diagram') {
|
||||
homeView.style.display = 'none';
|
||||
diagramViewer.style.display = 'flex';
|
||||
diagramTitle.textContent = title;
|
||||
diagramContainer.innerHTML = '<div class="d-flex justify-content-center align-items-center h-100"><div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div></div>';
|
||||
|
||||
try {
|
||||
const response = await fetch(svgPath);
|
||||
if (!response.ok) throw new Error(`Network error: ${response.status}`);
|
||||
const svgContent = await response.text();
|
||||
|
||||
const parser = new DOMParser();
|
||||
const svgDoc = parser.parseFromString(svgContent, "image/svg+xml");
|
||||
const svgElement = svgDoc.querySelector('svg');
|
||||
|
||||
if (svgElement) {
|
||||
diagramContainer.innerHTML = '';
|
||||
diagramContainer.appendChild(svgElement);
|
||||
panzoomInstance = Panzoom(svgElement, {
|
||||
canvas: true,
|
||||
maxScale: 10,
|
||||
minScale: 0.3,
|
||||
zoomOnDblClick: false
|
||||
});
|
||||
diagramContainer.addEventListener('wheel', panzoomInstance.zoomWithWheel);
|
||||
diagramContainer.focus();
|
||||
} else {
|
||||
throw new Error('No SVG element found.');
|
||||
}
|
||||
} catch (error) {
|
||||
diagramContainer.innerHTML = `<div class="alert alert-danger m-3">Failed to load diagram: ${error.message}</div>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zoomInBtn.addEventListener('click', () => { panzoomInstance?.zoomIn(); diagramContainer.focus(); });
|
||||
zoomOutBtn.addEventListener('click', () => { panzoomInstance?.zoomOut(); diagramContainer.focus(); });
|
||||
resetBtn.addEventListener('click', () => { panzoomInstance?.reset(); diagramContainer.focus(); });
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
showView('home', document.getElementById('nav-home'));
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
45
firebase/internal-launchpad/logo.svg
Normal file
45
firebase/internal-launchpad/logo.svg
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Adobe Illustrator 29.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#24303B;}
|
||||
.st1{fill:#002FE3;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M459.81,202.55c-5.03,0.59-9.08,4.49-10.36,9.38l-15.99,59.71l-16.24-56.3
|
||||
c-1.68-5.92-6.22-10.86-12.19-12.34c-1.58-0.39-3.11-0.54-4.64-0.49h-0.15c-1.53-0.05-3.11,0.1-4.64,0.49
|
||||
c-5.97,1.48-10.51,6.42-12.24,12.34l-3.6,12.53l-11.35,39.38l-7.9-27.54c-10.76-37.5-48.56-62.23-88.38-55.32
|
||||
c-33.26,5.82-57.05,35.68-56.99,69.48v0.79c0,4.34,0.39,8.73,1.13,13.18c0.18,1.02,0.37,2.03,0.6,3.03
|
||||
c1.84,8.31,10.93,12.73,18.49,8.8v0c5.36-2.79,7.84-8.89,6.42-14.77c-0.85-3.54-1.28-7.23-1.23-11.03
|
||||
c0-25.02,20.48-45.5,45.55-45.2c7.6,0.1,15.59,2.07,23.59,6.37c13.52,7.3,23.15,20.18,27.34,34.94l13.32,46.34
|
||||
c1.73,5.97,6.22,11,12.24,12.58c9.62,2.62,19-3.06,21.51-12.04l16.09-56.7l0.2-0.1l16.09,56.85c1.63,5.68,5.87,10.41,11.55,11.99
|
||||
c9.13,2.57,18.11-2.66,20.67-11.2l24.13-79.6C475.35,209.85,468.64,201.56,459.81,202.55z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M83.32,255.47c-1.7-2.2-1.67-5.29,0.07-7.46l20.19-25.12c5.63-7.01,3.73-16.22-4.64-19.53
|
||||
c-5.29-2.09-10.99-0.39-14.28,3.75l-32.67,41v-32.24c0-6.63-4.77-12.68-11.38-13.34c-7.59-0.76-13.99,5.18-13.99,12.62v80.99
|
||||
c0,6.63,4.77,12.68,11.37,13.34C45.6,310.24,52,304.3,52,296.86v-12.73l11.65-13.22l25.12,33.69c2.33,3.12,5.99,4.95,9.87,4.95
|
||||
h1.4c10.23,0,16-11.75,9.74-19.85L83.32,255.47z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st1" d="M306.76,234.3c-5.42,2.52-8.26,8.45-7.01,14.3c0.64,3.01,0.98,6.14,0.98,9.35v0.3c0,0,0,0,0,0.05
|
||||
c0,24.5-19.71,44.44-44.09,45c-22.25-0.13-43.56-9.01-59.31-24.75l-14.06-14.06c0.43-0.17,0.9-0.3,1.33-0.49
|
||||
c5.92-2.62,10.51-6.32,13.77-11.2c1.94-2.91,3.23-6.22,4.02-9.84c0.08-0.37,0.15-0.75,0.22-1.12c0.14-0.79,0.29-1.57,0.38-2.39
|
||||
c0.16-1.38,0.27-2.79,0.27-4.27c0-6.86-1.63-12.73-4.89-17.62c-3.26-4.89-7.85-8.59-13.77-11.2c-5.92-2.62-12.88-3.9-20.82-3.9
|
||||
h-20.73c-12.58,0-22.75,10.21-22.75,22.75v71.65c0,7.01,5.68,12.68,12.73,12.68c3.5,0,6.66-1.43,8.98-3.7
|
||||
c2.27-2.32,3.7-5.48,3.7-8.98V267.9h5.04l28.63,28.63c20.27,20.27,47.65,31.75,76.28,32.13v0.1c0.33,0,0.65-0.05,0.97-0.05
|
||||
c0.16,0,0.32,0.02,0.48,0.02v-0.05c38.16-0.83,69.01-32.05,69.01-70.74c0-5.12-0.54-10.1-1.59-14.91
|
||||
C322.83,235.11,314.11,230.88,306.76,234.3z M173.15,246.68c-3.01,2.07-7.15,3.11-12.43,3.11h-8.98c-3.31,0-6.02-2.71-6.02-6.02
|
||||
v-14.41c0-3.31,2.71-6.02,6.02-6.02h9.53c5.23,0,9.28,1.09,12.09,3.26c2.86,2.17,4.25,5.58,4.25,10.21
|
||||
C177.59,241.3,176.11,244.56,173.15,246.68z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
11
firebase/storage.rules
Normal file
11
firebase/storage.rules
Normal file
@@ -0,0 +1,11 @@
|
||||
rules_version = '2';
|
||||
|
||||
service firebase.storage {
|
||||
match /b/{bucket}/o {
|
||||
// Base rules: By default, lock down all access.
|
||||
// Client-side uploads will be managed via signed URLs generated by the backend if needed.
|
||||
match /{allPaths=**} {
|
||||
allow read, write: if false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user