From f5c247668a6671f5a1d47af0b44dfc3030813a38 Mon Sep 17 00:00:00 2001 From: Vignesh Mohankumar Date: Mon, 15 Jan 2024 14:41:12 -0500 Subject: [PATCH] secure input --- .../src/content/03-10-secure-input.tsx | 44 ++++++++++++ .../src/custom-components/SecureInput.css | 66 +++++++++++++++++ .../src/custom-components/SecureInput.tsx | 72 +++++++++++++++++++ .../src/custom-components/checkmark.svg | 7 ++ packages/website/src/routes.tsx | 6 ++ 5 files changed, 195 insertions(+) create mode 100644 packages/website/src/content/03-10-secure-input.tsx create mode 100644 packages/website/src/custom-components/SecureInput.css create mode 100644 packages/website/src/custom-components/SecureInput.tsx create mode 100644 packages/website/src/custom-components/checkmark.svg diff --git a/packages/website/src/content/03-10-secure-input.tsx b/packages/website/src/content/03-10-secure-input.tsx new file mode 100644 index 00000000..3a0ecc49 --- /dev/null +++ b/packages/website/src/content/03-10-secure-input.tsx @@ -0,0 +1,44 @@ +import React, { useState } from "react"; +import { PageTitle } from "../components/PageTitle"; +import { PageContent } from "../components/PageContent"; +import { InlineWidget, Item } from "../components/InlineWidget"; +import { disclaimerSnippet } from "../snippets"; +import SecureInput from "../custom-components/SecureInput"; + +export const content = ` +This component allows you to create a secure input field. The input field is rendered in an iframe, and the inputted data is sent to the bot via a secure channel. This means that the inputted data is not accessible to the website owner. + +~~~js +${disclaimerSnippet} +~~~ +`; + +export const WebWidgetComponentsSecureInput = () => { + const [submitted, setSubmitted] = useState(false); + + const items: Item[][] = [ + [ + { + type: "custom", + element: , + }, + ], + ]; + + if (submitted) { + items.push([ + { + type: "bot", + message: `Thank you! You're now logged in.`, + }, + ]); + } + + return ( + <> + + + + + ); +}; diff --git a/packages/website/src/custom-components/SecureInput.css b/packages/website/src/custom-components/SecureInput.css new file mode 100644 index 00000000..3206a24b --- /dev/null +++ b/packages/website/src/custom-components/SecureInput.css @@ -0,0 +1,66 @@ +.form-container, +.success-container { + height: 168px; + padding: 20px; + background: #efefef; +} + +.form-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.form-container form { + margin: 0; +} + +.form-container form > input { + margin-bottom: 10px; +} + +.success-container { + display: flex; + align-items: center; + justify-content: center; +} + +.checkmark-icon { + height: 50px; + width: auto; +} + +.checkmark-icon path { + fill: green; +} + +input { + width: 100%; + padding: 5px 10px; + border: 1px solid #ccc; + border-radius: 4px; +} + +.form-container [type="submit"] { + display: block; + width: 100%; + background-color: rgba(38, 99, 218, 1); + padding: 8px 12px; + border-radius: 6px; + border: none; + color: #fff; + font-size: 0.75rem; + text-transform: uppercase; + font-weight: 600; + cursor: pointer; + letter-spacing: 0.05rem; +} + +.form-container [type="submit"]:hover { + background-color: rgba(30, 86, 196, 1); +} + +.form-container [type="submit"]:disabled { + background-color: #cccccc; +} diff --git a/packages/website/src/custom-components/SecureInput.tsx b/packages/website/src/custom-components/SecureInput.tsx new file mode 100644 index 00000000..22e3dd37 --- /dev/null +++ b/packages/website/src/custom-components/SecureInput.tsx @@ -0,0 +1,72 @@ +import React, { useState, ChangeEvent, FormEvent } from "react"; +import "./SecureInput.css"; +import checkmarkIcon from "./checkmark.svg"; + +const SecureInput: React.FC = () => { + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const [isSuccess, setIsSuccess] = useState(false); + + const handleEmailChange = (event: ChangeEvent) => { + setEmail(event.target.value); + }; + + const handlePasswordChange = (event: ChangeEvent) => { + setPassword(event.target.value); + }; + + const handleSubmit = async (event: FormEvent) => { + event.preventDefault(); + setIsLoading(true); + + try { + await new Promise((resolve) => setTimeout(resolve, 2000)); + setIsSuccess(true); + } catch (error) { + console.error("Error:", error); + } + + setIsLoading(false); + }; + + if (isSuccess) { + return ( +
+ checkmark +
+ ); + } + + return ( +
+
+ + + +
+
+ ); +}; + +export default SecureInput; diff --git a/packages/website/src/custom-components/checkmark.svg b/packages/website/src/custom-components/checkmark.svg new file mode 100644 index 00000000..a1464d14 --- /dev/null +++ b/packages/website/src/custom-components/checkmark.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/packages/website/src/routes.tsx b/packages/website/src/routes.tsx index cf99e915..6334594a 100644 --- a/packages/website/src/routes.tsx +++ b/packages/website/src/routes.tsx @@ -29,6 +29,7 @@ import { HeadlessApi } from "./content/05-02-headless-api"; import { MultimodalSetup } from "./content/06-01-multimodal-setup"; import { MultimodalApiReference } from "./content/06-02-multimodal-api-reference"; import { MultimodalTryLive } from "./content/06-03-multimodal-try-live"; +import { WebWidgetComponentsSecureInput } from "./content/03-10-secure-input"; export const routes: { heading: string; @@ -108,6 +109,11 @@ export const routes: { url: "/widget-components/file-upload", element: , }, + { + label: "Secure input", + url: "/widget-components/secure-input", + element: , + }, ], }, {