# Unified Infrastructure Pages - Design Document

**Approach:** Single set of pages that dynamically handles servers, switches, and cameras
**Files Required:** 4 files (vs 12 separate files)

---

## Architecture

### URL Structure
```
displayinfrastructure.asp?type=server     → List all servers
displayinfrastructure.asp?type=switch     → List all switches
displayinfrastructure.asp?type=camera     → List all cameras

displayinfrastructure_detail.asp?type=server&id=5    → Server #5 detail/edit
displayinfrastructure_detail.asp?type=switch&id=12   → Switch #12 detail/edit
displayinfrastructure_detail.asp?type=camera&id=3    → Camera #3 detail/edit

addinfrastructure.asp?type=server         → Add new server form
addinfrastructure.asp?type=switch         → Add new switch form
addinfrastructure.asp?type=camera         → Add new camera form

saveinfrastructure_direct.asp             → Universal save endpoint
```

---

## File 1: displayinfrastructure.asp (List View)

### Logic Flow
```vbscript
<%
' Get device type from URL
Dim deviceType
deviceType = Request.QueryString("type")

' Validate type
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
    deviceType = "server" ' Default
End If

' Set display variables based on type
Dim tableName, idField, pageTitle, iconClass, addUrl
Select Case deviceType
    Case "server"
        tableName = "servers"
        idField = "serverid"
        pageTitle = "Servers"
        iconClass = "zmdi-storage"
        addUrl = "addinfrastructure.asp?type=server"
    Case "switch"
        tableName = "switches"
        idField = "switchid"
        pageTitle = "Switches"
        iconClass = "zmdi-device-hub"
        addUrl = "addinfrastructure.asp?type=switch"
    Case "camera"
        tableName = "cameras"
        idField = "cameraid"
        pageTitle = "Cameras"
        iconClass = "zmdi-videocam"
        addUrl = "addinfrastructure.asp?type=camera"
End Select

' Build query
Dim strSQL
strSQL = "SELECT d.*, m.modelnumber, v.vendor " & _
         "FROM " & tableName & " d " & _
         "LEFT JOIN models m ON d.modelid = m.modelnumberid " & _
         "LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
         "WHERE d.isactive = 1 " & _
         "ORDER BY d." & idField & " DESC"

Set rs = objConn.Execute(strSQL)
%>

<h5 class="card-title">
    <i class="zmdi <%=iconClass%>"></i> <%=pageTitle%>
</h5>
<a href="<%=addUrl%>" class="btn btn-primary">
    <i class="zmdi zmdi-plus-circle"></i> Add <%=pageTitle%>
</a>

<table class="table table-hover">
    <thead>
        <tr>
            <th>ID</th>
            <th>Vendor</th>
            <th>Model</th>
            <th>Serial</th>
            <th>IP Address</th>
            <th>Description</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
    <% Do While Not rs.EOF %>
        <tr>
            <td><%=rs(idField)%></td>
            <td><%=Server.HTMLEncode(rs("vendor") & "")%></td>
            <td><%=Server.HTMLEncode(rs("modelnumber") & "")%></td>
            <td><%=Server.HTMLEncode(rs("serialnumber") & "")%></td>
            <td><%=Server.HTMLEncode(rs("ipaddress") & "")%></td>
            <td><%=Server.HTMLEncode(rs("description") & "")%></td>
            <td>
                <a href="displayinfrastructure_detail.asp?type=<%=deviceType%>&id=<%=rs(idField)%>">
                    View
                </a>
            </td>
        </tr>
    <%
        rs.MoveNext
    Loop
    %>
    </tbody>
</table>
```

---

## File 2: displayinfrastructure_detail.asp (Detail/Edit View)

