fix: Remove demo pages and add testDataService for production build

This commit is contained in:
dahoud
2025-10-02 00:10:01 +00:00
parent b430bf3b96
commit 5bdd4b6e4f
11 changed files with 137 additions and 1877 deletions

View File

@@ -1,839 +0,0 @@
'use client';
import { Button } from 'primereact/button';
import { Checkbox } from 'primereact/checkbox';
import { Chip } from 'primereact/chip';
import { InputText } from 'primereact/inputtext';
import React, { useState } from 'react';
import BlockViewer from '../../../demo/components/BlockViewer';
const BlocksDemo = () => {
const [checked, setChecked] = useState(false);
const block1 = `
<div className="grid grid-nogutter surface-section text-800">
<div className="col-12 md:col-6 p-6 text-center md:text-left flex align-items-center ">
<section>
<span className="block text-6xl font-bold mb-1">Create the screens</span>
<div className="text-6xl text-primary font-bold mb-3">your visitors deserve to see</div>
<p className="mt-0 mb-4 text-700 line-height-3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<Button label="Learn More" type="button" className="mr-3" raised />
<Button label="Live Demo" type="button" outlined />
</section>
</div>
<div className="col-12 md:col-6 overflow-hidden">
<img src="assets/images/blocks/hero/hero-1.png" alt="hero-1" className="md:ml-auto block md:h-full" style={{ clipPath: 'polygon(8% 0, 100% 0%, 100% 100%, 0 100%)' }} />
</div>
</div>
`;
const block2 = `
<div className="surface-section px-4 py-8 md:px-6 lg:px-8 text-center">
<div className="mb-3 font-bold text-3xl">
<span className="text-900">One Product, </span>
<span className="text-blue-600">Many Solutions</span>
</div>
<div className="text-700 mb-6">Ac turpis egestas maecenas pharetra convallis posuere morbi leo urna.</div>
<div className="grid">
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-desktop text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Built for Developers</div>
<span className="text-700 line-height-3">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-lock text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">End-to-End Encryption</div>
<span className="text-700 line-height-3">Risus nec feugiat in fermentum posuere urna nec. Posuere sollicitudin aliquam ultrices sagittis.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-check-circle text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Easy to Use</div>
<span className="text-700 line-height-3">Ornare suspendisse sed nisi lacus sed viverra tellus. Neque volutpat ac tincidunt vitae semper.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-globe text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Fast & Global Support</div>
<span className="text-700 line-height-3">Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum tellus.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-github text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Open Source</div>
<span className="text-700 line-height-3">Nec tincidunt praesent semper feugiat. Sed adipiscing diam donec adipiscing tristique risus nec feugiat. </span>
</div>
<div className="col-12 md:col-4 md:mb-4 mb-0 px-3">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-shield text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Trusted Securitty</div>
<span className="text-700 line-height-3">Mattis rhoncus urna neque viverra justo nec ultrices. Id cursus metus aliquam eleifend.</span>
</div>
</div>
</div>
`;
const block3 = `<div className="surface-ground px-4 py-8 md:px-6 lg:px-8">
<div className="text-900 font-bold text-6xl mb-4 text-center">Pricing Plans</div>
<div className="text-700 text-xl mb-6 text-center line-height-3">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.</div>
<div className="grid">
<div className="col-12 lg:col-4">
<div className="p-3 h-full">
<div className="shadow-2 p-3 h-full flex flex-column surface-card" style="border-radius: "6px"">
<div className="text-900 font-medium text-xl mb-2">Basic</div>
<div className="text-600">Plan description</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<div className="flex align-items-center">
<span className="font-bold text-2xl text-900">$9</span>
<span className="ml-2 font-medium text-600">per month</span>
</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<ul className="list-none p-0 m-0 flex-grow-1">
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Arcu vitae elementum</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Dui faucibus in ornare</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Morbi tincidunt augue</span>
</li>
</ul>
<hr className="mb-3 mx-0 border-top-1 border-none surface-border mt-auto" />
<Button label="Buy Now" className="p-3 w-full mt-auto"></Button>
</div>
</div>
</div>
<div className="col-12 lg:col-4">
<div className="p-3 h-full">
<div className="shadow-2 p-3 h-full flex flex-column surface-card" style="border-radius: 6px">
<div className="text-900 font-medium text-xl mb-2">Premium</div>
<div className="text-600">Plan description</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<div className="flex align-items-center">
<span className="font-bold text-2xl text-900">$29</span>
<span className="ml-2 font-medium text-600">per month</span>
</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<ul className="list-none p-0 m-0 flex-grow-1">
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Arcu vitae elementum</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Dui faucibus in ornare</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Morbi tincidunt augue</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Duis ultricies lacus sed</span>
</li>
</ul>
<hr className="mb-3 mx-0 border-top-1 border-none surface-border" />
<Button label="Buy Now" className="p-3 w-full"></Button>
</div>
</div>
</div>
<div className="col-12 lg:col-4">
<div className="p-3 h-full">
<div className="shadow-2 p-3 flex flex-column surface-card" style="border-radius: 6px">
<div className="text-900 font-medium text-xl mb-2">Enterprise</div>
<div className="text-600">Plan description</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<div className="flex align-items-center">
<span className="font-bold text-2xl text-900">$49</span>
<span className="ml-2 font-medium text-600">per month</span>
</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<ul className="list-none p-0 m-0 flex-grow-1">
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Arcu vitae elementum</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Dui faucibus in ornare</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Morbi tincidunt augue</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Duis ultricies lacus sed</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Imperdiet proin</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Nisi scelerisque</span>
</li>
</ul>
<hr className="mb-3 mx-0 border-top-1 border-none surface-border" />
<Button label="Buy Now" className="p-3 w-full" outlined></Button>
</div>
</div>
</div>
</div>
</div>`;
const block4 = `
<div className="surface-section text-700 text-center">
<div className="text-blue-600 font-bold mb-3"><i className="pi pi-discord"></i>&nbsp;POWERED BY DISCORD</div>
<div className="text-900 font-bold text-5xl mb-3">Join Our Design Community</div>
<div className="text-700 text-2xl mb-5">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.</div>
<Button label="Join Now" icon="pi pi-discord" className="font-bold px-5 py-3 white-space-nowrap" rounded raised />
</div>
`;
const block5 = `
<div className="bg-bluegray-900 text-gray-100 p-3 flex justify-content-between lg:justify-content-center align-items-center flex-wrap">
<div className="font-bold mr-8">🔥 Hot Deals!</div>
<div className="align-items-center hidden lg:flex">
<span className="line-height-3">Libero voluptatum atque exercitationem praesentium provident odit.</span>
</div>
<a className="flex align-items-center ml-2 mr-8">
<span className="underline font-bold">Learn More</span>
</a>
<a className="flex align-items-center no-underline justify-content-center border-circle text-100 hover:bg-bluegray-700 cursor-pointer transition-colors transition-duration-150" style={{ width: '2rem', height: '2rem' }}>
<i className="pi pi-times"></i>
</a>
</div>
`;
const block6 = `
<div className="surface-section">
<ul className="list-none p-0 m-0 flex align-items-center font-medium mb-3">
<li>
<a className="text-500 no-underline line-height-3 cursor-pointer">Application</a>
</li>
<li className="px-2">
<i className="pi pi-angle-right text-500 line-height-3"></i>
</li>
<li>
<span className="text-900 line-height-3">Analytics</span>
</li>
</ul>
<div className="flex align-items-start flex-column lg:justify-content-between lg:flex-row">
<div>
<div className="font-medium text-3xl text-900">Customers</div>
<div className="flex align-items-center text-700 flex-wrap">
<div className="mr-5 flex align-items-center mt-3">
<i className="pi pi-users mr-2"></i>
<span>332 Active Users</span>
</div>
<div className="mr-5 flex align-items-center mt-3">
<i className="pi pi-globe mr-2"></i>
<span>9402 Sessions</span>
</div>
<div className="flex align-items-center mt-3">
<i className="pi pi-clock mr-2"></i>
<span>2.32m Avg. Duration</span>
</div>
</div>
</div>
<div className="mt-3 lg:mt-0">
<Button label="Add" className="mr-2" icon="pi pi-user-plus" outlined />
<Button label="Save" icon="pi pi-check" />
</div>
</div>
</div>
`;
const block7 = `
<div className="grid">
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-section shadow-2 p-3 border-1 border-50 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Orders</span>
<div className="text-900 font-medium text-xl">152</div>
</div>
<div className="flex align-items-center justify-content-center bg-blue-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-shopping-cart text-blue-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">24 new </span>
<span className="text-500">since last visit</span>
</div>
</div>
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-section shadow-2 p-3 border-1 border-50 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Revenue</span>
<div className="text-900 font-medium text-xl">$2.100</div>
</div>
<div className="flex align-items-center justify-content-center bg-orange-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-map-marker text-orange-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">%52+ </span>
<span className="text-500">since last week</span>
</div>
</div>
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-section shadow-2 p-3 border-1 border-50 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Customers</span>
<div className="text-900 font-medium text-xl">28441</div>
</div>
<div className="flex align-items-center justify-content-center bg-cyan-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-inbox text-cyan-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">520 </span>
<span className="text-500">newly registered</span>
</div>
</div>
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-section shadow-2 p-3 border-1 border-50 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Comments</span>
<div className="text-900 font-medium text-xl">152 Unread</div>
</div>
<div className="flex align-items-center justify-content-center bg-purple-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-comment text-purple-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">85 </span>
<span className="text-500">responded</span>
</div>
</div>
</div>
`;
const block8 = `
<div className="flex align-items-center justify-content-center">
<div className="surface-card p-4 shadow-2 border-round w-full lg:w-6">
<div className="text-center mb-5">
<img src="assets/images/blocks/logos/hyper.svg" alt="hyper" height={50} className="mb-3" />
<div className="text-900 text-3xl font-medium mb-3">Welcome Back</div>
<span className="text-600 font-medium line-height-3">Do not have an account?</span>
<a className="font-medium no-underline ml-2 text-blue-500 cursor-pointer">Create today!</a>
</div>
<div>
<label htmlFor="email" className="block text-900 font-medium mb-2">Email</label>
<InputText id="email" type="text" placeholder="Email address" className="w-full mb-3" />
<label htmlFor="password" className="block text-900 font-medium mb-2">Password</label>
<InputText id="password" type="password" placeholder="Password" className="w-full mb-3" />
<div className="flex align-items-center justify-content-between mb-6">
<div className="flex align-items-center">
<Checkbox id="rememberme" onChange={e => setChecked(e.checked)} checked={checked} className="mr-2" />
<label htmlFor="rememberme" className="text-900">Remember me</label>
</div>
<a className="font-medium no-underline ml-2 text-blue-500 text-right cursor-pointer">Forgot your password?</a>
</div>
<Button label="Sign In" icon="pi pi-user" className="w-full" />
</div>
</div>
</div>
`;
const block9 = `
<div className="surface-section">
<div className="font-medium text-3xl text-900 mb-3">Movie Information</div>
<div className="text-500 mb-5">Morbi tristique blandit turpis. In viverra ligula id nulla hendrerit rutrum.</div>
<ul className="list-none p-0 m-0">
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Title</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">Heat</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Genre</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">
<Chip label="Crime" className="mr-2" />
<Chip label="Drama" className="mr-2" />
<Chip label="Thriller" />
</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Director</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">Michael Mann</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Actors</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">Robert De Niro, Al Pacino</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-bottom-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Plot</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1 line-height-3">
A group of professional bank robbers start to feel the heat from police
when they unknowingly leave a clue at their latest heist.</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
</ul>
</div>
`;
const block10 = `
<div className="surface-card p-4 shadow-2 border-round">
<div className="text-3xl font-medium text-900 mb-3">Card Title</div>
<div className="font-medium text-500 mb-3">Vivamus id nisl interdum, blandit augue sit amet, eleifend mi.</div>
<div style={{ height: '150px' }} className="border-2 border-dashed surface-border"></div>
</div>
`;
return (
<>
<BlockViewer header="Hero" code={block1} free>
<div className="grid grid-nogutter surface-section text-800">
<div className="col-12 md:col-6 p-6 text-center md:text-left flex align-items-center ">
<section>
<span className="block text-6xl font-bold mb-1">Create the screens</span>
<div className="text-6xl text-primary font-bold mb-3">your visitors deserve to see</div>
<p className="mt-0 mb-4 text-700 line-height-3">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<Button label="Learn More" type="button" className="mr-3" raised />
<Button label="Live Demo" type="button" outlined />
</section>
</div>
<div className="col-12 md:col-6 overflow-hidden">
<img src="/demo/images/blocks/hero/hero-1.png" alt="hero-1" className="md:ml-auto block md:h-full" style={{ clipPath: 'polygon(8% 0, 100% 0%, 100% 100%, 0 100%)' }} />
</div>
</div>
</BlockViewer>
<BlockViewer header="Feature" code={block2} free>
<div className="surface-section px-4 py-8 md:px-6 lg:px-8 text-center">
<div className="mb-3 font-bold text-3xl">
<span className="text-900">One Product, </span>
<span className="text-blue-600">Many Solutions</span>
</div>
<div className="text-700 mb-6">Ac turpis egestas maecenas pharetra convallis posuere morbi leo urna.</div>
<div className="grid">
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-desktop text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Built for Developers</div>
<span className="text-700 line-height-3">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-lock text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">End-to-End Encryption</div>
<span className="text-700 line-height-3">Risus nec feugiat in fermentum posuere urna nec. Posuere sollicitudin aliquam ultrices sagittis.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-check-circle text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Easy to Use</div>
<span className="text-700 line-height-3">Ornare suspendisse sed nisi lacus sed viverra tellus. Neque volutpat ac tincidunt vitae semper.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-globe text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Fast & Global Support</div>
<span className="text-700 line-height-3">Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum tellus.</span>
</div>
<div className="col-12 md:col-4 mb-4 px-5">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-github text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Open Source</div>
<span className="text-700 line-height-3">Nec tincidunt praesent semper feugiat. Sed adipiscing diam donec adipiscing tristique risus nec feugiat. </span>
</div>
<div className="col-12 md:col-4 md:mb-4 mb-0 px-3">
<span className="p-3 shadow-2 mb-3 inline-block surface-card" style={{ borderRadius: '10px' }}>
<i className="pi pi-shield text-4xl text-blue-500"></i>
</span>
<div className="text-900 text-xl mb-3 font-medium">Trusted Securitty</div>
<span className="text-700 line-height-3">Mattis rhoncus urna neque viverra justo nec ultrices. Id cursus metus aliquam eleifend.</span>
</div>
</div>
</div>
</BlockViewer>
<BlockViewer header="Pricing" code={block3} free>
<div className="surface-ground px-4 py-8 md:px-6 lg:px-8">
<div className="text-900 font-bold text-6xl mb-4 text-center">Pricing Plans</div>
<div className="text-700 text-xl mb-6 text-center line-height-3">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.</div>
<div className="grid">
<div className="col-12 lg:col-4">
<div className="p-3 h-full">
<div className="shadow-2 p-3 h-full flex flex-column surface-card" style={{ borderRadius: '6px' }}>
<div className="text-900 font-medium text-xl mb-2">Basic</div>
<div className="text-600">Plan description</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<div className="flex align-items-center">
<span className="font-bold text-2xl text-900">$9</span>
<span className="ml-2 font-medium text-600">per month</span>
</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<ul className="list-none p-0 m-0 flex-grow-1">
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Arcu vitae elementum</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Dui faucibus in ornare</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Morbi tincidunt augue</span>
</li>
</ul>
<hr className="mb-3 mx-0 border-top-1 border-none surface-border mt-auto" />
<Button label="Buy Now" className="p-3 w-full mt-auto"></Button>
</div>
</div>
</div>
<div className="col-12 lg:col-4">
<div className="p-3 h-full">
<div className="shadow-2 p-3 h-full flex flex-column surface-card" style={{ borderRadius: '6px' }}>
<div className="text-900 font-medium text-xl mb-2">Premium</div>
<div className="text-600">Plan description</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<div className="flex align-items-center">
<span className="font-bold text-2xl text-900">$29</span>
<span className="ml-2 font-medium text-600">per month</span>
</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<ul className="list-none p-0 m-0 flex-grow-1">
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Arcu vitae elementum</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Dui faucibus in ornare</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Morbi tincidunt augue</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Duis ultricies lacus sed</span>
</li>
</ul>
<hr className="mb-3 mx-0 border-top-1 border-none surface-border" />
<Button label="Buy Now" className="p-3 w-full"></Button>
</div>
</div>
</div>
<div className="col-12 lg:col-4">
<div className="p-3 h-full">
<div className="shadow-2 p-3 flex flex-column surface-card" style={{ borderRadius: '6px' }}>
<div className="text-900 font-medium text-xl mb-2">Enterprise</div>
<div className="text-600">Plan description</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<div className="flex align-items-center">
<span className="font-bold text-2xl text-900">$49</span>
<span className="ml-2 font-medium text-600">per month</span>
</div>
<hr className="my-3 mx-0 border-top-1 border-none surface-border" />
<ul className="list-none p-0 m-0 flex-grow-1">
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Arcu vitae elementum</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Dui faucibus in ornare</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Morbi tincidunt augue</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Duis ultricies lacus sed</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Imperdiet proin</span>
</li>
<li className="flex align-items-center mb-3">
<i className="pi pi-check-circle text-green-500 mr-2"></i>
<span>Nisi scelerisque</span>
</li>
</ul>
<hr className="mb-3 mx-0 border-top-1 border-none surface-border" />
<Button label="Buy Now" className="p-3 w-full" outlined></Button>
</div>
</div>
</div>
</div>
</div>
</BlockViewer>
<BlockViewer header="Call to Action" code={block4} containerClassName="surface-section px-4 py-8 md:px-6 lg:px-8" free>
<div className="surface-section text-700 text-center">
<div className="text-blue-600 font-bold mb-3">
<i className="pi pi-discord"></i>&nbsp;POWERED BY DISCORD
</div>
<div className="text-900 font-bold text-5xl mb-3">Join Our Design Community</div>
<div className="text-700 text-2xl mb-5">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Velit numquam eligendi quos.</div>
<Button label="Join Now" icon="pi pi-discord" className="font-bold px-5 py-3 white-space-nowrap" raised rounded />
</div>
</BlockViewer>
<BlockViewer header="Banner" code={block5} containerClassName="surface-section py-8" free>
<div className="bg-bluegray-900 text-gray-100 p-3 flex justify-content-between lg:justify-content-center align-items-center flex-wrap">
<div className="font-bold mr-8">🔥 Hot Deals!</div>
<div className="align-items-center hidden lg:flex">
<span className="line-height-3">Libero voluptatum atque exercitationem praesentium provident odit.</span>
</div>
<a className="flex align-items-center ml-2 mr-8">
<span className="underline font-bold">Learn More</span>
</a>
<a className="flex align-items-center no-underline justify-content-center border-circle text-100 hover:bg-bluegray-700 cursor-pointer transition-colors transition-duration-150" style={{ width: '2rem', height: '2rem' }}>
<i className="pi pi-times"></i>
</a>
</div>
</BlockViewer>
<div className="block-category-title">Application UI</div>
<BlockViewer header="Page Heading" code={block6} containerClassName="surface-section px-4 py-5 md:px-6 lg:px-8" free>
<div className="surface-section">
<ul className="list-none p-0 m-0 flex align-items-center font-medium mb-3">
<li>
<a className="text-500 no-underline line-height-3 cursor-pointer">Application</a>
</li>
<li className="px-2">
<i className="pi pi-angle-right text-500 line-height-3"></i>
</li>
<li>
<span className="text-900 line-height-3">Analytics</span>
</li>
</ul>
<div className="flex align-items-start flex-column lg:justify-content-between lg:flex-row">
<div>
<div className="font-medium text-3xl text-900">Customers</div>
<div className="flex align-items-center text-700 flex-wrap">
<div className="mr-5 flex align-items-center mt-3">
<i className="pi pi-users mr-2"></i>
<span>332 Active Users</span>
</div>
<div className="mr-5 flex align-items-center mt-3">
<i className="pi pi-globe mr-2"></i>
<span>9402 Sessions</span>
</div>
<div className="flex align-items-center mt-3">
<i className="pi pi-clock mr-2"></i>
<span>2.32m Avg. Duration</span>
</div>
</div>
</div>
<div className="mt-3 lg:mt-0">
<Button label="Add" className="mr-2" outlined icon="pi pi-user-plus" />
<Button label="Save" icon="pi pi-check" />
</div>
</div>
</div>
</BlockViewer>
<BlockViewer header="Stats" code={block7} free>
<div className="surface-ground px-4 py-5 md:px-6 lg:px-8">
<div className="grid">
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-card shadow-2 p-3 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Orders</span>
<div className="text-900 font-medium text-xl">152</div>
</div>
<div className="flex align-items-center justify-content-center bg-blue-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-shopping-cart text-blue-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">24 new </span>
<span className="text-500">since last visit</span>
</div>
</div>
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-card shadow-2 p-3 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Revenue</span>
<div className="text-900 font-medium text-xl">$2.100</div>
</div>
<div className="flex align-items-center justify-content-center bg-orange-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-map-marker text-orange-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">%52+ </span>
<span className="text-500">since last week</span>
</div>
</div>
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-card shadow-2 p-3 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Customers</span>
<div className="text-900 font-medium text-xl">28441</div>
</div>
<div className="flex align-items-center justify-content-center bg-cyan-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-inbox text-cyan-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">520 </span>
<span className="text-500">newly registered</span>
</div>
</div>
<div className="col-12 md:col-6 lg:col-3">
<div className="surface-card shadow-2 p-3 border-round">
<div className="flex justify-content-between mb-3">
<div>
<span className="block text-500 font-medium mb-3">Comments</span>
<div className="text-900 font-medium text-xl">152 Unread</div>
</div>
<div className="flex align-items-center justify-content-center bg-purple-100 border-round" style={{ width: '2.5rem', height: '2.5rem' }}>
<i className="pi pi-comment text-purple-500 text-xl"></i>
</div>
</div>
<span className="text-green-500 font-medium">85 </span>
<span className="text-500">responded</span>
</div>
</div>
</div>
</div>
</BlockViewer>
<BlockViewer header="Sign-In" code={block8} containerClassName="px-4 py-8 md:px-6 lg:px-8" free>
<div className="flex align-items-center justify-content-center">
<div className="surface-card p-4 shadow-2 border-round w-full lg:w-6">
<div className="text-center mb-5">
<img src="/demo/images/blocks/logos/hyper.svg" alt="hyper" height={50} className="mb-3" />
<div className="text-900 text-3xl font-medium mb-3">Welcome Back</div>
<span className="text-600 font-medium line-height-3">Do not have an account?</span>
<a className="font-medium no-underline ml-2 text-blue-500 cursor-pointer">Create today!</a>
</div>
<div>
<label htmlFor="email" className="block text-900 font-medium mb-2">
Email
</label>
<InputText id="email" type="text" placeholder="Email address" className="w-full mb-3" />
<label htmlFor="password" className="block text-900 font-medium mb-2">
Password
</label>
<InputText id="password" type="password" placeholder="Password" className="w-full mb-3" />
<div className="flex align-items-center justify-content-between mb-6">
<div className="flex align-items-center">
<Checkbox id="rememberme" onChange={(e) => setChecked(e.checked as boolean)} checked={checked} className="mr-2" />
<label htmlFor="rememberme" className="text-900">
Remember me
</label>
</div>
<a className="font-medium no-underline ml-2 text-blue-500 text-right cursor-pointer">Forgot your password?</a>
</div>
<Button label="Sign In" icon="pi pi-user" className="w-full" />
</div>
</div>
</div>
</BlockViewer>
<BlockViewer header="Description List" code={block9} containerClassName="surface-section px-4 py-8 md:px-6 lg:px-8" free>
<div className="surface-section">
<div className="font-medium text-3xl text-900 mb-3">Movie Information</div>
<div className="text-500 mb-5">Morbi tristique blandit turpis. In viverra ligula id nulla hendrerit rutrum.</div>
<ul className="list-none p-0 m-0">
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Title</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">Heat</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Genre</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">
<Chip label="Crime" className="mr-2" />
<Chip label="Drama" className="mr-2" />
<Chip label="Thriller" />
</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Director</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">Michael Mann</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Actors</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1">Robert De Niro, Al Pacino</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
<li className="flex align-items-center py-3 px-2 border-top-1 border-bottom-1 border-300 flex-wrap">
<div className="text-500 w-6 md:w-2 font-medium">Plot</div>
<div className="text-900 w-full md:w-8 md:flex-order-0 flex-order-1 line-height-3">A group of professional bank robbers start to feel the heat from police when they unknowingly leave a clue at their latest heist.</div>
<div className="w-6 md:w-2 flex justify-content-end">
<Button label="Edit" icon="pi pi-pencil" text />
</div>
</li>
</ul>
</div>
</BlockViewer>
<BlockViewer header="Card" code={block10} containerClassName="px-4 py-8 md:px-6 lg:px-8" free>
<div className="surface-card p-4 shadow-2 border-round">
<div className="text-3xl font-medium text-900 mb-3">Card Title</div>
<div className="font-medium text-500 mb-3">Vivamus id nisl interdum, blandit augue sit amet, eleifend mi.</div>
<div style={{ height: '150px' }} className="border-2 border-dashed surface-border"></div>
</div>
</BlockViewer>
</>
);
};
export default BlocksDemo;

