Skip to content

Commit

Permalink
risk matrix ui configured
Browse files Browse the repository at this point in the history
  • Loading branch information
Prasanth-S7 committed Dec 9, 2024
1 parent 28bc3e9 commit 3192785
Show file tree
Hide file tree
Showing 15 changed files with 624 additions and 173 deletions.
298 changes: 295 additions & 3 deletions admin/package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"@stepperize/react": "^3.1.1",
"@tanstack/react-table": "^8.20.5",
"@types/axios": "^0.14.4",
"@types/qrcode": "^1.5.5",
"@types/qrcode.react": "^1.0.5",
"axios": "^1.7.8",
"chrono-node": "^2.7.7",
"class-variance-authority": "^0.7.0",
Expand All @@ -51,6 +53,8 @@
"mapbox-gl": "^3.8.0",
"motion": "^11.13.1",
"ol": "^10.2.1",
"qrcode": "^1.5.4",
"qrcode.react": "^4.1.0",
"radix-ui": "^1.0.1",
"react": "^18.3.1",
"react-chrono": "^2.6.1",
Expand Down
12 changes: 7 additions & 5 deletions admin/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ import RiskMatrix from './pages/RiskMatrixs'
import { ShiftTemplateCard } from './components/custom/shiftTemplateCard'
import { ShiftTemplates } from './pages/ShiftTemplates'
import CreateShiftTemplate from './pages/CreateShiftTemplate'
import YellowBook from './pages/YellowBook'
import FormPage from './pages/FormPage'
import { OperatorResponseForm } from './components/operatorResponseForm'

interface ErrorPageProps {
error: Error & { digest?: string }
Expand Down Expand Up @@ -210,10 +211,11 @@ function App() {
path: '/risk-matrix',
element: <RiskMatrix />
},
{
path: '/yellow-book',
element: <YellowBook />
}
// {
// path: '/form/:uniqueKey',
// element: <OperatorResponseForm />
// },

]
},
{
Expand Down
110 changes: 69 additions & 41 deletions admin/src/components/custom/dynamicFormGenerator.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, { useState } from 'react';
import QRCode from 'qrcode';
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Calendar } from "@/components/ui/calendar";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { CalendarIcon } from "lucide-react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { CalendarIcon, QrCode } from "lucide-react";
import { format } from "date-fns";
import { cn } from "@/lib/utils";

Expand Down Expand Up @@ -34,15 +36,17 @@ type FormStructure = {
sections: FormSection[];
};

export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ formData }) => {
export default function DynamicFormGenerator({ formData, qrCodeUrl }) {
console.log(formData);
// State to manage form values
const [formValues, setFormValues] = useState<{ [key: string]: any }>({});
const [qrCodeImage, setQrCodeImage] = useState<string | null>(null);

// Generic change handler for inputs
const handleChange = (name: string, value: any) => {
setFormValues(prev => ({
setFormValues((prev) => ({
...prev,
[name]: value
[name]: value,
}));
};

Expand All @@ -58,7 +62,7 @@ export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ fo
required={field.required}
/>
);

case 'Textarea':
return (
<Textarea
Expand All @@ -68,7 +72,7 @@ export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ fo
required={field.required}
/>
);

case 'Number':
return (
<Input
Expand All @@ -79,10 +83,10 @@ export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ fo
required={field.required}
/>
);

case 'Select':
return (
<Select
<Select
onValueChange={(value) => handleChange(field.name, value)}
value={formValues[field.name] || undefined}
>
Expand All @@ -98,27 +102,7 @@ export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ fo
</SelectContent>
</Select>
);

case 'Multi Select':
// Note: This would typically require a multi-select component
return (
<Select
onValueChange={(value) => handleChange(field.name, value)}
value={formValues[field.name] || undefined}
>
<SelectTrigger>
<SelectValue placeholder={field.placeholder} />
</SelectTrigger>
<SelectContent>
{field.options?.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
);


case 'Date Picker':
return (
<Popover>
Expand All @@ -131,10 +115,9 @@ export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ fo
)}
>
<CalendarIcon className="mr-2 h-4 w-4" />
{formValues[field.name]
{formValues[field.name]
? format(formValues[field.name], "PPP")
: <span>{field.placeholder}</span>
}
: <span>{field.placeholder}</span>}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0">
Expand All @@ -147,26 +130,71 @@ export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ fo
</PopoverContent>
</Popover>
);

default:
return <Input placeholder={field.placeholder} />;
}
};

// Generate QR Code
const generateQRCode = async () => {
const shareableLink = `http://localhost:5173/form/${qrCodeUrl}`;
try {
const qrCode = await QRCode.toDataURL(shareableLink);
setQrCodeImage(qrCode);
} catch (err) {
console.error("Failed to generate QR code:", err);
}
};

// Submit handler
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
console.log('Form Submitted', formValues);
// Add your submission logic here
};

