diff --git a/html/static/js/table-site.js b/html/static/js/table-site.js
new file mode 100644
index 00000000..df55f2e6
--- /dev/null
+++ b/html/static/js/table-site.js
@@ -0,0 +1,173 @@
+class TableSite extends HTMLElement {
+ constructor() {
+ super();
+ this.attachShadow({ mode: "open" });
+ this._sites = [];
+ }
+
+ /**
+ * Set the sites data and render the table
+ */
+ set sites(value) {
+ this._sites = value;
+ this.render();
+ }
+
+ /**
+ * Get the sites data
+ */
+ get sites() {
+ return this._sites;
+ }
+
+ connectedCallback() {
+ this.render();
+ }
+
+ /**
+ * Get badge color class based on report status
+ */
+ getConditionClass(status) {
+ switch (status) {
+ case "Reported":
+ return "bg-warning text-dark";
+ case "Assigned":
+ return "bg-info text-dark";
+ case "On-Hold":
+ return "bg-secondary";
+ case "Complete":
+ return "bg-success";
+ default:
+ return "bg-secondary";
+ }
+ }
+
+ render() {
+ // Create the styles
+ const style = `
+
+ `;
+
+ // Create the table
+ let tableHTML = `
+
+
+
+ | Site ID |
+ Condition |
+ Address |
+
+
+
+ `;
+
+ // Generate rows for each report
+ if (this._sites.length > 0) {
+ this._sites.forEach((site) => {
+ tableHTML += `
+
+ | ${site.id} |
+ ${site.condition} |
+ ${site.address} |
+
+ `;
+ });
+ } else {
+ tableHTML += `
+ | No sites |
+ `;
+ }
+
+ tableHTML += `
+
+
+ `;
+
+ // Set the shadow DOM content
+ this.shadowRoot.innerHTML = style + tableHTML;
+ // Add click handlers for the rows
+ this.shadowRoot.querySelectorAll("tr.clickable-row").forEach((el) => {
+ el.addEventListener("click", (e) => {
+ let element = e.target;
+ while (element.nodeName != "TR") {
+ element = element.parentElement;
+ }
+ this.dispatchEvent(
+ new CustomEvent("row-clicked", {
+ bubbles: true,
+ composed: true, // Allows event to cross shadow DOM boundary
+ detail: {
+ reportId: element.dataset.reportId,
+ },
+ }),
+ );
+ });
+ });
+ }
+}
+
+// Register the custom element
+customElements.define("table-site", TableSite);
diff --git a/html/template/sync/review/site.html b/html/template/sync/review/site.html
index 6b8c8914..d35a31fc 100644
--- a/html/template/sync/review/site.html
+++ b/html/template/sync/review/site.html
@@ -7,34 +7,25 @@
src="//unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.js"
>
-
@@ -188,7 +135,7 @@ document.addEventListener('DOMContentLoaded', onLoad);