View File

@@ -1,429 +0,0 @@
'use client';
import { Button } from 'primereact/button';
import { Column } from 'primereact/column';
import { DataTable } from 'primereact/datatable';
import { Dialog } from 'primereact/dialog';
import { FileUpload } from 'primereact/fileupload';
import { InputNumber } from 'primereact/inputnumber';
import { InputText } from 'primereact/inputtext';
import { InputTextarea } from 'primereact/inputtextarea';
import { RadioButton } from 'primereact/radiobutton';
import { Rating } from 'primereact/rating';
import { Toast } from 'primereact/toast';
import { Toolbar } from 'primereact/toolbar';
import { classNames } from 'primereact/utils';
import React, { useEffect, useRef, useState } from 'react';
import { ProductService } from '../../../../demo/service/ProductService';
import type { Demo } from '@/types';
const Crud = () => {
let emptyProduct: Demo.Product = {
id: null,
name: '',
image: null,
description: '',
category: null,
price: 0,
quantity: 0,
rating: 0,
inventoryStatus: 'INSTOCK'
};
const [products, setProducts] = useState(null);
const [productDialog, setProductDialog] = useState(false);
const [deleteProductDialog, setDeleteProductDialog] = useState(false);
const [deleteProductsDialog, setDeleteProductsDialog] = useState(false);
const [product, setProduct] = useState(emptyProduct);
const [selectedProducts, setSelectedProducts] = useState(null);
const [submitted, setSubmitted] = useState(false);
const [globalFilter, setGlobalFilter] = useState(null);
const toast = useRef(null);
const dt = useRef(null);
useEffect(() => {
ProductService.getProducts().then((data) => setProducts(data));
}, []);
const formatCurrency = (value) => {
return value.toLocaleString('en-US', {
style: 'currency',
currency: 'USD'
});
};
const openNew = () => {
setProduct(emptyProduct);
setSubmitted(false);
setProductDialog(true);
};
const hideDialog = () => {
setSubmitted(false);
setProductDialog(false);
};
const hideDeleteProductDialog = () => {
setDeleteProductDialog(false);
};
const hideDeleteProductsDialog = () => {
setDeleteProductsDialog(false);
};
const saveProduct = () => {
setSubmitted(true);
if (product.name.trim()) {
let _products = [...products];
let _product = { ...product };
if (product.id) {
const index = findIndexById(product.id);
_products[index] = _product;
toast.current.show({
severity: 'success',
summary: 'Successful',
detail: 'Product Updated',
life: 3000
});
} else {
_product.id = createId();
_product.code = createId();
_product.image = 'product-placeholder.svg';
_products.push(_product);
toast.current.show({
severity: 'success',
summary: 'Successful',
detail: 'Product Created',
life: 3000
});
}
setProducts(_products);
setProductDialog(false);
setProduct(emptyProduct);
}
};
const editProduct = (product) => {
setProduct({ ...product });
setProductDialog(true);
};
const confirmDeleteProduct = (product) => {
setProduct(product);
setDeleteProductDialog(true);
};
const deleteProduct = () => {
let _products = products.filter((val) => val.id !== product.id);
setProducts(_products);
setDeleteProductDialog(false);
setProduct(emptyProduct);
toast.current.show({
severity: 'success',
summary: 'Successful',
detail: 'Product Deleted',
life: 3000
});
};
const findIndexById = (id) => {
let index = -1;
for (let i = 0; i < products.length; i++) {
if (products[i].id === id) {
index = i;
break;
}
}
return index;
};
const createId = () => {
let id = '';
let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < 5; i++) {
id += chars.charAt(Math.floor(Math.random() * chars.length));
}
return id;
};
const exportCSV = () => {
dt.current.exportCSV();
};
const confirmDeleteSelected = () => {
setDeleteProductsDialog(true);
};
const deleteSelectedProducts = () => {
let _products = products.filter((val) => !selectedProducts.includes(val));
setProducts(_products);
setDeleteProductsDialog(false);
setSelectedProducts(null);
toast.current.show({
severity: 'success',
summary: 'Successful',
detail: 'Products Deleted',
life: 3000
});
};
const onCategoryChange = (e) => {
let _product = { ...product };
_product['category'] = e.value;
setProduct(_product);
};
const onInputChange = (e, name) => {
const val = (e.target && e.target.value) || '';
let _product = { ...product };
_product[`${name}`] = val;
setProduct(_product);
};
const onInputNumberChange = (e, name) => {
const val = e.value || 0;
let _product = { ...product };
_product[`${name}`] = val;
setProduct(_product);
};
const leftToolbarTemplate = () => {
return (
<React.Fragment>
<div className="my-2">
<Button severity="success" label="New" icon="pi pi-plus" className="mr-2" onClick={openNew} />
<Button severity="danger" label="Delete" icon="pi pi-trash" onClick={confirmDeleteSelected} disabled={!selectedProducts || !selectedProducts.length} />
</div>
</React.Fragment>
);
};
const rightToolbarTemplate = () => {
return (
<React.Fragment>
<FileUpload mode="basic" accept="image/*" maxFileSize={1000000} chooseLabel="Import" className="mr-2 inline-block" />
<Button severity="help" label="Export" icon="pi pi-upload" onClick={exportCSV} />
</React.Fragment>
);
};
const codeBodyTemplate = (rowData) => {
return (
<>
<span className="p-column-title">Code</span>
{rowData.code}
</>
);
};
const nameBodyTemplate = (rowData) => {
return (
<>
<span className="p-column-title">Name</span>
{rowData.name}
</>
);
};
const imageBodyTemplate = (rowData) => {
return (
<>
<span className="p-column-title">Image</span>
<img src={`/demo/images/product/${rowData.image}`} alt={rowData.image} className="shadow-2" width="100" />
</>
);
};
const priceBodyTemplate = (rowData) => {
return (
<>
<span className="p-column-title">Price</span>
{formatCurrency(rowData.price)}
</>
);
};
const categoryBodyTemplate = (rowData) => {
return (
<>
<span className="p-column-title">Category</span>
{rowData.category}
</>
);
};
const ratingBodyTemplate = (rowData) => {
return (
<>
<span className="p-column-title">Reviews</span>
<Rating value={rowData.rating} readOnly cancel={false} />
</>
);
};
const statusBodyTemplate = (rowData) => {
return (
<>
<span className="p-column-title">Status</span>
<span className={`product-badge status-${rowData.inventoryStatus.toLowerCase()}`}>{rowData.inventoryStatus}</span>
</>
);
};
const actionBodyTemplate = (rowData) => {
return (
<>
<Button icon="pi pi-pencil" rounded severity="success" className="mr-2" onClick={() => editProduct(rowData)} />
<Button icon="pi pi-trash" rounded severity="warning" onClick={() => confirmDeleteProduct(rowData)} />
</>
);
};
const header = (
<div className="flex flex-column md:flex-row md:justify-content-between md:align-items-center">
<h5 className="m-0">Manage Products</h5>
<span className="block mt-2 md:mt-0 p-input-icon-left">
<i className="pi pi-search" />
<InputText type="search" onInput={(e) => setGlobalFilter((e.target as HTMLInputElement).value)} placeholder="Search..." />
</span>
</div>
);
const productDialogFooter = (
<>
<Button label="Cancel" icon="pi pi-times" text onClick={hideDialog} />
<Button label="Save" icon="pi pi-check" text onClick={saveProduct} />
</>
);
const deleteProductDialogFooter = (
<>
<Button label="No" icon="pi pi-times" text onClick={hideDeleteProductDialog} />
<Button label="Yes" icon="pi pi-check" text onClick={deleteProduct} />
</>
);
const deleteProductsDialogFooter = (
<>
<Button label="No" icon="pi pi-times" text onClick={hideDeleteProductsDialog} />
<Button label="Yes" icon="pi pi-check" text onClick={deleteSelectedProducts} />
</>
);
return (
<div className="grid crud-demo">
<div className="col-12">
<div className="card">
<Toast ref={toast} />
<Toolbar className="mb-4" left={leftToolbarTemplate} right={rightToolbarTemplate}></Toolbar>
<DataTable
ref={dt}
value={products}
selection={selectedProducts}
onSelectionChange={(e) => setSelectedProducts(e.value)}
paginator
rows={10}
rowsPerPageOptions={[5, 10, 25]}
className="datatable-responsive"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} products"
globalFilter={globalFilter}
emptyMessage="No products found."
header={header}
responsiveLayout="scroll"
>
<Column selectionMode="multiple" headerStyle={{ width: '4rem' }}></Column>
<Column field="code" header="Code" sortable body={codeBodyTemplate} headerStyle={{ minWidth: '15rem' }}></Column>
<Column field="name" header="Name" sortable body={nameBodyTemplate} headerStyle={{ minWidth: '15rem' }}></Column>
<Column header="Image" body={imageBodyTemplate}></Column>
<Column field="price" header="Price" body={priceBodyTemplate} sortable></Column>
<Column field="category" header="Category" sortable body={categoryBodyTemplate} headerStyle={{ minWidth: '10rem' }}></Column>
<Column field="rating" header="Reviews" body={ratingBodyTemplate} sortable></Column>
<Column field="inventoryStatus" header="Status" body={statusBodyTemplate} sortable headerStyle={{ minWidth: '10rem' }}></Column>
<Column body={actionBodyTemplate} headerStyle={{ minWidth: '10rem' }}></Column>
</DataTable>
<Dialog visible={productDialog} style={{ width: '450px' }} header="Product Details" modal className="p-fluid" footer={productDialogFooter} onHide={hideDialog}>
{product.image && <img src={`/demo/images/product/${product.image}`} alt={product.image} width="150" className="mt-0 mx-auto mb-5 block shadow-2" />}
<div className="field">
<label htmlFor="name">Name</label>
<InputText
id="name"
value={product.name}
onChange={(e) => onInputChange(e, 'name')}
required
autoFocus
className={classNames({
'p-invalid': submitted && !product.name
})}
/>
{submitted && !product.name && <small className="p-invalid">Name is required.</small>}
</div>
<div className="field">
<label htmlFor="description">Description</label>
<InputTextarea id="description" value={product.description} onChange={(e) => onInputChange(e, 'description')} required rows={3} cols={20} />
</div>
<div className="field">
<label className="mb-3">Category</label>
<div className="formgrid grid">
<div className="field-radiobutton col-6">
<RadioButton inputId="category1" name="category" value="Accessories" onChange={onCategoryChange} checked={product.category === 'Accessories'} />
<label htmlFor="category1">Accessories</label>
</div>
<div className="field-radiobutton col-6">
<RadioButton inputId="category2" name="category" value="Clothing" onChange={onCategoryChange} checked={product.category === 'Clothing'} />
<label htmlFor="category2">Clothing</label>
</div>
<div className="field-radiobutton col-6">
<RadioButton inputId="category3" name="category" value="Electronics" onChange={onCategoryChange} checked={product.category === 'Electronics'} />
<label htmlFor="category3">Electronics</label>
</div>
<div className="field-radiobutton col-6">
<RadioButton inputId="category4" name="category" value="Fitness" onChange={onCategoryChange} checked={product.category === 'Fitness'} />
<label htmlFor="category4">Fitness</label>
</div>
</div>
</div>
<div className="formgrid grid">
<div className="field col">
<label htmlFor="price">Price</label>
<InputNumber id="price" value={product.price as number} onValueChange={(e) => onInputNumberChange(e, 'price')} mode="currency" currency="USD" locale="en-US" />
</div>
<div className="field col">
<label htmlFor="quantity">Quantity</label>
<InputNumber id="quantity" value={product.quantity} onValueChange={(e) => onInputNumberChange(e, 'quantity')} />
</div>
</div>
</Dialog>
<Dialog visible={deleteProductDialog} style={{ width: '450px' }} header="Confirm" modal footer={deleteProductDialogFooter} onHide={hideDeleteProductDialog}>
<div className="flex align-items-center justify-content-center">
<i className="pi pi-exclamation-triangle mr-3" style={{ fontSize: '2rem' }} />
{product && (
<span>
Are you sure you want to delete <b>{product.name}</b>?
</span>
)}
</div>
</Dialog>
<Dialog visible={deleteProductsDialog} style={{ width: '450px' }} header="Confirm" modal footer={deleteProductsDialogFooter} onHide={hideDeleteProductsDialog}>
<div className="flex align-items-center justify-content-center">
<i className="pi pi-exclamation-triangle mr-3" style={{ fontSize: '2rem' }} />
{product && <span>Are you sure you want to delete the selected products?</span>}
</div>
</Dialog>
</div>
</div>
</div>
);
};
export default Crud;