### Logic Flow
```vbscript
<%
' Get device type and ID
Dim deviceType, deviceId
deviceType = Request.QueryString("type")
deviceId = Request.QueryString("id")

' Validate
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
    Response.Redirect("displayinfrastructure.asp?type=server")
End If

' Set variables based on type
Dim tableName, idField, pageTitle, listUrl
Select Case deviceType
    Case "server"
        tableName = "servers"
        idField = "serverid"
        pageTitle = "Server"
        listUrl = "displayinfrastructure.asp?type=server"
    Case "switch"
        tableName = "switches"
        idField = "switchid"
        pageTitle = "Switch"
        listUrl = "displayinfrastructure.asp?type=switch"
    Case "camera"
        tableName = "cameras"
        idField = "cameraid"
        pageTitle = "Camera"
        listUrl = "displayinfrastructure.asp?type=camera"
End Select

' Fetch device
strSQL = "SELECT d.*, m.modelnumber, v.vendor, v.vendorid " & _
         "FROM " & tableName & " d " & _
         "LEFT JOIN models m ON d.modelid = m.modelnumberid " & _
         "LEFT JOIN vendors v ON m.vendorid = v.vendorid " & _
         "WHERE d." & idField & " = " & deviceId

Set rs = objConn.Execute(strSQL)

If rs.EOF Then
    Response.Write("Device not found")
    Response.End
End If
%>

<!-- Display Mode -->
<div id="displayMode">
    <h3><%=pageTitle%> #<%=rs(idField)%></h3>
    <p><strong>Vendor:</strong> <%=Server.HTMLEncode(rs("vendor") & "")%></p>
    <p><strong>Model:</strong> <%=Server.HTMLEncode(rs("modelnumber") & "")%></p>
    <p><strong>Serial:</strong> <%=Server.HTMLEncode(rs("serialnumber") & "")%></p>
    <p><strong>IP:</strong> <%=Server.HTMLEncode(rs("ipaddress") & "")%></p>
    <p><strong>Description:</strong> <%=Server.HTMLEncode(rs("description") & "")%></p>

    <button onclick="showEditMode()">Edit</button>
    <a href="<%=listUrl%>">Back to List</a>
</div>

<!-- Edit Mode -->
<div id="editMode" style="display:none;">
    <h3>Edit <%=pageTitle%></h3>
    <form method="post" action="saveinfrastructure_direct.asp">
        <input type="hidden" name="type" value="<%=deviceType%>">
        <input type="hidden" name="id" value="<%=rs(idField)%>">

        <!-- Model dropdown -->
        <select name="modelid">
            <!-- Populate models... -->
        </select>

        <input type="text" name="serialnumber" value="<%=Server.HTMLEncode(rs("serialnumber") & "")%>">
        <input type="text" name="ipaddress" value="<%=Server.HTMLEncode(rs("ipaddress") & "")%>">
        <textarea name="description"><%=Server.HTMLEncode(rs("description") & "")%></textarea>

        <button type="submit">Save</button>
        <button type="button" onclick="showDisplayMode()">Cancel</button>
    </form>
</div>
```

---

## File 3: addinfrastructure.asp (Add Form)

### Logic Flow
```vbscript
<%
' Get device type
Dim deviceType
deviceType = Request.QueryString("type")

' Validate
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
    deviceType = "server"
End If

' Set variables
Dim pageTitle, listUrl
Select Case deviceType
    Case "server"
        pageTitle = "Server"
        listUrl = "displayinfrastructure.asp?type=server"
    Case "switch"
        pageTitle = "Switch"
        listUrl = "displayinfrastructure.asp?type=switch"
    Case "camera"
        pageTitle = "Camera"
        listUrl = "displayinfrastructure.asp?type=camera"
End Select
%>

<h2>Add <%=pageTitle%></h2>

<form method="post" action="saveinfrastructure_direct.asp">
    <input type="hidden" name="type" value="<%=deviceType%>">

    <div class="form-group">
        <label>Model</label>
        <select name="modelid" required class="form-control">
            <option value="">-- Select Model --</option>
            <%
            strSQL = "SELECT m.modelnumberid, m.modelnumber, v.vendor " & _
                     "FROM models m " & _
                     "INNER JOIN vendors v ON m.vendorid = v.vendorid " & _
                     "WHERE m.isactive = 1 " & _
                     "ORDER BY v.vendor, m.modelnumber"
            Set rsModels = objConn.Execute(strSQL)
            Do While Not rsModels.EOF
            %>
                <option value="<%=rsModels("modelnumberid")%>">
                    <%=Server.HTMLEncode(rsModels("vendor") & " - " & rsModels("modelnumber"))%>
                </option>
            <%
                rsModels.MoveNext
            Loop
            %>
        </select>
    </div>

    <div class="form-group">
        <label>Serial Number</label>
        <input type="text" name="serialnumber" class="form-control" maxlength="100">
    </div>

    <div class="form-group">
        <label>IP Address</label>
        <input type="text" name="ipaddress" class="form-control" maxlength="15">
    </div>

    <div class="form-group">
        <label>Description</label>
        <textarea name="description" class="form-control" rows="3"></textarea>
    </div>

    <button type="submit" class="btn btn-success">Save <%=pageTitle%></button>
    <a href="<%=listUrl%>" class="btn btn-secondary">Cancel</a>
</form>
```

---

## File 4: saveinfrastructure_direct.asp (Universal Save)

