diff --git a/components/elements/FormInput/index.js b/components/elements/FormInput/index.js index bff0e19..c8d19fb 100644 --- a/components/elements/FormInput/index.js +++ b/components/elements/FormInput/index.js @@ -1,5 +1,13 @@ import React from "react"; -import { Input, Checkbox, Dropdown, Button, Space, Select, message } from "antd"; +import { + Input, + Checkbox, + Dropdown, + Button, + Space, + Select, + message, +} from "antd"; import { AiOutlineDown, AiOutlinePlus, AiOutlineClose } from "react-icons/ai"; import CustomParameter from "../CustomParameterInput"; export default function FormInput({ fields, setFields, hasFileField }) { @@ -32,7 +40,10 @@ export default function FormInput({ fields, setFields, hasFileField }) { const handleMenuClick = (e) => {}; const addField = () => { if (fields.length < 10) { - setFields([...fields, { name: "", isRequired: false }]); + setFields((prev) => [ + ...prev, + { label: "", type: "text", required: false }, + ]); } else { message.error("You cannot add more than 10 fields"); } @@ -51,7 +62,9 @@ export default function FormInput({ fields, setFields, hasFileField }) { return ( <>
-
Add Fields to your Form
+
+ Add Fields to your Form +
{fields.map((field, i) => (
@@ -63,7 +76,11 @@ export default function FormInput({ fields, setFields, hasFileField }) { style={{ width: "100%" }} options={ hasFileField - ? options.filter((option) => option.label !== "file" && option.label !== "image") + ? options.filter( + (option) => + option.label !== "file" && + option.label !== "image" + ) : options } showArrow={true} @@ -109,7 +126,12 @@ export default function FormInput({ fields, setFields, hasFileField }) {
handleRemove(i)}> - +
{/*
diff --git a/components/elements/FormResponse/index.js b/components/elements/FormResponse/index.js index 04e5bfe..359eaec 100644 --- a/components/elements/FormResponse/index.js +++ b/components/elements/FormResponse/index.js @@ -1,26 +1,26 @@ -import React from 'react'; +import React from "react"; +import moment from "moment"; + export default function FormResponse({ response }) { - return ( - <> -
-
-
-
Name:
-
Manas Gupta
-
-
-
City:
-
Ludhiana
-
-
-
State:
-
Punjab
-
-
- Submittted a week ago -
-
-
- - ); + return ( + <> +
+
+ {Object.entries(response.data).map((el) => ( +
+
+ {el[0]}: +
+
+ {el[1]} +
+
+ ))} +
+ {moment(response.createdAt).fromNow()} +
+
+
+ + ); } diff --git a/components/utils/API/index.js b/components/utils/API/index.js index 1c3329f..5d1632a 100644 --- a/components/utils/API/index.js +++ b/components/utils/API/index.js @@ -66,7 +66,11 @@ const get = async (endpoint, token = null) => { const patch = async (endpoint, body, token = null) => { try { - const response = await axios.patch(API_URL + endpoint, body, getHeaders(token)); + const response = await axios.patch( + API_URL + endpoint, + body, + getHeaders(token) + ); return response.data; } catch (err) { console.error(err?.response?.data || err); diff --git a/components/utils/JSONSchema/index.js b/components/utils/JSONSchema/index.js index 6d0a7a2..45a54d5 100644 --- a/components/utils/JSONSchema/index.js +++ b/components/utils/JSONSchema/index.js @@ -1,50 +1,62 @@ const options = { - email: { type: "string", format: "email" }, - checkbox: { type: "boolean" }, - color: { - type: "string", - pattern: "^#[0-9a-f]{3}([0-9a-f]{3})?$", - }, - date: { type: "string", format: "date" }, - "datetime-local": { type: "string", format: "date-time" }, - image: { - type: "string", - format: "uri", - }, - hidden: { type: "boolean" }, - month: { type: "integer", minimum: 1, maximum: 12 }, - number: { type: "number" }, - radio: { type: "boolean" }, - range: { type: "number" }, - reset: { type: "boolean" }, - search: { type: "string" }, - tel: { - type: "string", - minLength: 10, - maxLength: 20, - pattern: "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$", - }, - text: { type: "string" }, - time: { type: "string", format: "time" }, - url: { type: "string", format: "uri" }, - week: { type: "number", minimum: 1, maximum: 53 }, - file: { type: "string", format: "uri" }, - password: { type: "string" }, + email: { type: "string", format: "email" }, + checkbox: { type: "boolean" }, + color: { + type: "string", + pattern: "^#[0-9a-f]{3}([0-9a-f]{3})?$", + }, + date: { type: "string", format: "date" }, + "datetime-local": { type: "string", format: "date-time" }, + image: { + type: "string", + format: "uri", + }, + hidden: { type: "boolean" }, + month: { type: "integer", minimum: 1, maximum: 12 }, + number: { type: "number" }, + radio: { type: "boolean" }, + range: { type: "number" }, + reset: { type: "boolean" }, + search: { type: "string" }, + tel: { + type: "string", + minLength: 10, + maxLength: 20, + pattern: "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$", + }, + text: { type: "string" }, + time: { type: "string", format: "time" }, + url: { type: "string", format: "uri" }, + week: { type: "number", minimum: 1, maximum: 53 }, + file: { type: "string" }, + password: { type: "string" }, }; -const createJSONSchema = (inputs) => { - let JSONSchema = { - type: "object", - properties: {}, - required: [], - additionalProperties: false, +export const createJSONSchema = (inputs) => { + let JSONSchema = { + type: "object", + properties: {}, + required: [], + additionalProperties: false, + }; + inputs.forEach((input) => { + JSONSchema.properties[input.name] = options[input.type]; + if (input.isRequired) { + JSONSchema.required.push(input.name); + } + }); + return JSONSchema; +}; + +export const schemaToInputsConverter = (schema) => { + const inputs = []; + for (const [key, value] of Object.entries(schema.properties)) { + const input = { + name: key, + type: value.type, + isRequired: schema.required.includes(key), }; - inputs.forEach((input) => { - JSONSchema.properties[input.name] = options[input.type]; - if (input.isRequired) { - JSONSchema.required.push(input.name); - } - }); - return JSONSchema; + inputs.push(input); + } + return inputs; }; -export default createJSONSchema; diff --git a/package-lock.json b/package-lock.json index fec433f..354e969 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -143,6 +144,7 @@ "version": "7.22.1", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.1.tgz", "integrity": "sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA==", + "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.21.4", @@ -172,6 +174,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, "bin": { "json5": "lib/cli.js" }, @@ -183,6 +186,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, "bin": { "semver": "bin/semver.js" } @@ -574,6 +578,7 @@ "version": "7.22.3", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.3.tgz", "integrity": "sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==", + "dev": true, "dependencies": { "@babel/template": "^7.21.9", "@babel/traverse": "^7.22.1", @@ -5267,7 +5272,8 @@ "node_modules/convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "node_modules/copy-anything": { "version": "3.0.3", @@ -6572,6 +6578,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "engines": { "node": ">=6.9.0" } @@ -11470,20 +11477,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -11981,6 +11974,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -12054,6 +12048,7 @@ "version": "7.22.1", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.1.tgz", "integrity": "sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA==", + "dev": true, "requires": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.21.4", @@ -12075,12 +12070,14 @@ "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -12372,6 +12369,7 @@ "version": "7.22.3", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.3.tgz", "integrity": "sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==", + "dev": true, "requires": { "@babel/template": "^7.21.9", "@babel/traverse": "^7.22.1", @@ -13319,8 +13317,7 @@ "@dicebear/avatars-avataaars-sprites": { "version": "4.10.7", "resolved": "https://registry.npmjs.org/@dicebear/avatars-avataaars-sprites/-/avatars-avataaars-sprites-4.10.7.tgz", - "integrity": "sha512-sNjy2VJUV3OHtFN/H1MeL8SN+v6xYIGoO1Zflh8O6vwoQJtNB+bg49H3olcIuRoVHKUdBmCvTS+6M6ZG+hgJBg==", - "requires": {} + "integrity": "sha512-sNjy2VJUV3OHtFN/H1MeL8SN+v6xYIGoO1Zflh8O6vwoQJtNB+bg49H3olcIuRoVHKUdBmCvTS+6M6ZG+hgJBg==" }, "@emotion/hash": { "version": "0.8.0", @@ -13474,8 +13471,7 @@ "@heroicons/react": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz", - "integrity": "sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==", - "requires": {} + "integrity": "sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==" }, "@humanwhocodes/config-array": { "version": "0.11.9", @@ -14166,8 +14162,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14355,8 +14350,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14468,8 +14462,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14520,8 +14513,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14556,8 +14548,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14603,8 +14594,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14642,8 +14632,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14725,8 +14714,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14741,8 +14729,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14774,8 +14761,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14798,8 +14784,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14845,8 +14830,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14878,16 +14862,14 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, "@react-types/shared": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.14.0.tgz", - "integrity": "sha512-K069Bh/P0qV3zUG8kqabeO8beAUlFdyVPvpcNVPjRl+0Q9NDS9mfdQbmUa0LqdVo5e6jRPdos77Ylflkrz8wcw==", - "requires": {} + "integrity": "sha512-K069Bh/P0qV3zUG8kqabeO8beAUlFdyVPvpcNVPjRl+0Q9NDS9mfdQbmUa0LqdVo5e6jRPdos77Ylflkrz8wcw==" }, "@react-types/switch": { "version": "3.2.5", @@ -14909,8 +14891,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14934,8 +14915,7 @@ "@react-types/shared": { "version": "3.16.0", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.16.0.tgz", - "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==", - "requires": {} + "integrity": "sha512-IQgU4oAEvMwylEvaTsr2XB1G/mAoMe1JFYLD6G78v++oAR9l8o9MQxZ0YSeANDkqTamb2gKezGoT1RxvSKjVxw==" } } }, @@ -14948,8 +14928,7 @@ "@stitches/react": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@stitches/react/-/react-1.2.8.tgz", - "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==", - "requires": {} + "integrity": "sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA==" }, "@swc/helpers": { "version": "0.4.14", @@ -15158,8 +15137,7 @@ "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" }, "acorn-node": { "version": "1.8.2", @@ -15694,7 +15672,8 @@ "convert-source-map": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "copy-anything": { "version": "3.0.3", @@ -16262,8 +16241,7 @@ "version": "4.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true, - "requires": {} + "dev": true }, "eslint-scope": { "version": "5.1.1", @@ -16681,7 +16659,8 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true }, "get-intrinsic": { "version": "1.1.3", @@ -18298,14 +18277,12 @@ "next-seo": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/next-seo/-/next-seo-5.15.0.tgz", - "integrity": "sha512-LGbcY91yDKGMb7YI+28n3g+RuChUkt6pXNpa8FkfKkEmNiJkeRDEXTnnjVtwT9FmMhG6NH8qwHTelGrlYm9rgg==", - "requires": {} + "integrity": "sha512-LGbcY91yDKGMb7YI+28n3g+RuChUkt6pXNpa8FkfKkEmNiJkeRDEXTnnjVtwT9FmMhG6NH8qwHTelGrlYm9rgg==" }, "next-themes": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz", - "integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==", - "requires": {} + "integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==" }, "nextjs-progressbar": { "version": "0.0.16", @@ -18771,8 +18748,7 @@ "qrcode.react": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", - "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", - "requires": {} + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==" }, "queue-microtask": { "version": "1.2.3", @@ -19223,14 +19199,12 @@ "react-icons": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.9.0.tgz", - "integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==", - "requires": {} + "integrity": "sha512-ijUnFr//ycebOqujtqtV9PFS7JjhWg0QU6ykURVHuL4cbofvRCf3f6GMn9+fBktEFQOIVZnuAYLZdiyadRQRFg==" }, "react-intersection-observer": { "version": "9.4.1", "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.1.tgz", - "integrity": "sha512-IXpIsPe6BleFOEHKzKh5UjwRUaz/JYS0lT/HPsupWEQou2hDqjhLMStc5zyE3eQVT4Fk3FufM8Fw33qW1uyeiw==", - "requires": {} + "integrity": "sha512-IXpIsPe6BleFOEHKzKh5UjwRUaz/JYS0lT/HPsupWEQou2hDqjhLMStc5zyE3eQVT4Fk3FufM8Fw33qW1uyeiw==" }, "react-is": { "version": "16.13.1", @@ -20080,13 +20054,6 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, - "typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "dev": true, - "peer": true - }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -20258,8 +20225,7 @@ "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "requires": {} + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==" }, "util-deprecate": { "version": "1.0.2", diff --git a/pages/dashboard/project/[id]/[formid]/index.js b/pages/dashboard/project/[id]/[formid]/index.js index 36c14ae..de1fa12 100644 --- a/pages/dashboard/project/[id]/[formid]/index.js +++ b/pages/dashboard/project/[id]/[formid]/index.js @@ -1,7 +1,12 @@ import React, { useState, useContext, useEffect } from "react"; import Image from "next/image"; import { useRouter } from "next/router"; -import { useQuery, dehydrate, QueryClient, useQueryClient } from "@tanstack/react-query"; +import { + useQuery, + dehydrate, + QueryClient, + useQueryClient, +} from "@tanstack/react-query"; import { BiSortAlt2 } from "react-icons/bi"; import { Modal, Button, Input, Space } from "antd"; @@ -15,21 +20,52 @@ import { MdOutlineContentCopy } from "react-icons/md"; export default function FormDashboard() { const router = useRouter(); + const limit = 10; const { formid, isNew, submissionLink } = router.query; const { setActive } = useContext(AppbarContext); let { isLoggedIn, user } = useContext(UserContext); const [form, setForm] = useState(null); - const [newFormSubmissionLinkModalOpen, setNewFormSubmissionLinkModalOpen] = useState(false); - + const [newFormSubmissionLinkModalOpen, setNewFormSubmissionLinkModalOpen] = + useState(false); + const [page, setPage] = useState(0), + [formSubmissions, setFormSubmissions] = useState(null), + [formSubmissionsCount, setFormSubmissionsCount] = useState(null); const getFormDashboard = async () => { const res = await get(`/form/dashboard/${formid}`); const data = res?.data?.data; setForm(data); }; - + const getFormResponses = async () => { + const res = await get( + `/form/submissions/${formid}?limit=${limit}&skip=${page * limit}` + ); + const data = res?.data?.data; + setFormSubmissions(data?.submissions); + setFormSubmissionsCount(data?.totalSubmissions); + }; const copySubmissionLink = () => { navigator.clipboard.writeText(submissionLink); }; + const handlePrevPage = () => { + if (page === 0) return; + setPage((prev) => prev - 1); + }; + const handleNextPage = () => { + setPage((prev) => prev + 1); + }; + const exportCSV = async () => { + const res = await get(`/form/csv/${formid}`); + console.log(res); + const data = res?.data?.data; + let encodeUri = data.encodeUri; + console.log(encodeUri); + let link = document.createElement("a"); + link.setAttribute("href", encodeUri); + link.setAttribute("download", "responses.csv"); + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + }; useEffect(() => { if (!isLoggedIn) { setActive({ @@ -50,6 +86,9 @@ export default function FormDashboard() { useEffect(() => { if (formid) getFormDashboard(); }, [formid]); + useEffect(() => { + if (formid) getFormResponses(); + }, [formid, page]); useEffect(() => { if (isNew && submissionLink) setNewFormSubmissionLinkModalOpen(true); }, [isNew, submissionLink]); @@ -74,34 +113,66 @@ export default function FormDashboard() {
-

{form?.name}

+

+ {form?.name} +

{form?.is_owner && ( - + )}
-
{form?.project?.name}
+
+ {form?.project?.name} +
- {"45"} Responses + {formSubmissionsCount}{" "} + + Responses +
- - Latest +
- - - - + {formSubmissions && + formSubmissions.map((formSubmission) => ( + + ))}
- - + +
@@ -115,7 +186,9 @@ export default function FormDashboard() { type="primary" onClick={() => { setNewFormSubmissionLinkModalOpen(false); - router.replace(router.asPath.split("?")[0], undefined, { shallow: true }); + router.replace(router.asPath.split("?")[0], undefined, { + shallow: true, + }); }} > Ok @@ -124,10 +197,15 @@ export default function FormDashboard() { >

Submission Link

- Here is your form submission link, send POST request to this link to store your form submission + Here is your form submission link, send POST request to this link to + store your form submission

- + diff --git a/pages/dashboard/project/[id]/[formid]/settings/index.js b/pages/dashboard/project/[id]/[formid]/settings/index.js index 1feb205..805778b 100644 --- a/pages/dashboard/project/[id]/[formid]/settings/index.js +++ b/pages/dashboard/project/[id]/[formid]/settings/index.js @@ -1 +1,315 @@ -export default function FormSettings() {} +import React, { useState, useRef, useContext, useEffect, useMemo } from "react"; +import Image from "next/image"; +import { Input, Checkbox, message, Modal, Button, Space } from "antd"; +import { useQuery, dehydrate, QueryClient } from "@tanstack/react-query"; + +import DashboardVector from "../../../../../../assets/svgs/dashboardsVector.svg"; +import FormInput from "../../../../../../components/elements/FormInput"; +import Footer from "../../../../../../components/elements/Footer"; +import { + createJSONSchema, + schemaToInputsConverter, +} from "../../../../../../components/utils/JSONSchema"; +import { useRouter } from "next/router"; +import { + AppbarContext, + UserContext, +} from "../../../../../../components/context"; +import { + get, + patch, + remove, + API_URL, +} from "../../../../../../components/utils/API"; +import Loader from "../../../../../../components/elements/Loader"; +import SEO from "../../../../../../components/utils/SEO"; +import { useGoogleReCaptcha } from "react-google-recaptcha-v3"; + +async function getProjectData(id) { + if (id) + return await get(`/project/dashboard/${id}`).then((data) => { + data?.data?.data?.forms?.forEach((form) => { + let iostr = form.date_created; + let iostr2 = form.last_updated; + let tempDate = new Date(iostr).toDateString().slice(4); + let tempDate2 = new Date(iostr2).toDateString().slice(4); + form.date_created = tempDate.slice(0, 6) + "," + tempDate.slice(6); + form.last_updated = tempDate2.slice(0, 6) + "," + tempDate2.slice(6); + }); + return data?.data?.data; + }); + return null; +} + +async function getFormData(id) { + if (id) + return await get(`/form/dashboard/${id}`).then((data) => { + return data?.data?.data; + }); + return null; +} + +export default function NewForm() { + const { executeRecaptcha } = useGoogleReCaptcha(); + const { setActive } = useContext(AppbarContext); + let { isLoggedIn, user } = useContext(UserContext); + + let [fields, setFields] = useState([]); + const [formName, setFormName] = useState(""); + const [hasRecaptcha, setHasRecaptcha] = useState(false); + const [password, setPassword] = useState(""); + const [enterPasswordModalOpen, setEnterPasswordModalOpen] = useState(false); + const [isDelete, setIsDelete] = useState(false); + const router = useRouter(); + const { id, formid } = router.query; + + const hasFileField = useMemo( + () => + fields.some((field) => field.type === "image" || field.type === "file"), + [fields] + ); + const handleSubmit = async (e) => { + e.preventDefault(); + try { + if (isDelete) { + const response = await remove(`/form/${formid}`, { password }); + if (response.status === "OK") { + message.success("Form deleted successfully"); + setIsDelete((prev) => !prev); + router.push(`/dashboard/project/${id}`); + } else { + message.error(response.data.error); + } + setPassword(""); + setIsDelete((prev) => false); + return; + } + if (!executeRecaptcha) return message.error("Recaptcha not loaded"); + const token = await executeRecaptcha("form"); + if (!token) return message.error("Recaptcha not verified"); + + const name = formName; + + const schema = createJSONSchema(fields); + const body = { + name, + schema, + hasRecaptcha, + password, + recaptcha_token: token, + hasFileField, + hostUrl: API_URL, + }; + const response = await patch(`/form/update/${formid}`, body); + if (response.status === "OK") { + message.success("Form updated successfully"); + router.push({ + pathname: `/dashboard/project/${id}/${response.data._doc.formId}`, + query: { + submissionLink: response.data.submissionLink, + }, + }); + } else message.error(response.data.error); + } catch (err) { + console.log(err); + message.error("Error in updating form"); + } + }; + + const handleCancel = async () => { + router.back(); + }; + + useEffect(() => { + if (!isLoggedIn) { + setActive({ + home: false, + dashboard: false, + documentation: false, + faq: false, + }); + router.push("/signin"); + } + setActive({ + home: false, + dashboard: true, + documentation: false, + faq: false, + }); + }, [user]); + + const projectQuery = useQuery({ + queryKey: ["projectData", id], + queryFn: () => { + return getProjectData(id); + }, + staleTime: 10 * 60 * 1000, + }); + const formQuery = useQuery({ + queryKey: ["formData", formid], + queryFn: () => { + return getFormData(formid); + }, + staleTime: 10 * 60 * 1000, + enabled: !!formid, + }); + + useEffect(() => { + if (formQuery?.data) { + const data = formQuery?.data; + const fields = schemaToInputsConverter(data.schema); + setFields((prev) => { + const data = JSON.parse(JSON.stringify(fields)); + return data; + }); + setFormName(data.name); + setHasRecaptcha(data.hasRecaptchaVerification); + } + }, [formQuery?.data]); + + if (projectQuery?.isLoading) return ; + + if (projectQuery?.isSuccess) + return ( + <> + +
+
+ Dashboard Vector +
+
+
+
+

+ {"New Form"} +

+
+
+
+ {projectQuery.data?.name} +
+
+
+
{ + e.preventDefault(); + setEnterPasswordModalOpen(true); + }} + > +
+
+ setFormName(e.target.value)} + required + /> +
+ +
+ setHasRecaptcha(e.target.checked)} + /> +
+ has reCAPTCHA Validation ? +
+
+
+ + + +
+
+
+
+
+