View File

@@ -1,149 +0,0 @@
'use client';
import { useRouter } from 'next/navigation';
import { FilterMatchMode, FilterOperator } from 'primereact/api';
import { Button } from 'primereact/button';
import { Column } from 'primereact/column';
import { DataTable, DataTableFilterMeta } from 'primereact/datatable';
import { InputText } from 'primereact/inputtext';
import { ProgressBar } from 'primereact/progressbar';
import React, { useEffect, useRef, useState } from 'react';
import { CustomerService } from '../../../../demo/service/CustomerService';
import type { Demo } from '@/types';
function List() {
const [customers, setCustomers] = useState<Demo.Customer[]>([]);
const [filters, setFilters] = useState<DataTableFilterMeta>({});
const [loading, setLoading] = useState(true);
const [globalFilterValue, setGlobalFilterValue] = useState('');
const router = useRouter();
const dt = useRef(null);
const getCustomers = (data: Demo.Customer[]) => {
return [...(data || [])].map((d) => {
d.date = new Date(d.date);
return d;
});
};
const formatDate = (value: Date) => {
return value.toLocaleDateString('en-US', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
};
const clearFilter = () => {
initFilters();
};
const initFilters = () => {
setFilters({
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
name: {
operator: FilterOperator.AND,
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
},
'country.name': {
operator: FilterOperator.AND,
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
},
representative: { value: null, matchMode: FilterMatchMode.IN },
date: {
operator: FilterOperator.AND,
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
},
activity: { value: null, matchMode: FilterMatchMode.BETWEEN }
});
setGlobalFilterValue('');
};
useEffect(() => {
CustomerService.getCustomersLarge().then((data) => {
setCustomers(getCustomers(data));
setLoading(false);
});
initFilters();
}, []);
const onGlobalFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { value } = e.target;
let _filters = { ...filters };
(_filters['global'] as any).value = value;
setFilters(_filters);
setGlobalFilterValue(value);
};
const renderHeader = () => {
return (
<div className="flex flex-wrap gap-2 align-items-center justify-content-between">
<span className="p-input-icon-left w-full sm:w-20rem flex-order-1 sm:flex-order-0">
<i className="pi pi-search"></i>
<InputText value={globalFilterValue} onChange={onGlobalFilterChange} placeholder="Global Search" className="w-full" />
</span>
<Button type="button" icon="pi pi-user-plus" label="Add New" className="w-full sm:w-auto flex-order-0 sm:flex-order-1" outlined onClick={() => router.push('/profile/create')} />
</div>
);
};
const nameBodyTemplate = (customer: Demo.Customer) => {
return (
<>
<span className="p-column-title">Name</span>
{customer.name}
</>
);
};
const countryBodyTemplate = (customer: Demo.Customer) => {
return (
<>
<img alt={customer.country.name} src={`/demo/images/flag/flag_placeholder.png`} className={'w-2rem mr-2 flag flag-' + customer.country.code} />
<span className="image-text">{customer.country.name}</span>
</>
);
};
const createdByBodyTemplate = (customer: Demo.Customer) => {
return (
<div className="inline-flex align-items-center">
<img alt={customer.representative.name} src={`/demo/images/avatar/${customer.representative.image}`} className="w-2rem mr-2" />
<span>{customer.representative.name}</span>
</div>
);
};
const dateBodyTemplate = (customer: Demo.Customer) => {
return formatDate(customer.date);
};
const activityBodyTemplate = (customer: Demo.Customer) => {
return <ProgressBar value={customer.activity} showValue={false} style={{ height: '.5rem' }} />;
};
const header = renderHeader();
return (
<div className="card">
<DataTable
ref={dt}
value={customers}
header={header}
paginator
rows={10}
responsiveLayout="scroll"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
rowsPerPageOptions={[10, 25, 50]}
filters={filters}
loading={loading}
>
<Column field="name" header="Name" sortable body={nameBodyTemplate} headerClassName="white-space-nowrap" style={{ width: '25%' }}></Column>
<Column field="country.name" header="Country" sortable body={countryBodyTemplate} headerClassName="white-space-nowrap" style={{ width: '25%' }}></Column>
<Column field="date" header="Join Date" sortable body={dateBodyTemplate} headerClassName="white-space-nowrap" style={{ width: '25%' }}></Column>
<Column field="representative.name" header="Created By" body={createdByBodyTemplate} headerClassName="white-space-nowrap" style={{ width: '25%' }} sortable></Column>
<Column field="activity" header="Activity" body={activityBodyTemplate} headerClassName="white-space-nowrap" style={{ width: '25%' }} sortable></Column>
</DataTable>
</div>
);
}
export default List;

