diff --git a/src/components/scanstations/AddScanStationModal.svelte b/src/components/scanstations/AddScanStationModal.svelte
index 64603c54..90f2c4d9 100644
--- a/src/components/scanstations/AddScanStationModal.svelte
+++ b/src/components/scanstations/AddScanStationModal.svelte
@@ -1,7 +1,7 @@
+
+
diff --git a/src/components/shared/TableActions.svelte b/src/components/shared/TableActions.svelte
new file mode 100644
index 00000000..f69afce5
--- /dev/null
+++ b/src/components/shared/TableActions.svelte
@@ -0,0 +1,26 @@
+
+
+{#if detailsLink}
+
{$_("details")}
+{:else if detailsAction}
+
+{/if}
+{#if deleteEnabled}
+
+{/if}
diff --git a/src/components/shared/TableBottom.svelte b/src/components/shared/TableBottom.svelte
new file mode 100644
index 00000000..1d6194fb
--- /dev/null
+++ b/src/components/shared/TableBottom.svelte
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+ Page
+
+ {$table.getState().pagination.pageIndex + 1} of{" "}
+ {$table.getPageCount()}
+
+
+
+ | Go to page:
+ {
+ const page = e.target.value ? Number(e.target.value) - 1 : 0;
+ $table.setPageIndex(page);
+ }}
+ class="border p-1 rounded w-16"
+ />
+
+
+
+
+
+ {Object.keys(selected).length} of{" "}
+ {$table.getPreFilteredRowModel().rows.length} Total Rows Selected
+
diff --git a/src/components/shared/TableHeader.svelte b/src/components/shared/TableHeader.svelte
new file mode 100644
index 00000000..0ab6d9f3
--- /dev/null
+++ b/src/components/shared/TableHeader.svelte
@@ -0,0 +1,57 @@
+
+
+
+ {#if !header.isPlaceholder}
+
+ {/if}
+ {#if header.column.getCanFilter()}
+
+ {
+ header.column.setFilterValue(e.target.value);
+ }}
+ type="text"
+ class="block w-full rounded-md border-gray-200 py-2 pl-8 text-xs focus:border-blue-500 focus:ring-blue-500"
+ placeholder=""
+ />
+
+
+ {/if}
+ |
diff --git a/src/components/shared/tablefilters.js b/src/components/shared/tablefilters.js
new file mode 100644
index 00000000..1a26b2cf
--- /dev/null
+++ b/src/components/shared/tablefilters.js
@@ -0,0 +1,34 @@
+export const groupFilter = (row, columnId, value) => {
+ const group = row.getValue(columnId);
+ if (group.responseType === "RUNNERORGANIZATION") {
+ return group.name.toLowerCase().includes(value.toLowerCase());
+ } else if (value.includes(">")) {
+ return (
+ `${group.parentGroup.name} > ${group.name}`.toLowerCase().includes(value.toLowerCase())
+ );
+ } else {
+ return (
+ group.name.toLowerCase().includes(value.toLowerCase()) ||
+ group.parentGroup.name.toLowerCase().includes(value.toLowerCase())
+ );
+ }
+};
+export const runnerFilter = (row, columnId, value) => {
+ const runner = row.getValue(columnId);
+ if(!runner && value == "blanko"){return true}
+ if(!runner){return false}
+
+ if(value.startsWith("#")){
+ return runner.id == value.replace("#","")
+ }
+
+ if(runner.middlename){
+ return `${runner.firstname} ${runner.middlename} ${runner.lastname}`.toLowerCase().includes(value.toLowerCase())
+ }
+ return `${runner.firstname} ${runner.lastname}`.toLowerCase().includes(value.toLowerCase())
+};
+
+export const statusFilter = (row, columnId, value) => {
+ const status = row.getValue(columnId);
+ return status.toString().includes(value);
+};
\ No newline at end of file
diff --git a/src/components/statsclients/AddStatsClientModal.svelte b/src/components/statsclients/AddStatsClientModal.svelte
index f4a8c00c..f6bd5f19 100644
--- a/src/components/statsclients/AddStatsClientModal.svelte
+++ b/src/components/statsclients/AddStatsClientModal.svelte
@@ -1,7 +1,7 @@