Index: pages/+Layout.telefunc.ts
===================================================================
--- pages/+Layout.telefunc.ts	(revision 5ce5904505744192d6f836fac3fea6ddf058d6ea)
+++ pages/+Layout.telefunc.ts	(revision 226fbbbab48f243ba6045007157b751910cdc7fb)
@@ -2,6 +2,7 @@
 import {ctx, getAuthState, requireUser} from "../server/telefunc/ctx";
 import {Abort} from "telefunc";
+import type {Database} from "../database/drizzle/db";
 
-export async function getAuthenticationState() {
+export async function AuthenticationState() {
     const context = getAuthState();
 
@@ -9,5 +10,5 @@
 }
 
-export async function getPopupAllComponents({ componentType, limit, q }
+export async function onGetAllComponents({ componentType, limit, q }
                                             : { componentType?: string; limit?: number; q?: string }) {
     const c = ctx();
@@ -18,5 +19,5 @@
 }
 
-export async function getPopupComponentDetails({ componentId }
+export async function onGetComponentDetails({ componentId }
                                            : { componentId: number }) {
     const context = ctx();
@@ -31,9 +32,9 @@
 }
 
-export async function getPopupSuggestComponent({ link, description, componentType }
+export async function onSuggestComponent({ link, description, componentType }
                                                : { link: string; description: string; componentType: string }) {
     const { c, userId } = requireUser()
 
-    const newSuggestionId = await drizzleQueries.addComponentSuggestion(c.db, userId, link, description, componentType);
+    const newSuggestionId = await drizzleQueries.addNewComponentSuggestion(c.db, userId, link, description, componentType);
 
     if(!newSuggestionId) throw Abort();
@@ -42,5 +43,5 @@
 }
 
-export async function getPopupAllApprovedBuilds({ limit, q }
+export async function onGetApprovedBuilds({ limit, q }
                                                  : { limit?: number; q?: string }) {
     const context = ctx();
@@ -51,5 +52,5 @@
 }
 
-export async function getPopupHighestRankedBuilds({ limit }
+export async function onGetHighestRankedBuilds({ limit }
                                                   : { limit?: number }) {
     const context = ctx();
@@ -62,5 +63,5 @@
 // Shared
 
-export async function getPopupBuildDetails({ buildId }
+export async function onGetBuildDetails({ buildId }
                                            : { buildId: number }) {
     const context = getAuthState();
@@ -75,5 +76,5 @@
 }
 
-export async function togglePopupFavorite({ buildId }
+export async function onToggleFavorite({ buildId }
                                           : { buildId: number }) {
     const { c, userId } = requireUser()
@@ -86,5 +87,5 @@
 }
 
-export async function setPopupRating({ buildId, value }
+export async function onSetRating({ buildId, value }
                                      : { buildId: number; value: number }) {
     const { c, userId } = requireUser()
@@ -99,5 +100,5 @@
 }
 
-export async function setPopupReview({ buildId, content }
+export async function onSetReview({ buildId, content }
                                      : { buildId: number; content: string }) {
     const { c, userId } = requireUser()
@@ -110,5 +111,5 @@
 }
 
-export async function clonePopupBuild({ buildId }
+export async function onCloneBuild({ buildId }
                                       : { buildId: number }) {
     const { c, userId } = requireUser()
@@ -116,8 +117,14 @@
     if (!Number.isInteger(buildId) || buildId <= 0) throw Abort();
 
-    const newBuildId = await drizzleQueries.cloneBuild(c.db, userId, buildId);
+    const newBuild = await drizzleQueries.cloneBuild(c.db, userId, buildId);
 
-    if (!newBuildId) throw Abort();
+    if (!newBuild) throw Abort();
 
-    return newBuildId;
+    return newBuild;
 }
+
+
+
+
+
+
Index: pages/dashboard/admin/adminDashboard.telefunc.ts
===================================================================
--- pages/dashboard/admin/adminDashboard.telefunc.ts	(revision 5ce5904505744192d6f836fac3fea6ddf058d6ea)
+++ pages/dashboard/admin/adminDashboard.telefunc.ts	(revision 226fbbbab48f243ba6045007157b751910cdc7fb)
@@ -2,4 +2,5 @@
 import { requireAdmin } from "../../../server/telefunc/ctx";
 import {Abort} from "telefunc";
+import { validateComponentSpecificData } from "../../../database/drizzle/config/componentFieldConfig";
 
 export async function getAdminInfoAndData() {
@@ -22,5 +23,5 @@
 }
 
-export async function setPopupBuildApprovalStatus({ buildId, isApproved }
+export async function onSetBuildApprovalStatus({ buildId, isApproved }
                                                  : { buildId: number; isApproved: boolean }) {
     const { c, userId } = await requireAdmin()
@@ -35,5 +36,5 @@
 }
 
-export async function setComponentSuggestionStatus({ suggestionId, status, adminComment }
+export async function onSetComponentSuggestionStatus({ suggestionId, status, adminComment }
                                                 : { suggestionId: number; status: string; adminComment: string }) {
     const { c, userId } = await requireAdmin()
@@ -48,2 +49,16 @@
     return { success: true };
 }
+
+export async function onCreateNewComponent({ name, brand, price, imgUrl, type, specificData }
+                                            : { name: string; brand: string; price: number; imgUrl: string; type: string, specificData: any }) {
+
+    const { c, userId } = await requireAdmin()
+
+    if(!validateComponentSpecificData(type, specificData)) throw Abort();
+
+    const newComponentId = await drizzleQueries.addNewComponent(c.db, name, brand, price, imgUrl, type, specificData);
+
+    if(!newComponentId) throw Abort();
+
+    return newComponentId;
+}
Index: pages/dashboard/user/userDashboard.telefunc.ts
===================================================================
--- pages/dashboard/user/userDashboard.telefunc.ts	(revision 5ce5904505744192d6f836fac3fea6ddf058d6ea)
+++ pages/dashboard/user/userDashboard.telefunc.ts	(revision 226fbbbab48f243ba6045007157b751910cdc7fb)
@@ -1,4 +1,5 @@
 import * as drizzleQueries from "../../../database/drizzle/queries";
 import {requireUser} from "../../../server/telefunc/ctx";
+import {Abort} from "telefunc";
 
 export async function getUserInfoAndData() {
@@ -18,2 +19,39 @@
     };
 }
+
+export async function onDeleteBuild({ buildId }
+                                  : { buildId: number }) {
+    const { c, userId } = requireUser()
+
+    if (!Number.isInteger(buildId) || buildId <= 0) throw Abort();
+
+    const result = await drizzleQueries.deleteBuild(c.db, userId, buildId);
+
+    return { success: true };
+}
+
+export async function onEditBuild({ buildId }
+                                  : { buildId: number }) {
+    const { c, userId } = requireUser()
+
+    if(!Number.isInteger(buildId) || buildId <= 0) throw Abort();
+
+    const buildDetails = await drizzleQueries.getBuildDetails(c.db, buildId, userId);
+
+    if(!buildDetails) throw Abort();
+
+    return buildDetails;
+}
+
+export async function onSaveEditBuild({ buildId, name, description, componentIds }
+                                      : { buildId: number; name: string; description: string; componentIds: number[] }) {
+    const { c, userId } = requireUser()
+
+    if (!Number.isInteger(buildId) || buildId <= 0) throw Abort();
+
+    const result = await drizzleQueries.editBuild(c.db, userId, buildId, name, description, componentIds);
+
+    if(!result) throw Abort();
+
+    return { success: true };
+}
Index: pages/forge/forge.telefunc.ts
===================================================================
--- pages/forge/forge.telefunc.ts	(revision 226fbbbab48f243ba6045007157b751910cdc7fb)
+++ pages/forge/forge.telefunc.ts	(revision 226fbbbab48f243ba6045007157b751910cdc7fb)
@@ -0,0 +1,15 @@
+import * as drizzleQueries from "../../database/drizzle/queries";
+import {ctx, getAuthState, requireUser} from "../../server/telefunc/ctx";
+import {Abort} from "telefunc";
+import type {Database} from "../../database/drizzle/db";
+
+export async function onSaveNewBuild({ name, description, componentIds }
+                                       : { name: string; description: string; componentIds: number[] }) {
+    const { c, userId } = requireUser()
+
+    const newBuildId = await drizzleQueries.addNewBuild(c.db, userId, name, description, componentIds);
+
+    if(!newBuildId) throw Abort();
+
+    return { success: true };
+}
Index: pages/index/approvedBuilds.telefunc.ts
===================================================================
--- pages/index/approvedBuilds.telefunc.ts	(revision 5ce5904505744192d6f836fac3fea6ddf058d6ea)
+++ 	(revision )
@@ -1,11 +1,0 @@
-import * as drizzleQueries from "../../database/drizzle/queries";
-import { ctx } from "../../server/telefunc/ctx";
-
-export async function getApprovedBuildCards( { limit }
-                                       : { limit?: number }) {
-    const context = ctx();
-
-    const approvedBuilds = await drizzleQueries.getApprovedBuilds(context.db, limit);
-
-    return approvedBuilds;
-}