### Logic Flow
```vbscript
<!--#include file="./includes/sql.asp"-->
<!--#include file="./includes/error_handler.asp"-->
<!--#include file="./includes/validation.asp"-->
<!--#include file="./includes/db_helpers.asp"-->

<%
' Get device type
Dim deviceType
deviceType = Request.Form("type")

' Validate type
If deviceType <> "server" AND deviceType <> "switch" AND deviceType <> "camera" Then
    Response.Write("Error: Invalid device type")
    Response.End
End If

' Set table name and ID field based on type
Dim tableName, idField, listUrl
Select Case deviceType
    Case "server"
        tableName = "servers"
        idField = "serverid"
        listUrl = "displayinfrastructure.asp?type=server"
    Case "switch"
        tableName = "switches"
        idField = "switchid"
        listUrl = "displayinfrastructure.asp?type=switch"
    Case "camera"
        tableName = "cameras"
        idField = "cameraid"
        listUrl = "displayinfrastructure.asp?type=camera"
End Select

' Get form data
Dim deviceId, modelid, serialnumber, ipaddress, description
deviceId = GetSafeInteger("FORM", "id", 0, 0, 999999)
modelid = GetSafeInteger("FORM", "modelid", 0, 0, 999999)
serialnumber = GetSafeString("FORM", "serialnumber", "", 0, 100, "^[A-Za-z0-9\-]+$")
ipaddress = GetSafeString("FORM", "ipaddress", "", 0, 15, "^[0-9\.]+$")
description = GetSafeString("FORM", "description", "", 0, 255, "")

' Determine INSERT or UPDATE
Dim strSQL

If deviceId = 0 Then
    ' INSERT - New device
    strSQL = "INSERT INTO " & tableName & " (modelid, serialnumber, ipaddress, description, isactive) " & _
             "VALUES (?, ?, ?, ?, 1)"
    Set rs = ExecuteParameterizedQuery(objConn, strSQL, Array(modelid, serialnumber, ipaddress, description))
Else
    ' UPDATE - Existing device
    strSQL = "UPDATE " & tableName & " " & _
             "SET modelid = ?, serialnumber = ?, ipaddress = ?, description = ? " & _
             "WHERE " & idField & " = ?"
    Set rs = ExecuteParameterizedQuery(objConn, strSQL, Array(modelid, serialnumber, ipaddress, description, deviceId))
End If

Call CleanupResources()

' Redirect back to list
Response.Redirect(listUrl)
%>
```

---

## Navigation Menu

### leftsidebar.asp Update
```html
<!-- Infrastructure Section -->
<li class="nav-header">INFRASTRUCTURE</li>
<li>
    <a href="displayinfrastructure.asp?type=server">
        <i class="zmdi zmdi-storage"></i> Servers
    </a>
</li>
<li>
    <a href="displayinfrastructure.asp?type=switch">
        <i class="zmdi zmdi-device-hub"></i> Switches
    </a>
</li>
<li>
    <a href="displayinfrastructure.asp?type=camera">
        <i class="zmdi zmdi-videocam"></i> Cameras
    </a>
</li>
```

---

## Pros vs Cons

### Unified Approach (Option 2) - RECOMMENDED

**Pros:**
-  Only 4 files to create (vs 12)
-  DRY - no code duplication
-  Easy to maintain - fix once, works for all
-  Easy to extend - add "UPS" or "Firewall" by just adding cases
-  Consistent UI across all infrastructure
-  Matches database design (vw_network_devices already unifies them)

**Cons:**
-  Slightly more complex logic (Select Case statements)
-  URLs less intuitive (type parameter required)
-  Harder to customize one type differently later

### Separate Pages Approach (Option 1)

**Pros:**
-  URLs cleaner (displayservers.asp vs displayinfrastructure.asp?type=server)
-  Simpler per-file logic (no branching)
-  Easy to customize one type differently
-  More explicit/clear what page does

**Cons:**
-  12 files instead of 4 (3x code duplication)
-  Bug fixes need to be applied 3 times
-  UI inconsistencies more likely
-  Adding new type = 4 more files

---

## Hybrid Approach (Best of Both?)

**Could also do:**
- Use unified pages for LIST/ADD/SAVE (shared logic)
- Use separate pages for DETAIL if they differ significantly

Example:
```
displayinfrastructure.asp?type=server       (unified list)
addinfrastructure.asp?type=server          (unified add form)
saveinfrastructure_direct.asp              (unified save)

displayserver.asp?id=5                     (separate detail - if servers need special fields)
displayswitch.asp?id=12                    (separate detail - if switches different)
displaycamera.asp?id=3                     (separate detail - if cameras different)
```

But for infrastructure devices with identical schemas, I'd stick with **fully unified**.

---

## My Recommendation

**Go with Option 2 (Unified Pages) because:**

1. Servers, switches, and cameras have **identical schemas** (modelid, serialnumber, ipaddress, description, maptop, mapleft, isactive)
2. They have **identical CRUD operations** (add, edit, view, delete)
3. The database already unifies them (`vw_network_devices`)
4. Much faster to implement (4 files vs 12)
5. Easier to maintain long-term

---

**Ready to implement?** I can create the 4 unified infrastructure files now.