View File

@@ -1,369 +0,0 @@
'use client';
import React, { useState, useEffect } from 'react';
import { Panel } from 'primereact/panel';
import { Button } from 'primereact/button';
import { Message } from 'primereact/message';
import { Divider } from 'primereact/divider';
import { Toast } from 'primereact/toast';
import { useRef } from 'react';
import TestDataGenerator from '../../../../components/test/TestDataGenerator';
import TestResults from '../../../../components/test/TestResults';
import WorkflowTests from '../../../../components/test/WorkflowTests';
import SystemIntegrationTest from '../../../../components/test/SystemIntegrationTest';
import PhasesQuickPreview from '../../../../components/phases/PhasesQuickPreview';
import PhaseValidationPanel from '../../../../components/phases/PhaseValidationPanel';
import AtlantisResponsivePhasesTable from '../../../../components/phases/AtlantisResponsivePhasesTable';
import AtlantisAccessibilityControls from '../../../../components/phases/AtlantisAccessibilityControls';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Tag } from 'primereact/tag';
import { Badge } from 'primereact/badge';
import { Dialog } from 'primereact/dialog';
import testDataService from '../../../../services/testDataService';
import phaseValidationService from '../../../../services/phaseValidationService';
import type { PhaseChantier, Chantier, Client } from '../../../../types/btp';
interface TestData {
client: Client;
chantier: Chantier;
phases: PhaseChantier[];
}
const TestPhasesPage: React.FC = () => {
const [testData, setTestData] = useState<TestData[]>([]);
const [selectedData, setSelectedData] = useState<TestData | null>(null);
const [validationDialogVisible, setValidationDialogVisible] = useState(false);
const [selectedPhase, setSelectedPhase] = useState<PhaseChantier | null>(null);
const [loading, setLoading] = useState(false);
const toast = useRef<Toast>(null);
// Auto-générer des données de test au chargement
useEffect(() => {
generateInitialData();
}, []);
const generateInitialData = async () => {
try {
const initialData = testDataService.generateTestDataset(2);
setTestData(initialData);
if (initialData.length > 0) {
setSelectedData(initialData[0]);
}
toast.current?.show({
severity: 'success',
summary: 'Données de test générées',
detail: `${initialData.length} projets avec phases créés`,
life: 3000
});
} catch (error) {
toast.current?.show({
severity: 'error',
summary: 'Erreur',
detail: 'Impossible de générer les données de test',
life: 5000
});
}
};
const handleDataGenerated = (newData: any) => {
if (Array.isArray(newData)) {
setTestData(prev => [...prev, ...newData]);
if (!selectedData && newData.length > 0) {
setSelectedData(newData[0]);
}
} else {
// Données individuelles (phases uniquement, etc.)
const dataItem: TestData = {
client: newData.client || testDataService.generateTestClient(Date.now()),
chantier: newData.chantier || testDataService.generateTestChantier(Date.now(), 'MAISON_INDIVIDUELLE', newData.client),
phases: newData.phases || []
};
setTestData(prev => [...prev, dataItem]);
setSelectedData(dataItem);
}
toast.current?.show({
severity: 'success',
summary: 'Nouvelles données générées',
detail: 'Les données ont été ajoutées avec succès',
life: 3000
});
};
const handlePhaseValidation = (phase: PhaseChantier) => {
setSelectedPhase(phase);
setValidationDialogVisible(true);
};
const handleStartPhase = (phaseId: string) => {
if (!selectedData) return;
const updatedPhases = selectedData.phases.map(p =>
p.id === phaseId
? { ...p, statut: 'EN_COURS' as const, dateDebutReelle: new Date().toISOString().split('T')[0] }
: p
);
const updatedData = { ...selectedData, phases: updatedPhases };
setSelectedData(updatedData);
setTestData(prev => prev.map(item =>
item.chantier.id === updatedData.chantier.id ? updatedData : item
));
toast.current?.show({
severity: 'info',
summary: 'Phase démarrée',
detail: `La phase a été mise en cours`,
life: 3000
});
setValidationDialogVisible(false);
};
// Templates pour l'affichage du tableau
const statusBodyTemplate = (rowData: PhaseChantier) => {
const severity = rowData.statut === 'TERMINEE' ? 'success' :
rowData.statut === 'EN_COURS' ? 'info' : 'secondary';
return <Tag value={rowData.statut} severity={severity} />;
};
const progressBodyTemplate = (rowData: PhaseChantier) => {
return (
<div className="flex align-items-center gap-2">
<span>{rowData.pourcentageAvancement || 0}%</span>
<div className="w-4rem h-0.5rem bg-gray-200 border-round overflow-hidden">
<div
className="h-full bg-primary border-round"
style={{ width: `${rowData.pourcentageAvancement || 0}%` }}
></div>
</div>
</div>
);
};
const validationBodyTemplate = (rowData: PhaseChantier) => {
if (!selectedData) return null;
const validation = phaseValidationService.validatePhaseStart(rowData, selectedData.phases);
const severity = validation.readyToStart ? 'success' :
validation.canStart ? 'warning' : 'danger';
const icon = validation.readyToStart ? 'pi pi-check-circle' :
validation.canStart ? 'pi pi-exclamation-triangle' : 'pi pi-times-circle';
return (
<div className="flex align-items-center gap-2">
<i className={`${icon} text-${severity === 'danger' ? 'red' : severity === 'warning' ? 'yellow' : 'green'}-500`}></i>
{validation.errors.length > 0 && (
<Badge value={validation.errors.length} severity="danger" />
)}
{validation.warnings.length > 0 && (
<Badge value={validation.warnings.length} severity="warning" />
)}
<Button
icon="pi pi-eye"
className="p-button-text p-button-sm"
onClick={() => handlePhaseValidation(rowData)}
tooltip="Voir la validation"
/>
</div>
);
};
const nameBodyTemplate = (rowData: PhaseChantier) => {
const isSubPhase = !!rowData.phaseParent;
return (
<div className={`flex align-items-center gap-2 ${isSubPhase ? 'ml-4' : ''}`}>
{isSubPhase && <i className="pi pi-arrow-right text-gray-400 text-xs"></i>}
<span className={isSubPhase ? 'text-600' : 'font-semibold'}>
{rowData.nom}
</span>
{rowData.critique && (
<Tag value="Critique" severity="danger" className="text-xs" />
)}
</div>
);
};
const actionsBodyTemplate = (rowData: PhaseChantier) => {
if (!selectedData) return null;
const validation = phaseValidationService.validatePhaseStart(rowData, selectedData.phases);
return (
<div className="flex gap-1">
<Button
icon="pi pi-play"
className="p-button-success p-button-sm"
disabled={!validation.canStart || rowData.statut === 'TERMINEE'}
onClick={() => handleStartPhase(rowData.id!)}
tooltip="Démarrer"
/>
<Button
icon="pi pi-eye"
className="p-button-outlined p-button-sm"
onClick={() => handlePhaseValidation(rowData)}
tooltip="Détails"
/>
</div>
);
};
return (
<div className="grid">
<Toast ref={toast} />
<div className="col-12">
<Panel header="Test du système de gestion des phases BTP" toggleable>
<Message
severity="info"
text="Cette page permet de tester le système complet de gestion des phases avec des données réalistes."
className="w-full mb-4"
/>
<TestResults className="mb-4" />
<WorkflowTests className="mb-4" />
<SystemIntegrationTest className="mb-4" />
<TestDataGenerator
onDataGenerated={handleDataGenerated}
className="mb-4"
/>
</Panel>
</div>
{testData.length > 0 && (
<>
<div className="col-12 md:col-4">
<Panel header="Projets de test" toggleable>
{testData.map((data, index) => (
<div
key={data.chantier.id}
className={`p-3 border-1 border-round cursor-pointer mb-2 ${
selectedData?.chantier.id === data.chantier.id
? 'border-primary bg-primary-50'
: 'surface-border hover:surface-100'
}`}
onClick={() => setSelectedData(data)}
>
<div className="font-semibold">{data.chantier.nom}</div>
<div className="text-600 text-sm">{data.client.nomComplet}</div>
<div className="text-600 text-sm">
{data.phases.length} phases {data.chantier.typeChantier}
</div>
</div>
))}
</Panel>
</div>
<div className="col-12 md:col-8">
{selectedData && (
<>
<AtlantisAccessibilityControls className="mb-4" />
<PhasesQuickPreview
phases={selectedData.phases}
className="mb-4"
/>
<AtlantisResponsivePhasesTable
phases={selectedData.phases}
onPhaseSelect={setSelectedPhase}
onPhaseStart={handleStartPhase}
onPhaseValidate={handlePhaseValidation}
className="mb-4"
/>
<Panel header={`Détails - ${selectedData.chantier.nom}`} toggleable collapsed>
<DataTable
value={selectedData.phases}
size="small"
className="p-datatable-sm"
emptyMessage="Aucune phase trouvée"
>
<Column
field="nom"
header="Phase"
body={nameBodyTemplate}
style={{ width: '25%' }}
/>
<Column
field="statut"
header="Statut"
body={statusBodyTemplate}
style={{ width: '10%' }}
/>
<Column
field="pourcentageAvancement"
header="Avancement"
body={progressBodyTemplate}
style={{ width: '15%' }}
/>
<Column
field="dateDebutPrevue"
header="Début prévu"
body={(rowData) => rowData.dateDebutPrevue ?
new Date(rowData.dateDebutPrevue).toLocaleDateString('fr-FR') : '-'
}
style={{ width: '12%' }}
/>
<Column
field="dateFinPrevue"
header="Fin prévue"
body={(rowData) => rowData.dateFinPrevue ?
new Date(rowData.dateFinPrevue).toLocaleDateString('fr-FR') : '-'
}
style={{ width: '12%' }}
/>
<Column
header="Validation"
body={validationBodyTemplate}
style={{ width: '15%' }}
/>
<Column
header="Actions"
body={actionsBodyTemplate}
style={{ width: '11%' }}
/>
</DataTable>
</Panel>
</>
)}
</div>
</>
)}
<Dialog
header="Validation des prérequis"
visible={validationDialogVisible}
onHide={() => setValidationDialogVisible(false)}
style={{ width: '90vw', maxWidth: '800px' }}
modal
>
{selectedPhase && selectedData && (
<PhaseValidationPanel
phase={selectedPhase}
allPhases={selectedData.phases}
onStartPhase={handleStartPhase}
onViewPrerequisite={(prereqId) => {
const prereq = selectedData.phases.find(p => p.id === prereqId);
if (prereq) {
setSelectedPhase(prereq);
}
}}
/>
)}
</Dialog>
</div>
);
};
export default TestPhasesPage;