DevelopedBy-Siva commited on
Commit
d28fc5d
·
1 Parent(s): 3c93545

refactor UI

Browse files
extension/content.js CHANGED
@@ -1,5 +1,24 @@
1
  function injectSidebar() {
2
  if (document.getElementById("flowpilot-sidebar-frame")) return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  const frame = document.createElement("iframe");
4
  frame.id = "flowpilot-sidebar-frame";
5
  frame.src = chrome.runtime.getURL("sidebar/index.html");
@@ -12,8 +31,21 @@ function injectSidebar() {
12
  border: "0",
13
  zIndex: "999999",
14
  boxShadow: "0 0 24px rgba(0,0,0,0.15)",
15
- background: "#f7f2e8"
 
 
 
 
 
 
 
 
 
 
 
16
  });
 
 
17
  document.body.appendChild(frame);
18
  }
19
 
 
1
  function injectSidebar() {
2
  if (document.getElementById("flowpilot-sidebar-frame")) return;
3
+
4
+ const launcher = document.createElement("button");
5
+ launcher.id = "flowpilot-sidebar-toggle";
6
+ launcher.textContent = "FlowPilot";
7
+ Object.assign(launcher.style, {
8
+ position: "fixed",
9
+ top: "16px",
10
+ right: "16px",
11
+ zIndex: "1000000",
12
+ border: "0",
13
+ borderRadius: "999px",
14
+ padding: "10px 14px",
15
+ background: "#a44a1f",
16
+ color: "#fff7f0",
17
+ font: '600 13px Georgia, "Times New Roman", serif',
18
+ cursor: "pointer",
19
+ boxShadow: "0 12px 28px rgba(0,0,0,0.18)"
20
+ });
21
+
22
  const frame = document.createElement("iframe");
23
  frame.id = "flowpilot-sidebar-frame";
24
  frame.src = chrome.runtime.getURL("sidebar/index.html");
 
31
  border: "0",
32
  zIndex: "999999",
33
  boxShadow: "0 0 24px rgba(0,0,0,0.15)",
34
+ background: "#f7f2e8",
35
+ transform: "translateX(100%)",
36
+ transition: "transform 180ms ease",
37
+ pointerEvents: "none"
38
+ });
39
+
40
+ let isOpen = false;
41
+ launcher.addEventListener("click", () => {
42
+ isOpen = !isOpen;
43
+ frame.style.transform = isOpen ? "translateX(0)" : "translateX(100%)";
44
+ frame.style.pointerEvents = isOpen ? "auto" : "none";
45
+ launcher.textContent = isOpen ? "Close FlowPilot" : "FlowPilot";
46
  });
47
+
48
+ document.body.appendChild(launcher);
49
  document.body.appendChild(frame);
50
  }
51
 
extension/sidebar/app.js CHANGED
@@ -60,10 +60,15 @@ async function saveBackendUrl() {
60
  const nextUrl = backendUrlInput.value.trim().replace(/\/$/, "");
61
  if (!nextUrl) {
62
  setStatus("Enter a backend URL ending in /api.", true);
63
- return;
 
 
 
 
64
  }
65
  await chrome.storage.local.set({ flowpilotBackendUrl: nextUrl });
66
  setStatus(`Backend saved: ${nextUrl}`);
 
67
  }
68
 
