diff --git a/GeradoresWS/Dockerfile b/GeradoresWS/Dockerfile index ddaaf9a..9183c54 100644 --- a/GeradoresWS/Dockerfile +++ b/GeradoresWS/Dockerfile @@ -6,7 +6,6 @@ EXPOSE 8080 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build - WORKDIR /src COPY ["GeradoresWS/GeradoresWS.csproj", "GeradoresWS/"] diff --git a/docker-compose.yml b/docker-compose.yml index 751c394..81b693b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,14 +1,22 @@ version: "3.8" services: geradoresws: - build: . + build: + context: . # Caminho para a pasta do Dockerfile do backend + dockerfile: Dockerfile + image: docker.io/shini89/geradoresws:latest ports: - "5050:8080" networks: - app-network + environment: + - ASPNETCORE_ENVIRONMENT=Production # Variavel de ambiente para o backend geradoresfe: - build: ./geradoresfe + build: + context: ./geradoresfe # Caminho para a pasta do Dockerfile do frontend + dockerfile: Dockerfile + image: docker.io/shini89/geradoresfe:latest ports: - "3000:3000" depends_on: @@ -21,4 +29,4 @@ services: networks: app-network: - driver: bridge \ No newline at end of file + driver: bridge diff --git a/geradoresfe/.env b/geradoresfe/.env index 0fcaa18..dd278cd 100644 --- a/geradoresfe/.env +++ b/geradoresfe/.env @@ -1 +1 @@ -REACT_APP_API_URL=http://localhost:5015/ \ No newline at end of file +REACT_APP_API_URL=https://localhost:44329/ \ No newline at end of file diff --git a/geradoresfe/.gitignore b/geradoresfe/.gitignore index 4d29575..18c0012 100644 --- a/geradoresfe/.gitignore +++ b/geradoresfe/.gitignore @@ -21,3 +21,8 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +.vercel + +package-lock.json +yarn-lock.json +pnpm-lock.json diff --git a/geradoresfe/.vscode/iisexpress.json b/geradoresfe/.vscode/iisexpress.json new file mode 100644 index 0000000..b67a3bd --- /dev/null +++ b/geradoresfe/.vscode/iisexpress.json @@ -0,0 +1,6 @@ +{ + "port": 26415, + "path": "./", + "clr": "v4.0", + "protocol": "http" +} diff --git a/geradoresfe/package.json b/geradoresfe/package.json index 6910eb4..4a26a76 100644 --- a/geradoresfe/package.json +++ b/geradoresfe/package.json @@ -1,26 +1,45 @@ { - "name": "geradoresfe", - "version": "0.1.0", - "private": true, + "name": "tailadmin-react-free", + "version": "2.0.0", "dependencies": { - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.5", - "@headlessui/react": "^2.2.0", - "@heroicons/react": "^2.1.5", - "@mui/icons-material": "^5.15.15", - "@mui/material": "^5.15.15", + "@fullcalendar/core": "^6.1.15", + "@fullcalendar/daygrid": "^6.1.15", + "@fullcalendar/interaction": "^6.1.15", + "@fullcalendar/list": "^6.1.15", + "@fullcalendar/react": "^6.1.15", + "@fullcalendar/timegrid": "^6.1.15", + "@react-jvectormap/core": "^1.0.4", + "@react-jvectormap/world": "^1.1.2", + "@tailwindcss/forms": "^0.5.9", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.5.2", - "@types/node": "^16.18.95", - "@types/react": "^18.2.74", - "@types/react-dom": "^18.2.24", - "axios": "^1.6.8", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "@types/node": "^16.18.119", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "apexcharts": "^4.1.0", + "autoprefixer": "^10.4.20", + "classnames": "^2.5.1", + "clsx": "^2.1.1", + "flatpickr": "^4.6.13", + "lucide-react": "^0.477.0", + "motion": "^12.4.10", + "postcss": "^8.4.49", + "react": "^18.3.1", + "react-apexcharts": "^1.6.0", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", + "react-dom": "^18.3.1", + "react-dropzone": "^14.3.5", + "react-flatpickr": "^3.10.13", "react-helmet": "^6.1.0", + "react-helmet-async": "^2.0.5", + "react-router": "^7.0.1", "react-scripts": "5.0.1", + "react-simple-maps": "^3.0.0", + "swiper": "^11.1.15", + "tailwind-merge": "^2.6.0", "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, @@ -49,10 +68,7 @@ ] }, "devDependencies": { - "@types/react-helmet": "^6.1.11", - "eslint": "^8.57.0", - "eslint-config-react-app": "^7.0.1", - "jest-editor-support": "^31.1.2", - "tailwindcss": "^3.4.13" + "@types/react-flatpickr": "^3.8.11", + "tailwindcss": "^3.4.15" } } diff --git a/geradoresfe/public/favicon.ico b/geradoresfe/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/geradoresfe/public/favicon.ico and /dev/null differ diff --git a/geradoresfe/public/index.html b/geradoresfe/public/index.html index aa069f2..7d64e7e 100644 --- a/geradoresfe/public/index.html +++ b/geradoresfe/public/index.html @@ -2,9 +2,8 @@ - + - - React App - +
*/} +
+
+ +
+ +
+
+ + Customers + +

