added multiple input functionality

This commit is contained in:
anikaahmed114 2024-03-30 04:07:40 -04:00
parent 3331c1943d
commit 85d99a0a96
5 changed files with 188 additions and 45 deletions

View File

@ -1,5 +1,7 @@
// pages/index.tsx
"use client";
import Image from 'next/image';
import Drawer from '@/components/page/Drawer';
@ -18,9 +20,21 @@ export default function Page() {
};
return (
<>
<h1 className="text-2xl font-bold text-gray-700 sm:text-3xl">Resources</h1>
<Drawer title="My Drawer Title" editableContent={pageContent} onSave={handleDrawerContentChange}>{pageContent}</Drawer>
</>
<div className="min-h-screen flex flex-col">
<div className="pt-16 px-8 pb-4 flex-grow">
<div className="mb-4 flex items-center space-x-4">
<Image
src="/logo.png" // Ensure the path to your logo is correct
alt="Compass Center logo"
width={25}
height={25}
// If you are using TypeScript and Next.js Image component, ensure you have set up 'next/image' in your 'next.config.js' for static import
/>
<h1 className="font-bold text-2xl text-purple-800">Untitled Page</h1>
</div>
<Drawer title="Sidebar Component" editableContent={pageContent} onSave={handleDrawerContentChange}>{pageContent}</Drawer>
</div>
</div>
);
};
};

View File

@ -0,0 +1,29 @@
import React, { ReactNode, useState } from "react";
interface TagProps {
text: string;
icon: React.ReactNode;
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
children?: React.ReactNode;
}
const Card: React.FC<TagProps> = ({children, text, icon, onClick }) => {
return (
<button
onClick={onClick}
className="flex flex-row space-x-2 items-start justify-start border border-gray-200 bg-white hover:bg-gray-50 shadow rounded-md p-4 focus:outline-none focus:ring-2 focus:ring-purple-600 focus:ring-opacity-50 w-1/4"
>
<span className="h-5 text-purple-700 w-5">
{icon}
</span>
<span className="text-sm text-gray-800 font-semibold">
{text}
</span>
{children}
</button>
);
};
export default Card;

View File

