mirror of
https://github.com/cssgunc/compass.git
synced 2025-04-10 06:10:17 -04:00
added multiple input functionality
This commit is contained in:
parent
3331c1943d
commit
85d99a0a96
|
@ -1,5 +1,7 @@
|
||||||
// pages/index.tsx
|
// pages/index.tsx
|
||||||
"use client";
|
"use client";
|
||||||
|
import Image from 'next/image';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import Drawer from '@/components/page/Drawer';
|
import Drawer from '@/components/page/Drawer';
|
||||||
|
@ -18,9 +20,21 @@ export default function Page() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="min-h-screen flex flex-col">
|
||||||
<h1 className="text-2xl font-bold text-gray-700 sm:text-3xl">Resources</h1>
|
<div className="pt-16 px-8 pb-4 flex-grow">
|
||||||
<Drawer title="My Drawer Title" editableContent={pageContent} onSave={handleDrawerContentChange}>{pageContent}</Drawer>
|
<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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
29
compass/components/page/Card.tsx
Normal file
29
compass/components/page/Card.tsx
Normal 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;
|
|
@ -1,8 +1,10 @@
|
||||||
import { FunctionComponent, ReactNode } from 'react';
|
import { FunctionComponent, ReactElement, ReactNode } from 'react';
|
||||||
import Button from '@/components/Button'
|
import Button from '@/components/Button'
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import {DATATYPE} from '@/utils/constants'
|
import { ChevronDoubleLeftIcon } from '@heroicons/react/24/solid';
|
||||||
import InlineLink from '@/components/InlineLink'
|
import { BookmarkIcon, XMarkIcon } from "@heroicons/react/24/solid";
|
||||||
|
import Card from '@/components/page/Card'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type DrawerProps = {
|
type DrawerProps = {
|
||||||
|
@ -15,62 +17,134 @@ type DrawerProps = {
|
||||||
onSave?: (content: any) => void;
|
onSave?: (content: any) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
interface EditContent {
|
||||||
|
content: string;
|
||||||
|
isEditing: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const Drawer: FunctionComponent<DrawerProps> = ({ title, children, onSave, editableContent }) => {
|
const Drawer: FunctionComponent<DrawerProps> = ({ title, children, onSave, editableContent }) => {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isEditing, setIsEditing] = 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 toggleDrawer = () => setIsOpen(!isOpen);
|
||||||
const toggleEditing = () => setIsEditing(!isEditing);
|
|
||||||
const handleContentChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleCardClick = (text: string, icon: ReactElement) => {
|
||||||
setEditContent(event.target.value);
|
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 ${
|
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"
|
isOpen ? "translate-x-0" : "translate-x-full"
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
|
const addInput = () => {
|
||||||
|
setEditContents([...editContents, { content: '', isEditing: true }]);
|
||||||
|
};
|
||||||
|
|
||||||
const saveChanges = () => {
|
const saveIndividualChange = (index: number) => {
|
||||||
console.log(editContent);
|
const content = editContents[index].content.trim();
|
||||||
if (onSave) {
|
if (!content) {
|
||||||
onSave(editContent);
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Button onClick={toggleDrawer}>{isOpen ? "Close" : "Open"} Drawer</Button>
|
<Card icon={<BookmarkIcon />} text="Resources" onClick={() => handleCardClick("Resources", <BookmarkIcon />)}/>
|
||||||
<div className={drawerClassName}>
|
<div className={drawerClassName}>
|
||||||
<div className="flex items-center justify-between p-4 border-b">
|
<div className="flex items-center justify-between p-4 border-b">
|
||||||
<h2>{title}</h2>
|
<span className="h-5 text-purple-700 w-5">
|
||||||
|
{currentCardIcon}
|
||||||
|
</span>
|
||||||
|
<h2>{currentCardText}</h2>
|
||||||
<div>
|
<div>
|
||||||
<Button onClick={toggleEditing}>{isEditing ? 'Cancel' : 'Edit'}</Button>
|
<button
|
||||||
<Button onClick={toggleDrawer}>«</Button>
|
onClick={toggleDrawer} className="py-2 text-gray-500 hover:text-gray-800"
|
||||||
|
>
|
||||||
|
<ChevronDoubleLeftIcon className="h-5 w-5" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
{isEditing ? (
|
{
|
||||||
<>
|
editContents.map((item, index) => (
|
||||||
<input
|
<div key={index} className="flex mb-2 items-center space-x-2">
|
||||||
type= 'text'
|
{item.isEditing ? (
|
||||||
value={editContent}
|
<>
|
||||||
onChange={handleContentChange}
|
<input
|
||||||
className="border p-2 w-full"
|
type="text"
|
||||||
/>
|
value={item.content}
|
||||||
<InlineLink onClick={saveChanges}>Save</InlineLink>
|
onChange={handleInputChange(index)}
|
||||||
</>
|
className="border p-2 w-full"
|
||||||
) : (
|
/>
|
||||||
children
|
<button
|
||||||
)}
|
onClick={() => saveIndividualChange(index)}
|
||||||
</div>
|
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>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Drawer;
|
export default Drawer;
|
||||||
|
|
||||||
|
|
30
compass/components/page/DropDown.tsx
Normal file
30
compass/components/page/DropDown.tsx
Normal 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;
|
|
@ -1,4 +0,0 @@
|
||||||
// components/Field.tsx
|
|
||||||
import { FunctionComponent, ReactNode } from 'react';
|
|
||||||
import Button from '@/components/Button'
|
|
||||||
import React, { useState } from 'react';
|
|
Loading…
Reference in New Issue
Block a user