+ 3,782 +

+
+ + + 11.01% + +
+
+ {/* */} + + {/* */} +
+
+ +
+
+
+ + Orders + +

+ 5,359 +

+
+ + + + 9.05% + +
+
+ {/* */} + + ); +} diff --git a/geradoresfe/src/components/ecommerce/MonthlySalesChart.tsx b/geradoresfe/src/components/ecommerce/MonthlySalesChart.tsx new file mode 100644 index 0000000..b8b442e --- /dev/null +++ b/geradoresfe/src/components/ecommerce/MonthlySalesChart.tsx @@ -0,0 +1,142 @@ +import Chart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { MoreDotIcon } from "../../icons"; +import { Dropdown } from "../ui/dropdown/Dropdown"; +import { DropdownItem } from "../ui/dropdown/DropdownItem"; +import { useState } from "react"; + +export default function MonthlySalesChart() { + const options: ApexOptions = { + colors: ["#465fff"], + chart: { + fontFamily: "Outfit, sans-serif", + type: "bar", + height: 180, + toolbar: { + show: false, + }, + }, + plotOptions: { + bar: { + horizontal: false, + columnWidth: "39%", + borderRadius: 5, + borderRadiusApplication: "end", + }, + }, + dataLabels: { + enabled: false, + }, + stroke: { + show: true, + width: 4, + colors: ["transparent"], + }, + xaxis: { + categories: [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + ], + axisBorder: { + show: false, + }, + axisTicks: { + show: false, + }, + }, + legend: { + show: true, + position: "top", + horizontalAlign: "left", + fontFamily: "Outfit", + }, + yaxis: { + title: { + text: undefined, + }, + }, + grid: { + yaxis: { + lines: { + show: true, + }, + }, + }, + fill: { + opacity: 1, + }, + + tooltip: { + x: { + show: false, + }, + y: { + formatter: (val: number) => `${val}`, + }, + }, + }; + const series = [ + { + name: "Sales", + data: [168, 385, 201, 298, 187, 195, 291, 110, 215, 390, 280, 112], + }, + ]; + const [isOpen, setIsOpen] = useState(false); + + function toggleDropdown() { + setIsOpen(!isOpen); + } + + function closeDropdown() { + setIsOpen(false); + } + + return ( +
+
+

+ Monthly Sales +

+
+ + + + View More + + + Delete + + +
+
+ +
+
+ +
+
+
+ ); +} diff --git a/geradoresfe/src/components/ecommerce/MonthlyTarget.tsx b/geradoresfe/src/components/ecommerce/MonthlyTarget.tsx new file mode 100644 index 0000000..6f544bb --- /dev/null +++ b/geradoresfe/src/components/ecommerce/MonthlyTarget.tsx @@ -0,0 +1,198 @@ +import Chart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import { useState } from "react"; +import { MoreDotIcon } from "../../icons"; +import { Dropdown } from "../ui/dropdown/Dropdown"; +import { DropdownItem } from "../ui/dropdown/DropdownItem"; + +export default function MonthlyTarget() { + const series = [75.55]; + const options: ApexOptions = { + colors: ["#465FFF"], + chart: { + fontFamily: "Outfit, sans-serif", + type: "radialBar", + height: 330, + sparkline: { + enabled: true, + }, + }, + plotOptions: { + radialBar: { + startAngle: -85, + endAngle: 85, + hollow: { + size: "80%", + }, + track: { + background: "#E4E7EC", + strokeWidth: "100%", + margin: 5, // margin is in pixels + }, + dataLabels: { + name: { + show: false, + }, + value: { + fontSize: "36px", + fontWeight: "600", + offsetY: -40, + color: "#1D2939", + formatter: function (val) { + return val + "%"; + }, + }, + }, + }, + }, + fill: { + type: "solid", + colors: ["#465FFF"], + }, + stroke: { + lineCap: "round", + }, + labels: ["Progress"], + }; + const [isOpen, setIsOpen] = useState(false); + + function toggleDropdown() { + setIsOpen(!isOpen); + } + + function closeDropdown() { + setIsOpen(false); + } + return ( +
+
+
+
+

+ Monthly Target +

+

+ Target you’ve set for each month +

+
+
+ + + + View More + + + Delete + + +
+
+
+
+ +
+ + + +10% + +
+

+ You earn $3287 today, it's higher than last month. Keep up your good + work! +

+
+ +
+
+

+ Target +

+

+ $20K + + + +

+
+ +
+ +
+

+ Revenue +

+

+ $20K + + + +

+
+ +
+ +
+

+ Today +

+

+ $20K + + + +

+
+
+
+ ); +} diff --git a/geradoresfe/src/components/ecommerce/RecentOrders.tsx b/geradoresfe/src/components/ecommerce/RecentOrders.tsx new file mode 100644 index 0000000..903d8f5 --- /dev/null +++ b/geradoresfe/src/components/ecommerce/RecentOrders.tsx @@ -0,0 +1,208 @@ +import { + Table, + TableBody, + TableCell, + TableHeader, + TableRow, +} from "../ui/table"; +import Badge from "../ui/badge/Badge"; + +// Define the TypeScript interface for the table rows +interface Product { + id: number; // Unique identifier for each product + name: string; // Product name + variants: string; // Number of variants (e.g., "1 Variant", "2 Variants") + category: string; // Category of the product + price: string; // Price of the product (as a string with currency symbol) + // status: string; // Status of the product + image: string; // URL or path to the product image + status: "Delivered" | "Pending" | "Canceled"; // Status of the product +} + +// Define the table data using the interface +const tableData: Product[] = [ + { + id: 1, + name: "MacBook Pro 13â€", + variants: "2 Variants", + category: "Laptop", + price: "$2399.00", + status: "Delivered", + image: "/images/product/product-01.jpg", // Replace with actual image URL + }, + { + id: 2, + name: "Apple Watch Ultra", + variants: "1 Variant", + category: "Watch", + price: "$879.00", + status: "Pending", + image: "/images/product/product-02.jpg", // Replace with actual image URL + }, + { + id: 3, + name: "iPhone 15 Pro Max", + variants: "2 Variants", + category: "SmartPhone", + price: "$1869.00", + status: "Delivered", + image: "/images/product/product-03.jpg", // Replace with actual image URL + }, + { + id: 4, + name: "iPad Pro 3rd Gen", + variants: "2 Variants", + category: "Electronics", + price: "$1699.00", + status: "Canceled", + image: "/images/product/product-04.jpg", // Replace with actual image URL + }, + { + id: 5, + name: "AirPods Pro 2nd Gen", + variants: "1 Variant", + category: "Accessories", + price: "$240.00", + status: "Delivered", + image: "/images/product/product-05.jpg", // Replace with actual image URL + }, +]; + +export default function RecentOrders() { + return ( +
+
+
+

+ Recent Orders +

+
+ +
+ + +
+
+
+ + {/* Table Header */} + + + + Products + + + Category + + + Price + + + Status + + + + + {/* Table Body */} + + + {tableData.map((product) => ( + + +
+
+ {product.name} +
+
+

+ {product.name} +

+ + {product.variants} + +
+
+
+ + {product.price} + + + {product.category} + + + + {product.status} + + +
+ ))} +
+
+
+
+ ); +} diff --git a/geradoresfe/src/components/ecommerce/StatisticsChart.tsx b/geradoresfe/src/components/ecommerce/StatisticsChart.tsx new file mode 100644 index 0000000..8376e61 --- /dev/null +++ b/geradoresfe/src/components/ecommerce/StatisticsChart.tsx @@ -0,0 +1,138 @@ +import React from "react"; +import Chart from "react-apexcharts"; +import { ApexOptions } from "apexcharts"; +import ChartTab from "../common/ChartTab"; + +export default function StatisticsChart() { + const options: ApexOptions = { + legend: { + show: false, // Hide legend + position: "top", + horizontalAlign: "left", + }, + colors: ["#465FFF", "#9CB9FF"], // Define line colors + chart: { + fontFamily: "Outfit, sans-serif", + height: 310, + type: "line", // Set the chart type to 'line' + toolbar: { + show: false, // Hide chart toolbar + }, + }, + stroke: { + curve: "straight", // Define the line style (straight, smooth, or step) + width: [2, 2], // Line width for each dataset + }, + + fill: { + type: "gradient", + gradient: { + opacityFrom: 0.55, + opacityTo: 0, + }, + }, + markers: { + size: 0, // Size of the marker points + strokeColors: "#fff", // Marker border color + strokeWidth: 2, + hover: { + size: 6, // Marker size on hover + }, + }, + grid: { + xaxis: { + lines: { + show: false, // Hide grid lines on x-axis + }, + }, + yaxis: { + lines: { + show: true, // Show grid lines on y-axis + }, + }, + }, + dataLabels: { + enabled: false, // Disable data labels + }, + tooltip: { + enabled: true, // Enable tooltip + x: { + format: "dd MMM yyyy", // Format for x-axis tooltip + }, + }, + xaxis: { + type: "category", // Category-based x-axis + categories: [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + ], + axisBorder: { + show: false, // Hide x-axis border + }, + axisTicks: { + show: false, // Hide x-axis ticks + }, + tooltip: { + enabled: false, // Disable tooltip for x-axis points + }, + }, + yaxis: { + labels: { + style: { + fontSize: "12px", // Adjust font size for y-axis labels + colors: ["#6B7280"], // Color of the labels + }, + }, + title: { + text: "", // Remove y-axis title + style: { + fontSize: "0px", + }, + }, + }, + }; + + const series = [ + { + name: "Sales", + data: [180, 190, 170, 160, 175, 165, 170, 205, 230, 210, 240, 235], + }, + { + name: "Revenue", + data: [40, 30, 50, 40, 55, 40, 70, 100, 110, 120, 150, 140], + }, + ]; + return ( +
+
+
+

+ Statistics +

+

+ Target you’ve set for each month +

+
+
+ +
+
+ +
+
+ +
+
+
+ ); +} diff --git a/geradoresfe/src/components/form/Form.tsx b/geradoresfe/src/components/form/Form.tsx new file mode 100644 index 0000000..0530a6a --- /dev/null +++ b/geradoresfe/src/components/form/Form.tsx @@ -0,0 +1,23 @@ +import React, { FC, ReactNode, FormEvent } from "react"; + +interface FormProps { + onSubmit: (event: FormEvent) => void; + children: ReactNode; + className?: string; +} + +const Form: FC = ({ onSubmit, children, className }) => { + return ( +
{ + event.preventDefault(); // Prevent default form submission + onSubmit(event); + }} + className={` ${className}`} // Default spacing between form fields + > + {children} +
+ ); +}; + +export default Form; diff --git a/geradoresfe/src/components/form/Label.tsx b/geradoresfe/src/components/form/Label.tsx new file mode 100644 index 0000000..8b0628b --- /dev/null +++ b/geradoresfe/src/components/form/Label.tsx @@ -0,0 +1,27 @@ +import React, { FC, ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +interface LabelProps { + htmlFor?: string; + children: ReactNode; + className?: string; +} + +const Label: FC = ({ htmlFor, children, className }) => { + return ( + + ); +}; + +export default Label; diff --git a/geradoresfe/src/components/form/MultiSelect.tsx b/geradoresfe/src/components/form/MultiSelect.tsx new file mode 100644 index 0000000..d25f7d1 --- /dev/null +++ b/geradoresfe/src/components/form/MultiSelect.tsx @@ -0,0 +1,166 @@ +import React, { useState } from "react"; + +interface Option { + value: string; + text: string; + selected: boolean; +} + +interface MultiSelectProps { + label: string; + options: Option[]; + defaultSelected?: string[]; + onChange?: (selected: string[]) => void; + disabled?: boolean; +} + +const MultiSelect: React.FC = ({ + label, + options, + defaultSelected = [], + onChange, + disabled = false, +}) => { + const [selectedOptions, setSelectedOptions] = + useState(defaultSelected); + const [isOpen, setIsOpen] = useState(false); + + const toggleDropdown = () => { + if (disabled) return; + setIsOpen((prev) => !prev); + }; + + const handleSelect = (optionValue: string) => { + const newSelectedOptions = selectedOptions.includes(optionValue) + ? selectedOptions.filter((value) => value !== optionValue) + : [...selectedOptions, optionValue]; + + setSelectedOptions(newSelectedOptions); + if (onChange) onChange(newSelectedOptions); + }; + + const removeOption = (index: number, value: string) => { + const newSelectedOptions = selectedOptions.filter((opt) => opt !== value); + setSelectedOptions(newSelectedOptions); + if (onChange) onChange(newSelectedOptions); + }; + + const selectedValuesText = selectedOptions.map( + (value) => options.find((option) => option.value === value)?.text || "" + ); + + return ( +
+ + +
+
+
+
+
+ {selectedValuesText.length > 0 ? ( + selectedValuesText.map((text, index) => ( +
+ {text} +
+
+ removeOption(index, selectedOptions[index]) + } + className="pl-2 text-gray-500 cursor-pointer group-hover:text-gray-400 dark:text-gray-400" + > + + + +
+
+
+ )) + ) : ( + + )} +
+
+ +
+
+
+ + {isOpen && ( +
e.stopPropagation()} + > +
+ {options.map((option, index) => ( +
+
handleSelect(option.value)} + > +
+
+ {option.text} +
+
+
+
+ ))} +
+
+ )} +
+
+
+ ); +}; + +export default MultiSelect; diff --git a/geradoresfe/src/components/form/Select.tsx b/geradoresfe/src/components/form/Select.tsx new file mode 100644 index 0000000..e2f3c6a --- /dev/null +++ b/geradoresfe/src/components/form/Select.tsx @@ -0,0 +1,64 @@ +import React, { useState } from "react"; + +interface Option { + value: string; + label: string; +} + +interface SelectProps { + options: Option[]; + placeholder?: string; + onChange: (value: string) => void; + className?: string; + defaultValue?: string; +} + +const Select: React.FC = ({ + options, + placeholder = "Select an option", + onChange, + className = "", + defaultValue = "", +}) => { + // Manage the selected value + const [selectedValue, setSelectedValue] = useState(defaultValue); + + const handleChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setSelectedValue(value); + onChange(value); // Trigger parent handler + }; + + return ( + + ); +}; + +export default Select; diff --git a/geradoresfe/src/components/form/form-elements/CheckboxComponents.tsx b/geradoresfe/src/components/form/form-elements/CheckboxComponents.tsx new file mode 100644 index 0000000..213416e --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/CheckboxComponents.tsx @@ -0,0 +1,36 @@ +import React, { useState } from "react"; +import ComponentCard from "../../common/ComponentCard"; +import Checkbox from "../input/Checkbox"; + +export default function CheckboxComponents() { + const [isChecked, setIsChecked] = useState(false); + const [isCheckedTwo, setIsCheckedTwo] = useState(true); + const [isCheckedDisabled, setIsCheckedDisabled] = useState(true); + return ( + +
+
+ + + Default + +
+
+ +
+
+ +
+
+
+ ); +} diff --git a/geradoresfe/src/components/form/form-elements/DefaultInputs.tsx b/geradoresfe/src/components/form/form-elements/DefaultInputs.tsx new file mode 100644 index 0000000..504325c --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/DefaultInputs.tsx @@ -0,0 +1,114 @@ +import React, { useState } from "react"; +import ComponentCard from "../../common/ComponentCard"; +import Label from "../Label"; +import Input from "../input/InputField"; +import Select from "../Select"; +import { CalenderIcon, EyeCloseIcon, EyeIcon, TimeIcon } from "../../../icons"; + +export default function DefaultInputs() { + const [showPassword, setShowPassword] = useState(false); + const options = [ + { value: "marketing", label: "Marketing" }, + { value: "template", label: "Template" }, + { value: "development", label: "Development" }, + ]; + const handleSelectChange = (value: string) => { + console.log("Selected value:", value); + }; + return ( + +
+
+ + +
+
+ + +
+
+ + + +
+
+
+ +
+ console.log(e.target.value)} + /> + + + +
+
+
+ +
+ console.log(e.target.value)} + /> + + + +
+
+
+ +
+ + + + + + + + +
+
+ +
+ ); +} diff --git a/geradoresfe/src/components/form/form-elements/DropZone.tsx b/geradoresfe/src/components/form/form-elements/DropZone.tsx new file mode 100644 index 0000000..064e7f5 --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/DropZone.tsx @@ -0,0 +1,77 @@ +import React from "react"; +import ComponentCard from "../../common/ComponentCard"; +import { useDropzone } from "react-dropzone"; +// import Dropzone from "react-dropzone"; + +const DropzoneComponent: React.FC = () => { + const onDrop = (acceptedFiles: File[]) => { + console.log("Files dropped:", acceptedFiles); + // Handle file uploads here + }; + + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + onDrop, + accept: { + "image/png": [], + "image/jpeg": [], + "image/webp": [], + "image/svg+xml": [], + }, + }); + return ( + +
+
+ {/* Hidden Input */} + + +
+ {/* Icon Container */} +
+
+ + + +
+
+ + {/* Text Content */} +