@ -1,8 +1,10 @@
import { FunctionComponent, ReactNode } from 'react';
import { FunctionComponent, ReactElement, ReactNode } from 'react';
import Button from '@/components/Button'
import React, { useState } from 'react';
import {DATATYPE} from '@/utils/constants'
import InlineLink from '@/components/InlineLink'
import { ChevronDoubleLeftIcon } from '@heroicons/react/24/solid';
import { BookmarkIcon, XMarkIcon } from "@heroicons/react/24/solid";
import Card from '@/components/page/Card'
type DrawerProps = {
@ -15,62 +17,134 @@ type DrawerProps = {
onSave?: (content: any) => void;
};
interface EditContent {
content: string;
isEditing: boolean;
}
const Drawer: FunctionComponent<DrawerProps> = ({ title, children, onSave, editableContent }) => {
const [isOpen, setIsOpen] = useState(false);
const [isEditing, setIsEditing] = useState(false);
const [editContent, setEditContent] = useState(editableContent || '');
const [editContents, setEditContents] = useState<EditContent[]>(editableContent || [{ content: '', isEditing: true }]);
const [currentCardText, setCurrentCardText] = useState("");
const [currentCardIcon, setCurrentCardIcon] = useState<string>('');
const [error, setError] = useState<string | null>(null);
const toggleDrawer = () => setIsOpen(!isOpen);
const toggleEditing = () => setIsEditing(!isEditing);
const handleContentChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setEditContent(event.target.value);
};
const handleCardClick = (text: string, icon: ReactElement) => {
console.log('click')
toggleDrawer();
setCurrentCardText(text);
setCurrentCardIcon(icon)};
const toggleEditing = () => setIsEditing(!isEditing);
const handleInputChange = (index: number) => (event: React.ChangeEvent<HTMLInputElement>) => {
const newContents = editContents.map((item, idx) => idx === index ? { ...item, content: event.target.value } : item);
setEditContents(newContents);
};
const drawerClassName = `fixed top-0 right-0 w-1/2 h-full bg-white shadow-xl transform ease-in-out duration-300 ${
isOpen ? "translate-x-0" : "translate-x-full"
}`;
const addInput = () => {
setEditContents([...editContents, { content: '', isEditing: true }]);
};
const saveChanges = () => {
console.log(editContent);
if (onSave) {
onSave(editContent);
const saveIndividualChange = (index: number) => {
const content = editContents[index].content.trim();
if (!content) {
setError("Input cannot be empty.");
return;
}
setIsEditing(false);
setError(null); // Clear error state if input passes validation
const updatedContents = editContents.map((item, idx) => idx === index ? { ...item, isEditing: false } : item);
setEditContents(updatedContents);
if (onSave) {
onSave(updatedContents);
}
};
const toggleEdit = (index: number) => {
const newContents = editContents.map((item, idx) => idx === index ? { ...item, isEditing: !item.isEditing } : item);
setEditContents(newContents);
};
const deleteInput = (index: number) => {
// Filter out the input at the given index
const filteredContents = editContents.filter((_, idx) => idx !== index);
setEditContents(filteredContents);
};
const addRow = () => {
}
return (
<div>
<Button onClick={toggleDrawer}>{isOpen ? "Close" : "Open"} Drawer</Button>
<Card icon={<BookmarkIcon />} text="Resources" onClick={() => handleCardClick("Resources", <BookmarkIcon />)}/>
<div className={drawerClassName}>
<div className="flex items-center justify-between p-4 border-b">
<h2>{title}</h2>
<div className="flex items-center justify-between p-4 border-b">
<span className="h-5 text-purple-700 w-5">
{currentCardIcon}
</span>
<h2>{currentCardText}</h2>
<div>
<Button onClick={toggleEditing}>{isEditing ? 'Cancel' : 'Edit'}</Button>
<Button onClick={toggleDrawer}>&laquo;</Button>
<button
onClick={toggleDrawer} className="py-2 text-gray-500 hover:text-gray-800"
>
<ChevronDoubleLeftIcon className="h-5 w-5" />
</button>
</div>
</div>
<div className="p-4">
{isEditing ? (
<>
<input
type= 'text'
value={editContent}
onChange={handleContentChange}
className="border p-2 w-full"
/>
<InlineLink onClick={saveChanges}>Save</InlineLink>
</>
) : (
children
)}
</div>
{
editContents.map((item, index) => (
<div key={index} className="flex mb-2 items-center space-x-2">
{item.isEditing ? (
<>
<input
type="text"
value={item.content}
onChange={handleInputChange(index)}
className="border p-2 w-full"
/>
<button
onClick={() => saveIndividualChange(index)}
className="py-2 px-4 bg-blue-500 text-white rounded"
>
Save
</button>
</>
) : (
<>
<span className="p-2 w-full">{item.content}</span>
<button
onClick={() => toggleEdit(index)}
className="py-2 px-4 bg-green-500 text-white rounded"
>
Edit
</button>
</>
)}
{/* Delete button moved here, outside of the editing conditional */}
<button
onClick={() => deleteInput(index)}
className="py-2 text-gray-500 hover:text-gray-800"
>
<XMarkIcon className="h-5 w-5" />
</button>
</div>
))
}
<button onClick={addInput} className="py-2 px-4 bg-blue-500 text-white rounded my-2">Add New Input</button>
</div>
</div>
</div>
);
};
export default Drawer;
export default Drawer;

View File

@ -0,0 +1,30 @@
import React, { ChangeEvent, FunctionComponent } from 'react';
// Define the shape of a single option
interface DropdownOption {
label: string;
value: string | number;
}
// Define the props for the Dropdown component
interface DropdownProps {
options: DropdownOption[];
onChange: (event: ChangeEvent<HTMLSelectElement>) => void; // Type for change event on <select>
defaultValue?: string | number;
id?: string;
}
// Dropdown Component
const Dropdown: FunctionComponent<DropdownProps> = ({ options, onChange, defaultValue, id }) => {
return (
<select id={id} defaultValue={defaultValue} onChange={onChange} className="form-select form-select-lg mb-3">
{options.map((option, index) => (
<option key={index} value={option.value}>
{option.label}
</option>
))}
</select>
);
};
export default Dropdown;

View File

@ -1,4 +0,0 @@
// components/Field.tsx
import { FunctionComponent, ReactNode } from 'react';
import Button from '@/components/Button'
import React, { useState } from 'react';