{
  "id": "VDut3fLvTiutz3bF",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Customer Feedback Collector",
  "tags": [],
  "nodes": [
    {
      "id": "e12b4e8b-25e7-4650-8421-3b31bd39260b",
      "name": "Feedback Input HTML",
      "type": "n8n-nodes-base.html",
      "position": [
        352,
        0
      ],
      "parameters": {
        "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n  <title>{{ $('Form Configuration').item.json.Title }}</title>\n  <style>\n    :root {\n      --bg: {{ $json.bg }};\n      --card: {{ $json.card }};\n      --text: {{ $json.text }};\n      --muted: {{ $json.muted }};\n      --accent: {{ $json.accent }};\n      --accent-contrast: {{ $json[\"accent-contrast\"] }};\n      --border: {{ $json.border }};\n      --star: {{ $json.star }};\n      --star-active: {{ $json[\"star-active\"] }};\n      --focus: {{ $json.focus }};\n      --radius: {{ $json.radius }};\n      --shadow: {{ $json.shadow }};\n      --maxw: {{ $json.maxw }};\n      --star-size: {{ $json[\"star-size\"] }};\n    }\n\n    * { box-sizing: border-box; }\n    html, body { height: 100%; }\n    body {\n      margin: 0;\n      font: 16px/1.5 system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\";\n      background: var(--bg);\n      color: var(--text);\n      display: grid;\n      place-items: center;\n      padding: 24px;\n    }\n\n    .card {\n      width: 100%;\n      max-width: var(--maxw);\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: var(--radius);\n      box-shadow: var(--shadow);\n      padding: 24px;\n    }\n\n    h1 { font-size: 1.25rem; margin: 0 0 4px; }\n    .sub { color: var(--muted); margin: 0 0 18px; font-size: 0.95rem; }\n\n    form { display: grid; gap: 18px; }\n    .field { display: grid; gap: 10px; }\n    label.top { font-weight: 600; }\n\n    .stars {\n      display: flex;\n      flex-direction: row-reverse;\n      justify-content: flex-end;\n      gap: 6px;\n    }\n\n    .stars input {\n      position: absolute;\n      inline-size: 1px;\n      block-size: 1px;\n      margin: -1px;\n      padding: 0;\n      border: 0;\n      clip: rect(0 0 0 0);\n      clip-path: inset(50%);\n      overflow: hidden;\n      white-space: nowrap;\n    }\n\n    .stars label {\n      cursor: pointer;\n      font-size: var(--star-size);\n      line-height: 1;\n      filter: drop-shadow(0 1px 0 rgba(0,0,0,0.05));\n    }\n\n    .stars label span { color: var(--star); transition: color 150ms ease; }\n    .stars label:hover span,\n    .stars label:hover ~ label span { color: var(--star-active); }\n    .stars input:checked ~ label span { color: var(--star-active); }\n\n    textarea {\n      width: 100%;\n      min-height: 110px;\n      resize: vertical;\n      padding: 12px 14px;\n      border-radius: 12px;\n      border: 1px solid var(--border);\n      background: #fff;\n      color: var(--text);\n      font: inherit;\n    }\n\n    textarea:focus { outline: none; box-shadow: var(--focus); border-color: var(--accent); }\n\n    .actions { display: flex; gap: 12px; justify-content: flex-end; }\n\n    button {\n      appearance: none;\n      border: 1px solid var(--accent);\n      background: var(--accent);\n      color: var(--accent-contrast);\n      padding: 10px 16px;\n      border-radius: 12px;\n      font-weight: 600;\n      cursor: pointer;\n      box-shadow: 0 6px 16px rgba(59, 130, 246, 0.25);\n    }\n\n    .muted-btn { background: transparent; color: var(--text); border-color: var(--border); box-shadow: none; }\n  </style>\n</head>\n<body>\n  <main class=\"card\" aria-labelledby=\"title\">\n    <h1 id=\"title\">{{ $('Form Configuration').item.json.Header }}</h1>\n    <p class=\"sub\">{{ $('Form Configuration').item.json.Description }}</p>\n\n    <form action=\"{{ $('Form Configuration').item.json.PostFeedbackLink }}{{ $('Form Configuration').item.json.queryParams }}\" method=\"POST\">\n      <div class=\"field\">\n        <label class=\"top\" for=\"rating-1\">Star rating <span aria-hidden=\"true\">*</span></label>\n        <div class=\"stars\" role=\"radiogroup\" aria-label=\"Star rating from 1 to 5\">\n          <input type=\"radio\" name=\"rating\" id=\"rating-5\" value=\"5\" required>\n          <label for=\"rating-5\" title=\"5 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-4\" value=\"4\" required>\n          <label for=\"rating-4\" title=\"4 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-3\" value=\"3\" required>\n          <label for=\"rating-3\" title=\"3 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-2\" value=\"2\" required>\n          <label for=\"rating-2\" title=\"2 stars\"><span>\u2605</span></label>\n\n          <input type=\"radio\" name=\"rating\" id=\"rating-1\" value=\"1\" required>\n          <label for=\"rating-1\" title=\"1 star\"><span>\u2605</span></label>\n        </div>\n      </div>\n\n      <div class=\"field\">\n        <label class=\"top\" for=\"message\">Message (optional)</label>\n        <textarea id=\"message\" name=\"message\" placeholder=\"Tell us a bit more\u2026\"></textarea>\n      </div>\n\n      <div class=\"actions\">\n        <button type=\"reset\" class=\"muted-btn\">{{ $('Form Configuration').item.json.ClearBtn }}</button>\n        <button type=\"submit\">{{ $('Form Configuration').item.json.SubmitBtn }}</button>\n      </div>\n    </form>\n  </main>\n</body>\n</html>"
      },
      "typeVersion": 1.2
    },
    {
      "id": "3cb73422-b12a-4afe-a76f-d935ad253497",
      "name": "Form Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -96,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "eb90800e-3fba-4f93-9058-3b663d6d92b1",
              "name": "Title",
              "type": "string",
              "value": "Simple Feedback Input"
            },
            {
              "id": "9b12be64-eca5-46b0-be34-a2760c03d356",
              "name": "Header",
              "type": "string",
              "value": "Rate your experience"
            },
            {
              "id": "230249b4-6431-455c-94fa-640720e4eb77",
              "name": "Description",
              "type": "string",
              "value": "Your rating helps us improve. Stars are required; message is optional."
            },
            {
              "id": "5c4f7ad0-b1dd-4eb5-9795-42b1051fa57e",
              "name": "ClearBtn",
              "type": "string",
              "value": "Clear"
            },
            {
              "id": "be71a869-305f-4039-a5aa-1d6f03fc50db",
              "name": "SubmitBtn",
              "type": "string",
              "value": "Submit feedback"
            },
            {
              "id": "d5b8e79b-fd2c-4cc5-9885-7259ee700477",
              "name": "PostFeedbackLink",
              "type": "string",
              "value": "https://sus-tech.app.n8n.cloud/webhook-test/feedback"
            },
            {
              "id": "4da8b6ef-efac-40d3-bdae-d06215fea967",
              "name": "queryParams",
              "type": "string",
              "value": "={{ $json.query && Object.keys($json.query).length\n  ? '?' + Object.keys($json.query)\n      .filter(k => $json.query[k] !== undefined && $json.query[k] !== null && $json.query[k] !== '')\n      .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(String($json.query[k])))\n      .join('&')\n  : ''\n}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "cf34fc30-a548-41a5-a408-2d2bc12a3d86",
      "name": "Post Feedback",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -320,
        224
      ],
      "parameters": {
        "path": "feedback",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "e84bbcd8-da2c-48ba-b35b-2e46a3482a0f",
      "name": "Input Feedback",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -320,
        0
      ],
      "parameters": {
        "path": "feedback",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "8cc22ea0-5c45-49cf-89c2-a1b4127db156",
      "name": "Page Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        128,
        224
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "40ca52c0-1258-4e59-aaa8-dd933d165c88",
              "name": "Title",
              "type": "string",
              "value": "Thank You for Your Feedback"
            },
            {
              "id": "94332494-7637-4df4-9281-e31fec3972ff",
              "name": "Header",
              "type": "string",
              "value": "Thank You!"
            },
            {
              "id": "82d691be-165a-44ef-be1b-8139e5a08eba",
              "name": "Description",
              "type": "string",
              "value": "We appreciate your feedback \u2014 it helps us improve our service."
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "df3617bd-2f2d-4710-a5c6-2dde47088291",
      "name": "Theme Configuration - Feedback Input",
      "type": "n8n-nodes-base.set",
      "position": [
        128,
        0
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"bg\": \"#f7f8fb\",\n  \"card\": \"#ffffff\",\n  \"text\": \"#1f2937\",\n  \"muted\": \"#6b7280\",\n  \"accent\": \"#3b82f6\",\n  \"accent-contrast\": \"#ffffff\",\n  \"border\": \"#e5e7eb\",\n  \"star\": \"#cbd5e1\",\n  \"star-active\": \"#f59e0b\",\n  \"focus\": \"0 0 0 4px rgba(59, 130, 246, 0.25)\",\n  \"radius\": \"16px\",\n  \"shadow\": \"0 10px 25px rgba(2, 6, 23, 0.06), 0 4px 10px rgba(2, 6, 23, 0.04)\",\n  \"maxw\": \"560px\",\n  \"star-size\": \"28px\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "478081b7-dda8-4963-a388-b38a0c289000",
      "name": "Feedback Submitted HTML",
      "type": "n8n-nodes-base.html",
      "position": [
        576,
        224
      ],
      "parameters": {
        "html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n  <title>Thank You for Your Feedback</title>\n  <style>\n    :root {\n      --bg: #f7f8fb;\n      --card: #ffffff;\n      --muted: #6b7280;\n      --border: #e5e7eb;\n      --radius: 16px;\n      --shadow: 0 10px 25px rgba(2, 6, 23, 0.06), 0 4px 10px rgba(2, 6, 23, 0.04);\n      --maxw: 560px;\n    }\n\n    * { box-sizing: border-box; }\n    html, body { height: 100%; }\n\n    body {\n      margin: 0;\n      font: 16px/1.5 system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Helvetica, Arial;\n      background: var(--bg);\n      color: var(--text);\n      display: grid;\n      place-items: center;\n      padding: 24px;\n    }\n\n    .card {\n      width: 100%;\n      max-width: var(--maxw);\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: var(--radius);\n      box-shadow: var(--shadow);\n      padding: 40px 28px;\n      text-align: center;\n    }\n\n    h1 {\n      font-size: 1.6rem;\n    }\n\n    p.sub {\n      color: var(--muted);\n      font-size: 1rem;\n    }\n  </style>\n</head>\n<body>\n  <main class=\"card\">\n    <h1>Thank You!</h1>\n    <p class=\"sub\">We appreciate your feedback \u2014 it helps us improve our service.</p>\n  </main>\n</body>\n</html>"
      },
      "typeVersion": 1.2
    },
    {
      "id": "adf15b9a-be26-4db1-8d95-052b557e69d8",
      "name": "Theme Configuration - Feedback Submitted",
      "type": "n8n-nodes-base.set",
      "position": [
        352,
        224
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"bg\": \"#f7f8fb\",\n  \"card\": \"#ffffff\",\n  \"muted\": \"#6b7280\",\n  \"border\": \"#e5e7eb\",\n  \"radius\": \"16px\",\n  \"shadow\": \"0 10px 25px rgba(2, 6, 23, 0.06), 0 4px 10px rgba(2, 6, 23, 0.04)\",\n  \"maxw\": \"560px\"\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "5d455df8-2475-4d9e-a3d4-910b71b7e426",
      "name": "Respond with Feedback Submitted",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        800,
        224
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{ $json.html }}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "721dbba9-5668-481c-b775-3c0af3e0a905",
      "name": "Respond with Feedback Input",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        576,
        0
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{ $json.html }}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "6217311f-fe16-4240-a8c2-69708c26641b",
      "name": "Save Feedback to Data Table",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        -96,
        224
      ],
      "parameters": {
        "columns": {
          "value": {
            "rating": "={{ $json.body.rating }}",
            "message": "={{ $json.body.message }}",
            "additionalInformation": "={{ JSON.stringify($json.query) }}"
          },
          "schema": [
            {
              "id": "rating",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "rating",
              "defaultMatch": false
            },
            {
              "id": "message",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "message",
              "defaultMatch": false
            },
            {
              "id": "additionalInformation",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "additionalInformation",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "0wPZ9d7FiU9fblye",
          "cachedResultUrl": "/projects/YLDgXBJO8HihYrEM/datatables/0wPZ9d7FiU9fblye",
          "cachedResultName": "Feedback"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d814b58f-c0e4-436f-a3d6-e86b072c3607",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        -176
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "content": "### Overview\n- Collects quick **1\u20135\u2b50 feedback** + optional message.  \n- Saves results to an **n8n Data Table**, including any query params.  \n- Displays a simple **\u201cThank you\u201d** confirmation page.  \n- Fully self-contained \u2014 **no external services or creds** needed."
      },
      "typeVersion": 1
    },
    {
      "id": "64b43e7f-8f92-4ba7-acef-c0fd2b2bea1a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        -176
      ],
      "parameters": {
        "color": 5,
        "width": 672,
        "content": "### Setup\n* Open **Form Configuration** \u2192 update title, text, and `PostFeedbackLink` (the POST Feedback webhook URL).  \n* Optionally adjust **Theme Configuration**\n* Confirm **Data Table** mapping (rating, message, additional info).  "
      },
      "typeVersion": 1
    },
    {
      "id": "bedfbab0-58d1-4371-aeba-6e724e58b3db",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        0
      ],
      "parameters": {
        "width": 480,
        "content": "### How It Works\n- **GET `/feedback`** \u2192 renders the styled HTML form.  \n- **POST `/feedback`** \u2192 receives rating/message, saves to Data Table, returns confirmation.  \n- Query params (e.g. `?userId=123&source=email`) are automatically stored as JSON.  "
      },
      "typeVersion": 1
    },
    {
      "id": "f4c0fb33-498f-4b00-a901-bed5794604f0",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        176
      ],
      "parameters": {
        "color": 6,
        "width": 480,
        "height": 192,
        "content": "### Notes\n- Only submitted fields + query info are stored. \n- If something fails:  \n  - Ensure both webhooks are published. \n  - Verify the `PostFeedbackLink`\n  - Check Data Table schema matches node mapping.  \n- Need help? \u2709\ufe0f **office@sus-tech.at**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f40e8a7d-45dc-4054-aaa6-8ce99afff84b",
  "connections": {
    "Post Feedback": {
      "main": [
        [
          {
            "node": "Save Feedback to Data Table",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Input Feedback": {
      "main": [
        [
          {
            "node": "Form Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Form Configuration": {
      "main": [
        [
          {
            "node": "Theme Configuration - Feedback Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Page Configuration": {
      "main": [
        [
          {
            "node": "Theme Configuration - Feedback Submitted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Feedback Input HTML": {
      "main": [
        [
          {
            "node": "Respond with Feedback Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Feedback Submitted HTML": {
      "main": [
        [
          {
            "node": "Respond with Feedback Submitted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Feedback to Data Table": {
      "main": [
        [
          {
            "node": "Page Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theme Configuration - Feedback Input": {
      "main": [
        [
          {
            "node": "Feedback Input HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Theme Configuration - Feedback Submitted": {
      "main": [
        [
          {
            "node": "Feedback Submitted HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}