69
  async function analyzeBusiness() {
@@ -78,7 +83,10 @@ async function analyzeBusiness() {
78
  setStatus("Running analysis against the configured backend.");
79
 
80
  try {
81
- await saveBackendUrl();
 
 
 
82
  const payload = await apiRequest("/analyze", {
83
  method: "POST",
84
  body: JSON.stringify({
@@ -119,3 +127,14 @@ function setStatus(message, isError = false) {
119
  onboardingStatus.textContent = message;
120
  onboardingStatus.classList.toggle("error-copy", isError);
121
  }
 
 
 
 
 
 
 
 
 
 
 
 
60
  const nextUrl = backendUrlInput.value.trim().replace(/\/$/, "");
61
  if (!nextUrl) {
62
  setStatus("Enter a backend URL ending in /api.", true);
63
+ return false;
64
+ }
65
+ if (!isSupportedBackendUrl(nextUrl)) {
66
+ setStatus("Use either http://localhost:8000/api or an https://...hf.space/api backend.", true);
67
+ return false;
68
  }
69
  await chrome.storage.local.set({ flowpilotBackendUrl: nextUrl });
70
  setStatus(`Backend saved: ${nextUrl}`);
71
+ return true;
72
  }
73
 
74
  async function analyzeBusiness() {
 
83
  setStatus("Running analysis against the configured backend.");
84
 
85
  try {
86
+ const saved = await saveBackendUrl();
87
+ if (!saved) {
88
+ return;
89
+ }
90
  const payload = await apiRequest("/analyze", {
91
  method: "POST",
92
  body: JSON.stringify({
 
127
  onboardingStatus.textContent = message;
128
  onboardingStatus.classList.toggle("error-copy", isError);
129
  }
130
+
131
+ function isSupportedBackendUrl(value) {
132
+ try {
133
+ const url = new URL(value);
134
+ const isLocal = url.protocol === "http:" && url.hostname === "localhost" && url.pathname === "/api";
135
+ const isSpace = url.protocol === "https:" && url.hostname.endsWith(".hf.space") && url.pathname === "/api";
136
+ return isLocal || isSpace;
137
+ } catch {
138
+ return false;
139
+ }
140
+ }
extension/sidebar/components/DashboardScreen.js CHANGED
@@ -4,7 +4,8 @@ export function DashboardScreen() {
4
  return `
5
  <section class="screen-card">
6
  <div class="step-label">8. Dashboard</div>
7
- <h2>Live automation status</h2>
 
8
  <div class="dashboard-row">
9
  <span>3 active workflows</span>
10
  ${StatusBadge("active")}
 
4
  return `
5
  <section class="screen-card">
6
  <div class="step-label">8. Dashboard</div>
7
+ <h2>Dashboard Preview</h2>
8
+ <p class="muted">Real workflow health and counts will appear here after deploy/status wiring.</p>
9
  <div class="dashboard-row">
10
  <span>3 active workflows</span>
11
  ${StatusBadge("active")}
extension/sidebar/components/DeployingScreen.js CHANGED
@@ -2,7 +2,8 @@ export function DeployingScreen() {
2
  return `
3
  <section class="screen-card">
4
  <div class="step-label">7. Deploy</div>
5
- <h2>Building your workflows...</h2>
 
6
  <ul class="status-list">
7
  <li>Order Processing (Full Auto) deployed</li>
8
  <li>Weekly Order Summary deployed for Fridays at 8:00 AM</li>
 
2
  return `
3
  <section class="screen-card">
4
  <div class="step-label">7. Deploy</div>
5
+ <h2>Deployment Preview</h2>
6
+ <p class="muted">This section is a visual stub until deploy actions are connected.</p>
7
  <ul class="status-list">
8
  <li>Order Processing (Full Auto) deployed</li>
9
  <li>Weekly Order Summary deployed for Fridays at 8:00 AM</li>
extension/sidebar/components/OnboardingScreen.js CHANGED
@@ -9,6 +9,7 @@ export function OnboardingScreen() {
9
  class="text-input"
10
  placeholder="https://technophyle-flow-pilot.hf.space/api"
11
  />
 
12
  <div class="button-row">
13
  <button id="flowpilot-save-url" class="ghost-button">Save URL</button>
14
  </div>
 
9
  class="text-input"
10
  placeholder="https://technophyle-flow-pilot.hf.space/api"
11
  />
12
+ <p class="muted helper-copy">Supported today: localhost for development or a *.hf.space/api backend.</p>
13
  <div class="button-row">
14
  <button id="flowpilot-save-url" class="ghost-button">Save URL</button>
15
  </div>
extension/sidebar/components/TaskCategoryGroup.js CHANGED
@@ -1,10 +1,22 @@
1
  export function TaskCategoryGroup(title, items) {
 
 
 
2
  return `
3
  <div class="category-group">
4
- <p class="group-title">${title}</p>
5
  <ul>
6
- ${items.map((item) => `<li><label><input type="checkbox" checked /> ${item}</label></li>`).join("")}
7
  </ul>
8
  </div>
9
  `;
10
  }
 
 
 
 
 
 
 
 
 
 
1
  export function TaskCategoryGroup(title, items) {
2
+ const safeItems = items.length
3
+ ? items.map((item) => `<li><label><input type="checkbox" checked /> ${escapeHtml(item)}</label></li>`).join("")
4
+ : `<li class="muted">No tasks in this category yet.</li>`;
5
  return `
6
  <div class="category-group">
7
+ <p class="group-title">${escapeHtml(title)}</p>
8
  <ul>
9
+ ${safeItems}
10
  </ul>
11
  </div>
12
  `;
13
  }
14
+
15
+ function escapeHtml(value) {
16
+ return String(value)
17
+ .replaceAll("&", "&amp;")
18
+ .replaceAll("<", "&lt;")
19
+ .replaceAll(">", "&gt;")
20
+ .replaceAll('"', "&quot;")
21
+ .replaceAll("'", "&#39;");
22
+ }
extension/sidebar/components/WorkflowCard.js CHANGED
@@ -7,7 +7,8 @@ export function WorkflowCard(title, mode, steps, ownerInvolvement) {
7
  ${steps.map((step) => `<li>${step}</li>`).join("")}
8
  </ul>
9
  <p class="muted">You do: ${ownerInvolvement}</p>
10
- <button class="primary-button small-button">Choose</button>
 
11
  </article>
12
  `;
13
  }
 
7
  ${steps.map((step) => `<li>${step}</li>`).join("")}
8
  </ul>
9
  <p class="muted">You do: ${ownerInvolvement}</p>
10
+ <button class="primary-button small-button" disabled>Choose</button>
11
+ <p class="muted helper-copy">Preview only. Workflow selection is the next wiring step.</p>
12
  </article>
13
  `;
14
  }
extension/sidebar/components/WorkflowPicker.js CHANGED
@@ -5,6 +5,7 @@ export function WorkflowPicker() {
5
  <section class="screen-card">
6
  <div class="step-label">4. Pick Workflows</div>
7
  <h2>Order Processing</h2>
 
8
  <div class="workflow-grid">
9
  ${WorkflowCard("Workflow A", "Full Auto", ["AI extracts order", "Checks sheet inventory", "Updates sheet and replies"], "Nothing unless alerted")}
10
  ${WorkflowCard("Workflow B", "Review First", ["AI extracts order", "Shows summary in sidebar", "You approve before sending"], "One click per order")}
 
5
  <section class="screen-card">
6
  <div class="step-label">4. Pick Workflows</div>
7
  <h2>Order Processing</h2>
8
+ <p class="muted">These cards are illustrative until we wire real workflow suggestions from the backend.</p>
9
  <div class="workflow-grid">
10
  ${WorkflowCard("Workflow A", "Full Auto", ["AI extracts order", "Checks sheet inventory", "Updates sheet and replies"], "Nothing unless alerted")}
11
  ${WorkflowCard("Workflow B", "Review First", ["AI extracts order", "Shows summary in sidebar", "You approve before sending"], "One click per order")}
extension/sidebar/styles/sidebar.css CHANGED
@@ -147,6 +147,12 @@ body {
147
  margin: 12px 0 0;
148
  }
149
 
 
 
 
 
 
 
150
  .error-copy {
151
  color: #9e2f1f;
152
  }
@@ -171,6 +177,11 @@ body {
171
  padding: 18px;
172
  }
173
 
 
 
 
 
 
174
  ul {
175
  padding-left: 18px;
176
  }
 
147
  margin: 12px 0 0;
148
  }
149
 
150
+ .helper-copy {
151
+ margin: 8px 0 0;
152
+ font-size: 12px;
153
+ line-height: 1.5;
154
+ }
155
+
156
  .error-copy {
157
  color: #9e2f1f;
158
  }
 
177
  padding: 18px;
178
  }
179
 
180
+ button[disabled] {
181
+ cursor: not-allowed;
182
+ opacity: 0.55;
183
+ }
184
+
185
  ul {
186
  padding-left: 18px;
187
  }