return (
<div className="max-w-4xl mx-auto p-6 shadow-md rounded-lg">
<h1 className="text-2xl font-bold mb-4">{formData.form_name}</h1>
<p className="text-muted-foreground mb-6">{formData.form_description}</p>

<div className="flex justify-between items-center mb-4">
<div>
<h1 className="text-2xl font-bold">{formData.form_name}</h1>
<p className="text-muted-foreground">{formData.form_description}</p>
</div>
<Dialog>
<DialogTrigger asChild>
<Button variant="outline" onClick={generateQRCode}>
<QrCode className="mr-2 h-4 w-4" /> Generate Share Link
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Shareable Form Link</DialogTitle>
</DialogHeader>
<div className="flex flex-col items-center space-y-4">
{qrCodeImage && (
<>
<img src={qrCodeImage} alt="QR Code" className="w-64 h-64" />
<div className="flex items-center space-x-2">
<Input
value={`http://localhost:5173/form/${qrCodeUrl}`}
readOnly
className="w-full"
/>
<Button
variant="outline"
onClick={() => navigator.clipboard.writeText(qrCodeImage)}
>
Copy
</Button>
</div>
</>
)}
</div>
</DialogContent>
</Dialog>
</div>

<form onSubmit={handleSubmit} className="space-y-6">
{formData.sections.map((section, sectionIndex) => (
{formData?.sections?.map((section, sectionIndex) => (
<div key={sectionIndex} className="border-b pb-6">
<h2 className="text-xl font-semibold mb-4">{section.section_name}</h2>
{section.section_description && (
Expand All @@ -188,9 +216,9 @@ export const DynamicFormGenerator: React.FC<{ formData: FormStructure }> = ({ fo
</div>
</div>
))}

<Button type="submit" className="w-full">Submit Form</Button>
</form>
</div>
);
};
}
Empty file.
24 changes: 22 additions & 2 deletions admin/src/pages/CreateShiftTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { Sparkles } from "lucide-react"
import { formData } from "./YellowBook"
import { dummyAiResponse } from "@/lib/dummyAiResponse"
import { DynamicFormBuilder } from "@/components/forms/dynamic-form-builder"
import { DynamicFormGenerator } from "@/components/custom/dynamicFormGenerator"
import DynamicFormGenerator from "@/components/custom/dynamicFormGenerator"

type FieldType = 'text' | 'number' | 'select' | 'checkbox' | 'textarea' | 'date'

Expand Down Expand Up @@ -198,6 +198,26 @@ export default function FormTemplateBuilder() {
async function onAIGenerate(){
const queryString = `Make me a shift log template for ${selectedRole} that will help me to fill ${selectedForm}, ${userQuery}`
console.log("reaches")
//make the api call here
//generate a unique string here to set as a key to the response
//the dummy ai response is something like this now


// export const dummyAiResponse = {
// form_name: "Coal Mine Blasting Operation Record",
// form_description:
// "Comprehensive documentation of coal mine blasting operations, adhering to Indian mining safety standards.",
// sections: [
// {
// section_name: "General Information",
// section_description: "Basic details about the blasting operation.",
// fields: [
// {
// label: "Mine Name",
// name: "mine_name",
// set this key in the qr code route params /form/:uniquekey
// when some one hits this route it should fetch the unique and search it in the database and get the formdata and render the form on the screen
//when he fills this form and submit it store the formData along with response in a state
setAiResponse(dummyAiResponse)
}

Expand Down Expand Up @@ -334,7 +354,7 @@ export default function FormTemplateBuilder() {
</div>
</div>

{aiResponse!= null ?sections.map((section) => (
{aiResponse=== null ?sections.map((section) => (
<Card key={section.id} className="border">
<div className="bg-blue-600 text-white p-4 rounded-t-lg flex items-center justify-between">
<div className="flex items-center gap-2">
Expand Down
61 changes: 61 additions & 0 deletions admin/src/pages/FormPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import DynamicFormGenerator from '@/components/custom/dynamicFormGenerator';

// Example database or state to store forms (replace this with your API/database)
const mockFormDatabase: { [key: string]: any } = {
"coal-mine-blasting-operation-record": {
form_name: "Example Form",
form_description: "This is a dynamically generated form.",
sections: [
{
section_name: "Personal Information",
fields: [
{
label: "Name",
name: "name",
type: "Text",
placeholder: "Enter your name",
required: true,
},
{
label: "Email",
name: "email",
type: "Text",
placeholder: "Enter your email",
required: true,
},
],
},
],
},
};

function FormPage() {
const { uniqueKey } = useParams(); // Get the uniqueKey from the URL
const [formData, setFormData] = useState(null);

useEffect(() => {
// Fetch the form data using the uniqueKey from the URL
// the url is like this http://localhost:5173/form/067c1614-4e87-4839-8012-4ef292ca9296
// but the unique key is null

console.log(uniqueKey)
const fetchedData = localStorage.getItem(uniqueKey?.toString());
console.log(fetchedData)

if (fetchedData) {
setFormData(JSON.parse(fetchedData)); // Load the form data from localStorage (or your database)
}
}, [uniqueKey]);

if (!formData) return <p>Loading form...</p>;

return (
<div>
<DynamicFormGenerator formData={formData} />
</div>
);
}

export default FormPage;
Loading

0 comments on commit 3192785

Please sign in to comment.