+ {isDragActive ? "Drop Files Here" : "Drag & Drop Files Here"} +

+ + + Drag and drop your PNG, JPG, WebP, SVG images here or browse + + + + Browse File + +
+
+
+
+ ); +}; + +export default DropzoneComponent; diff --git a/geradoresfe/src/components/form/form-elements/FileInputExample.tsx b/geradoresfe/src/components/form/form-elements/FileInputExample.tsx new file mode 100644 index 0000000..e2a977a --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/FileInputExample.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import ComponentCard from "../../common/ComponentCard"; +import FileInput from "../input/FileInput"; +import Label from "../Label"; + +export default function FileInputExample() { + const handleFileChange = (event: React.ChangeEvent) => { + const file = event.target.files?.[0]; + if (file) { + console.log("Selected file:", file.name); + } + }; + + return ( + +
+ + +
+
+ ); +} diff --git a/geradoresfe/src/components/form/form-elements/InputGroup.tsx b/geradoresfe/src/components/form/form-elements/InputGroup.tsx new file mode 100644 index 0000000..2e7208e --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/InputGroup.tsx @@ -0,0 +1,55 @@ +import React from "react"; +import ComponentCard from "../../common/ComponentCard"; +import Label from "../Label"; +import Input from "../input/InputField"; +import { EnvelopeIcon } from "../../../icons"; +import PhoneInput from "../group-input/PhoneInput"; + +export default function InputGroup() { + const countries = [ + { code: "US", label: "+1" }, + { code: "GB", label: "+44" }, + { code: "CA", label: "+1" }, + { code: "AU", label: "+61" }, + ]; + const handlePhoneNumberChange = (phoneNumber: string) => { + console.log("Updated phone number:", phoneNumber); + }; + return ( + +
+
+ +
+ + + + +
+
+
+ + +
{" "} +
+ + +
+
+
+ ); +} diff --git a/geradoresfe/src/components/form/form-elements/InputStates.tsx b/geradoresfe/src/components/form/form-elements/InputStates.tsx new file mode 100644 index 0000000..6d93d62 --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/InputStates.tsx @@ -0,0 +1,69 @@ +import React, { useState } from "react"; +import ComponentCard from "../../common/ComponentCard"; +import Input from "../input/InputField"; +import Label from "../Label"; + +export default function InputStates() { + const [email, setEmail] = useState(""); + const [error, setError] = useState(false); + + // Simulate a validation check + const validateEmail = (value: string) => { + const isValidEmail = + /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value); + setError(!isValidEmail); + return isValidEmail; + }; + + const handleEmailChange = (e: React.ChangeEvent) => { + const value = e.target.value; + setEmail(value); + validateEmail(value); + }; + return ( + +
+ {/* Error Input */} +
+ + +
+ + {/* Success Input */} +
+ + +
+ + {/* Disabled Input */} +
+ + +
+
+
+ ); +} diff --git a/geradoresfe/src/components/form/form-elements/RadioButtons.tsx b/geradoresfe/src/components/form/form-elements/RadioButtons.tsx new file mode 100644 index 0000000..0ad1c21 --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/RadioButtons.tsx @@ -0,0 +1,42 @@ +import React, { useState } from "react"; +import ComponentCard from "../../common/ComponentCard"; +import Radio from "../input/Radio"; + +export default function RadioButtons() { + const [selectedValue, setSelectedValue] = useState("option2"); + + const handleRadioChange = (value: string) => { + setSelectedValue(value); + }; + return ( + +
+ + + +
+
+ ); +} diff --git a/geradoresfe/src/components/form/form-elements/SelectInputs.tsx b/geradoresfe/src/components/form/form-elements/SelectInputs.tsx new file mode 100644 index 0000000..95989ed --- /dev/null +++ b/geradoresfe/src/components/form/form-elements/SelectInputs.tsx @@ -0,0 +1,52 @@ +import React, { useState } from "react"; +import ComponentCard from "../../common/ComponentCard"; +import Label from "../Label"; +import Select from "../Select"; +import MultiSelect from "../MultiSelect"; + +export default function SelectInputs() { + const options = [ + { value: "marketing", label: "Marketing" }, + { value: "template", label: "Template" }, + { value: "development", label: "Development" }, + ]; + const handleSelectChange = (value: string) => { + console.log("Selected value:", value); + }; + const [selectedValues, setSelectedValues] = useState([]); + + const multiOptions = [ + { value: "1", text: "Option 1", selected: false }, + { value: "2", text: "Option 2", selected: false }, + { value: "3", text: "Option 3", selected: false }, + { value: "4", text: "Option 4", selected: false }, + { value: "5", text: "Option 5", selected: false }, + ]; + return ( + +
+
+ +