reza added button and tag

master
Reza_ashrafi 3 years ago
parent 0b27064f81
commit a3c5099b95
  1. 10
      package.json
  2. 60
      src/App.css
  3. 43
      src/App.js
  4. 51
      src/Views/Home/Main/index.js
  5. 119
      src/Views/Home/Sidebar/index.js
  6. 16
      src/Views/Home/index.js
  7. 11
      src/components/Alert/index.js
  8. 8
      src/components/Button/black-downward-arrow.svg
  9. 8
      src/components/Button/black-left-arrow.svg
  10. 8
      src/components/Button/black-right-arrow.svg
  11. BIN
      src/components/Button/black-upward-arrow.png
  12. 139
      src/components/Button/index.js
  13. 3
      src/components/Button/white-downward-arrow.svg
  14. 6
      src/components/Button/white-left-arrow.svg
  15. 8
      src/components/Button/white-right-arrow.svg
  16. 3
      src/components/Button/white-upward-arrow.svg
  17. 38
      src/components/CircularProgressbar/index.js
  18. BIN
      src/components/Code/copy.png
  19. 74
      src/components/Code/index.js
  20. 11
      src/components/Counter/index.js
  21. 15
      src/components/Input/index.js
  22. 9
      src/components/Range/index.js
  23. 32
      src/components/Recharts/index.js
  24. 4
      src/components/Search/index.js
  25. 10
      src/components/SelectCheckbox/index.js
  26. 10
      src/components/SelectRadio/index.js
  27. 8
      src/components/SidebarCategoryHover/Col.js
  28. 2
      src/components/SidebarCategoryHover/index.js
  29. 15
      src/components/SidebarCategoryHover/list.js
  30. 8
      src/components/Slider/index.js
  31. 16
      src/components/StarRating/index.js
  32. 84
      src/components/Stepper/index.js
  33. 8
      src/components/Tag/black-cancle-icon.svg
  34. 25
      src/components/Tag/index.js
  35. 11
      src/components/Toast/index.js
  36. 4
      src/components/VerticalExpandableProductFilter/index.js
  37. 6
      src/components/search-with-suggest/index.js
  38. 12
      src/redux/actions/components.js
  39. 1
      src/redux/actions/index.js
  40. 450
      src/redux/data.js
  41. 6
      src/redux/index.js
  42. 16
      src/redux/reducers/components.js
  43. 1
      src/redux/reducers/index.js
  44. 14
      src/redux/store.js
  45. 45
      src/router.js
  46. 7493
      yarn.lock

@ -9,9 +9,19 @@
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"lodash": "^4.17.21",
"rc-slider": "^9.7.5",
"react": "^17.0.2",
"react-circular-progressbar": "^2.0.4",
"react-code-blocks": "^0.0.9-0",
"react-dom": "^17.0.2",
"react-redux": "^7.2.6",
"react-router-dom": "^6.2.1",
"react-scripts": "4.0.3",
"react-star-rating-component": "^1.4.1",
"recharts": "^2.1.8",
"redux": "^4.1.2",
"redux-devtools-extension": "^2.13.9",
"redux-thunk": "^2.4.1",
"sass": "^1.43.4",
"web-vitals": "^1.0.1"
},

@ -1,59 +1,3 @@
.App {
text-align: center;
body{
direction: rtl;
padding: 10px;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
.en {
direction: ltr;
text-align: left;
}
.fa {
direction: rtl;
text-align: right;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
/* clears the ‘X’ from Internet Explorer */
input[type=search]::-ms-clear { display: none; width : 0; height: 0; }
input[type=search]::-ms-reveal { display: none; width : 0; height: 0; }
/* clears the ‘X’ from Chrome */
input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-results-button,
input[type="search"]::-webkit-search-results-decoration { display: none; }
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
}

@ -1,40 +1,17 @@
import Search from './components/Search';
import SearchWithSuggest from './components/search-with-suggest';
import Input from './components/Input';
import Radio from './components/Radio';
import Checkbox from './components/Checkbox';
import SelectRadio from './components/SelectRadio';
import SelectCheckbox from './components/SelectCheckbox';
import Switch from './components/Switch';
import VerticalExpandableProductFilter from './components/VerticalExpandableProductFilter';
import SidebarCategoryHover from './components/SidebarCategoryHover';
import Router from './router.js';
import {Provider} from 'react-redux';
import store from './redux/store';
import 'rc-slider/assets/index.css';
import 'react-circular-progressbar/dist/styles.css';
import './App.css';
import "./App.css";
function App() {
return (
<div className="App">
<Search />
<hr className="my-2" />
<SearchWithSuggest lang="en" />
<hr className="my-2" />
<Input status={false} label={'نام خانوادگی'} lang="fa" maxLength="30" inputMode="numeric" message="خطا" />
<hr className="my-2" />
<Radio />
<hr className="my-2" />
<Checkbox />
<hr className="my-2" />
<SelectRadio />
<hr className="my-2" />
<SelectCheckbox />
<hr className="my-2" />
<Switch />
<hr className="my-2" />
<VerticalExpandableProductFilter />
<hr className="my-2" />
<SidebarCategoryHover />
</div>
<Provider store={store}>
<Router />
</Provider>
);
}
export default App;
export default App;

@ -0,0 +1,51 @@
import React from "react";
import { connect } from "react-redux";
import Code from "../../../components/Code";
function Main({ activeComponent }) {
return (
<div className="lg:flex lg:flex-col lg:w-5/6 lg:h-full border-r border-gray-200">
<header className="w-full flex flex-row items-center h-16 px-1 py-4 bg-gray-700"></header>
<section className="w-full lg:overflow-y-scroll py-5 px-10 flex-1 flex-col">
<h1 className="font-bold text-3xl mb-10 text-left">
{activeComponent?.content?.name}
</h1>
{activeComponent?.content?.component}
{activeComponent?.content?.code && (
<Code code={activeComponent?.content?.code} />
)}
{/* <h2>Props</h2> */}
{activeComponent?.props?.length > 0 && (
<table className="w-full" style={{ direction: "ltr" }}>
<thead>
<tr>
<th className="font-bold text-lg">Name</th>
<th className="font-bold text-lg">Type</th>
<th className="font-bold text-lg">Required</th>
<th className="font-bold text-lg">Default value</th>
<th className="font-bold text-lg">Description</th>
</tr>
</thead>
<tbody className="w-full divided divide-y">
{activeComponent?.props?.map((prop, index) => (
<tr key={index} className="">
<td className="py-3 text-center">{prop.name}</td>
<td className="py-3 text-center">{prop.type}</td>
<td className="py-3 text-center">{prop.required}</td>
<td className="py-3 text-center">{prop.defaultValue}</td>
<td className="py-3 text-center">{prop.description}</td>
</tr>
))}
</tbody>
</table>
)}
</section>
</div>
);
}
const mapStateToProps = (state) => ({
activeComponent: state.components.activeComponent,
});
export default connect(mapStateToProps, {})(Main);

@ -0,0 +1,119 @@
import React from "react";
import { connect } from "react-redux";
import { components } from "../../../redux/actions";
function Sidebar({ list, setActive }) {
return (
<div className="lg:flex lg:flex-col lg:w-1/6 lg:h-full" style={{ direction: 'ltr' }}>
<header className="w-full flex flex-row items-center h-16 px-1 py-4 bg-gray-700">
<img
src={"https://barnamenegar.ir/static/media/white logo 2.7ffbddbc.svg"}
alt="logo"
className="w-full"
/>
</header>
<ul className="w-full flex-1 p-0 m-0 list-none divided divide-y max-h-full lg:overflow-y-scroll divide-blue-100 border-r border-gray-200">
{list.map((material, index) => (
<li
key={index}
className="w-full py-3 px-3 font-medium text-md cursor-pointer h-12"
onClick={() => setActive(material)}
>
{material.name}
</li>
))}
</ul>
</div>
);
}
const mapStateToProps = (state) => ({
list: state.components.list,
});
export default connect(mapStateToProps, {
setActive: components.activeComponent,
})(Sidebar);
Sidebar.defaultProps = {
materials: [
{
name: "Button",
},
{
name: "TextInput",
},
{
name: "Search",
},
{
name: "Radio",
},
{
name: "Check Box",
},
{
name: "Select Box",
},
{
name: "Category",
},
{
name: "Tag",
},
{
name: "Slider",
},
{
name: "Counters",
},
{
name: "Features",
},
{
name: "Calendar",
},
{
name: "Date Picker",
},
{
name: "Alert",
},
{
name: "Reaction",
},
{
name: "Step",
},
{
name: "Vote Status",
},
{
name: "Comment",
},
{
name: "Info Box",
},
{
name: "Quote",
},
{
name: "Blog",
},
{
name: "Percent",
},
{
name: "Chart",
},
{
name: "Bottom Navigation",
},
{
name: "Navbar",
},
{
name: "Product",
},
],
};

@ -0,0 +1,16 @@
import React from "react";
import Sidebar from "./Sidebar";
import Main from "./Main";
function Home() {
return (
<div className="flex lg:w-full lg:flex-col lg:h-screen lg:overflow-hidden">
<div className="lg:w-full h-full lg:flex lg:flex-row">
<Main />
<Sidebar />
</div>
</div>
);
}
export default Home;

@ -0,0 +1,11 @@
import React from 'react'
function Alert() {
return (
<div>
</div>
)
}
export default Alert;

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="37.14" height="37.14" viewBox="0 0 37.14 37.14">
<g id="vuesax_linear_arrow-left" data-name="vuesax/linear/arrow-left" transform="translate(401.14 289.14) rotate(180)">
<g id="arrow-left" transform="translate(364 252)">
<path id="Vector" d="M10.983,24.512.894,14.423a3.073,3.073,0,0,1,0-4.333L10.983,0" transform="translate(12.229 6.314)" fill="none" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<path id="Vector-2" data-name="Vector" d="M0,0H37.14V37.14H0Z" transform="translate(37.14 37.14) rotate(180)" fill="none" opacity="0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 658 B

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="37.14" height="37.14" viewBox="0 0 37.14 37.14">
<g id="vuesax_linear_arrow-left" data-name="vuesax/linear/arrow-left" transform="translate(-364 -252)">
<g id="arrow-left" transform="translate(364 252)">
<path id="Vector" d="M10.983,24.512.894,14.423a3.073,3.073,0,0,1,0-4.333L10.983,0" transform="translate(12.229 6.314)" fill="none" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<path id="Vector-2" data-name="Vector" d="M0,0H37.14V37.14H0Z" transform="translate(37.14 37.14) rotate(180)" fill="none" opacity="0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 642 B

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="37.14" height="37.14" viewBox="0 0 37.14 37.14">
<g id="vuesax_linear_arrow-left" data-name="vuesax/linear/arrow-left" transform="translate(401.14 289.14) rotate(180)">
<g id="arrow-left" transform="translate(364 252)">
<path id="Vector" d="M10.983,24.512.894,14.423a3.073,3.073,0,0,1,0-4.333L10.983,0" transform="translate(12.229 6.314)" fill="none" stroke="#646464" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<path id="Vector-2" data-name="Vector" d="M0,0H37.14V37.14H0Z" transform="translate(37.14 37.14) rotate(180)" fill="none" opacity="0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

@ -0,0 +1,139 @@
import React from "react";
import whiteLeftArrow from "./white-left-arrow.svg";
import whiteRightArrow from "./white-right-arrow.svg";
import whiteUpwardArrow from "./white-upward-arrow.svg";
import whiteDownwardArrow from "./white-downward-arrow.svg";
import blackRightArrow from "./black-right-arrow.svg";
import blackLeftArrow from "./black-left-arrow.svg";
import blackUpwardArrow from "./black-upward-arrow.png";
import blackDownwardArrow from "./black-downward-arrow.svg";
const Button = ({
buttonBgColor,
circleArrowBgClr,
buttonTextColor,
buttonBorder,
buttonBorderColor,
buttonBorderRadius,
imageMarginRight,
imageWidth,
imageHeight,
// icons
leftArrowWhite,
rightArrowWhite,
upwardArrowWhite,
downwardArrowWhite,
leftArrowBlack,
rightArrowBlack,
upwardArrowBlack,
downwardArrowBlack,
circleArrow,
}) => {
return (
<button
className={`flex items-center border-none cursor-pointer py-2.5 px-2 text-sm ${buttonBgColor} ${buttonTextColor} ${buttonBorder} ${buttonBorderColor} ${buttonBorderRadius}`}
>
اطلاعات بیشتر
{leftArrowWhite && (
<img
src={whiteLeftArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{rightArrowWhite && (
<img
src={whiteRightArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{upwardArrowWhite && (
<img
src={whiteUpwardArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{downwardArrowWhite && (
<img
src={whiteDownwardArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{leftArrowBlack && (
<img
src={blackLeftArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{rightArrowBlack && (
<img
src={blackRightArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{upwardArrowBlack && (
<img
src={blackUpwardArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{downwardArrowBlack && (
<img
src={blackDownwardArrow}
alt=""
className={`${imageMarginRight} ${imageWidth} ${imageHeight} `}
/>
)}
{circleArrow && (
<span className={`rounded-full p-2 mr-2 ${circleArrowBgClr} `}>
<img src={whiteLeftArrow} alt="" className="w-4" />
</span>
)}
</button>
);
};
export default Button;
// color classes that i defined in tailwind.config.js and we can use for text color:
// ----> text-grayTextColor
// ----> text-white
// color classes that i defined in tailwind.config.js and we can use for background color:
// ----> bg-darkGreenBg
// ----> bg-midGrayBgColor
// color classes that i defined in tailwind.config.js and we can use for border color:
// ----> border-lightBlueBorderColor
Button.defaultProps = {
buttonBgColor: "bg-darkGreenBg",
circleArrowBgClr: "bg-darkGreenBg",
buttonTextColor: "text-white",
buttonBorder: "border-b-4",
buttonBorderColor: "border-lightBlueBorderColor",
buttonBorderRadius: "rounded",
buttonPaddingX: "px-6",
buttonPaddingY: "py-4",
imageMarginRight: "mr-1",
imageWidth: "w-4",
imageHeight: "h-4",
// icons
leftArrowWhite: false,
rightArrowWhite: false,
upwardArrowWhite: false,
downwardArrowWhite: false,
leftArrowBlack: false,
rightArrowBlack: false,
upwardArrowBlack: false,
downwardArrowBlack: false,
circleArrow: false,
};

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28.755" height="14.605" viewBox="0 0 28.755 14.605">
<path id="Vector" d="M10.983,24.512,3.275,16.8.894,14.423a3.073,3.073,0,0,1,0-4.333L10.983,0" transform="translate(2.121 13.105) rotate(-90)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
</svg>

After

Width:  |  Height:  |  Size: 343 B

@ -0,0 +1,6 @@
<svg id="vuesax_linear_arrow-left" data-name="vuesax/linear/arrow-left" xmlns="http://www.w3.org/2000/svg" width="33.524" height="33.524" viewBox="0 0 33.524 33.524">
<g id="arrow-left" transform="translate(0 0)">
<path id="Vector" d="M9.914,22.126.807,13.018a2.774,2.774,0,0,1,0-3.911L9.914,0" transform="translate(11.038 5.699)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<path id="Vector-2" data-name="Vector" d="M0,0H33.524V33.524H0Z" transform="translate(33.524 33.524) rotate(180)" fill="none" opacity="0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 587 B

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="37.14" height="37.14" viewBox="0 0 37.14 37.14">
<g id="vuesax_linear_arrow-left" data-name="vuesax/linear/arrow-left" transform="translate(401.14 289.14) rotate(180)">
<g id="arrow-left" transform="translate(364 252)">
<path id="Vector" d="M10.983,24.512.894,14.423a3.073,3.073,0,0,1,0-4.333L10.983,0" transform="translate(12.229 6.314)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
<path id="Vector-2" data-name="Vector" d="M0,0H37.14V37.14H0Z" transform="translate(37.14 37.14) rotate(180)" fill="none" opacity="0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 655 B

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28.755" height="14.605" viewBox="0 0 28.755 14.605">
<path id="Vector" d="M10.983,24.512.894,14.423a3.073,3.073,0,0,1,0-4.333L10.983,0" transform="translate(26.634 1.5) rotate(90)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"/>
</svg>

After

Width:  |  Height:  |  Size: 329 B

@ -0,0 +1,38 @@
import React from "react";
import {
CircularProgressbar,
buildStyles,
CircularProgressbarWithChildren,
} from "react-circular-progressbar";
function CustomCircularProgressbar() {
const percentage = 66;
return (
<>
<div style={{ width: 200, height: 200 }}>
<CircularProgressbar value={percentage} text={`${percentage}%`} />
</div>
<div style={{ width: 200, height: 200, marginTop : 20 }}>
<CircularProgressbarWithChildren
value={80}
styles={buildStyles({
pathColor: "#f00",
trailColor: "transparent",
// strokeLinecap: "butt",
})}
>
<CircularProgressbar
value={70}
styles={buildStyles({
trailColor: "transparent",
// strokeLinecap: "butt",
})}
/>
</CircularProgressbarWithChildren>
</div>
</>
);
}
export default CustomCircularProgressbar;

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

@ -0,0 +1,74 @@
import { useState } from "react";
import copyIcon from "./copy.png";
function Code({ code }) {
const [copied, setCopied] = useState(false);
const [height, setHeight] = useState(350);
const copyToClipboard = () => {
setCopied(true);
let copyText = document.getElementById(code).innerText;
/* Select the text field */
// copyText.setSelectionRange(0, 99999); /* For mobile devices */
/* Copy the text inside the text field */
navigator.clipboard.writeText(copyText);
};
return (
<div className="flex flex-col w-full my-10">
<div className="w-full flex flex-row items-center justify-between">
<div className="flex flex-row items-center">
<img
src={copyIcon}
alt="copy"
className="w-8 h-8 hover:bg-purple-300 p-1 rounded-md ml-2 cursor-pointer"
onClick={() => copyToClipboard()}
/>
<span
className={`transition-all duration-500 text-md font-medium text-green-600 ${
copied ? "opacity-100" : "opacity-0"
}`}
>
Copied!
</span>
</div>
<div
className={`font-bold text-lg cursor-pointer ${
height === 350 ? "text-blue-500" : "text-red-500"
}`}
onClick={() => setHeight(() => (height == 350 ? "auto" : 350))}
>
{height === 350 ? "Read more" : "Close"}
</div>
</div>
<pre
className="bg-gray-900 text-green-200 p-3 rounded-md select-text cursor-pointer relative mt-1 h-72 overflow-y-scroll"
id={code}
style={{ height: height, direction: "ltr" }}
>
{code}
</pre>
</div>
);
}
Code.defaultProps = {
code: `class HelloMessage extends React.Component {
handlePress = () => {
alert('Hello')
}
render() {
return (
<div>
<p>Hello {this.props.name}</p>
<button onClick={this.handlePress}>Say Hello</button>
</div>
);
}
}
ReactDOM.render(
<HelloMessage name="Taylor" />,
mountNode
);`,
};
export default Code;

@ -0,0 +1,11 @@
import React from 'react'
function Counter({}) {
return (
<div>
</div>
)
}
export default Counter

@ -38,14 +38,14 @@ export default function Input(props) {
return (
<div
className={_.join(
["input flex flex-col relative mb-6", langDetector(lang, "fa", "en")],
["input flex flex-col relative my-2", langDetector(lang, "fa", "en")],
" "
)}
>
<label
className={_.join(
[
"absolute top-1/2 transform -translate-y-1/2 text-gray-500 bg-white px-2 text-xs transition-all duration-300",
"absolute top-1/2 transform -translate-y-1/2 text-gray-500 bg-white px-2 text-lg transition-all duration-300",
langDetector(lang, "right-2", "left-2"),
inputStatusHandler(
value,
@ -67,7 +67,7 @@ export default function Input(props) {
inputMode={inputMode}
className={_.join(
[
"flex-1 border rounded-sm outline-none p-2",
"flex-1 border rounded-md outline-none p-2",
inputStatusHandler(
value,
focusToggle,
@ -160,3 +160,12 @@ export default function Input(props) {
</div>
);
}
Input.defaultProps = {
lang : 'fa',
inputMode : 'string',
label : 'label',
status : '',
maxLength : '',
message : '',
}

@ -0,0 +1,9 @@
import { Range } from 'rc-slider';
function RcRange({}) {
return (
<Range />
)
}
export default RcRange;

@ -0,0 +1,32 @@
import React from "react";
import { LineChart, XAxis, Tooltip, CartesianGrid, Line } from "recharts";
function Recharts({ data }) {
return (
<LineChart
width={400}
height={400}
data={data}
margin={{ top: 5, right: 20, left: 10, bottom: 5 }}
>
<XAxis dataKey="name" />
<Tooltip />
<CartesianGrid stroke="#f5f5f5" />
{/* <Line type="monotone" dataKey="uv" stroke="#ff7300" yAxisId={0} /> */}
<Line type="monotone" dataKey="pv" stroke="#387908" yAxisId={1} />
</LineChart>
);
}
export default Recharts;
Recharts.defaultProps = {
data: [
{ name: "", uv: 400, pv: 100, amt: 600 },
{ name: "", uv: 400, pv: 200, amt: 500 },
{ name: "", uv: 400, pv: 300, amt: 400 },
{ name: "", uv: 400, pv: 400, amt: 300 },
{ name: "", uv: 400, pv: 500, amt: 200 },
{ name: "", uv: 400, pv: 600, amt: 100 },
],
};

@ -8,7 +8,7 @@ const langDetector = (lang = 'fa', option1, option2) => {
export default function Search(props) {
return (
<div className="flex items-center justify-center w-full">
<div className="flex items-center justify-center w-full my-2">
<div className="relative text-gray-600 focus-within:text-gray-400 w-full">
<span className={_.join(["absolute inset-y-0 flex items-center pl-2", langDetector(props.lang, "left-0", "right-0")], " ")}>
<button
@ -21,7 +21,7 @@ export default function Search(props) {
<input
type="search"
name="q"
className="w-full py-2 text-sm text-white border rounded-sm pr-5 outline-none focus:ring-1 focus:text-gray-900"
className="w-full py-3 text-sm text-white border rounded-md pr-5 outline-none focus:ring-1 focus:text-gray-900"
placeholder={_.join([langDetector(props.lang , "جستجو...", "Search...")], " ")}
autoComplete="off"
/>

@ -25,20 +25,20 @@ export default function SelectCheckbox(props) {
return (
<div
className={_.join(
["select-search flex flex-col relative", langDetector(lang, "fa", "en")],
["select-search flex flex-col relative my-2 rounded-md", langDetector(lang, "fa", "en")],
" "
)}
>
<div
className={_.join(
["search flex flex-column relative", langDetector(lang, "fa", "en")],
["search flex flex-column relative rounded-md bg-white mb-2 border", langDetector(lang, "fa", "en")],
" "
)}
onClick={() => setToggle(() => !toggle)}
>
<input
type="search"
className="w-full py-3 px-3 text-xs border rounded-sm bg-transparent placeholder-gray-500"
className="w-full py-3 px-3 text-xs bg-transparent placeholder-gray-500"
onChange={(e) => onChangeText(e.target.value)}
placeholder={langDetector(lang, "تنظیمات", "setting")}
disabled
@ -50,7 +50,7 @@ export default function SelectCheckbox(props) {
[
"cursor-pointer w-5 absolute top-1/2 transform -translate-y-1/2 transition-all duration-300",
langDetector(lang, "left-3", "right-3"),
toggle ? '-rotate-180' : '',
toggle ? '' : '-rotate-180',
],
" "
)}
@ -60,7 +60,7 @@ export default function SelectCheckbox(props) {
<div
className={_.join(
[
"select-search__list absolute top-12 left-0 flex flex-col px-5 border rounded-sm w-full bg-white z-20",
"select-search__list absolute top-12 left-0 flex flex-col px-5 border rounded-md w-full bg-white z-20",
toggle ? "select-search__listActive" : "",
"transition",
],

@ -29,7 +29,7 @@ export default function SelectRadio(props) {
<div
className={_.join(
[
"flex flex-col relative",
"flex flex-col relative rounded-md my-2",
langDetector(lang, "fa", "en"),
],
" "
@ -37,14 +37,14 @@ export default function SelectRadio(props) {
>
<div
className={_.join(
["flex flex-col relative", langDetector(lang, "fa", "en")],
["flex flex-col relative bg-white rounded-md border", langDetector(lang, "fa", "en")],
" "
)}
onClick={() => setToggle(() => !toggle)}
>
<input
type="search"
className="py-3 px-3 text-xs border rounded-sm bg-transparent focus:ring-1 outline-none focus:placeholder-blue-500 placeholder-gray-500"
className="py-3 px-3 text-xs rounded-md bg-transparent focus:ring-1 outline-none focus:placeholder-blue-500 placeholder-gray-500"
onChange={(e) => onChangeText(e.target.value)}
placeholder={langDetector(lang, "تنظیمات", "setting")}
disabled
@ -56,7 +56,7 @@ export default function SelectRadio(props) {
[
"w-5 absolute top-1/2 transform -translate-y-1/2 cursor-pointer transition-all duration-300",
langDetector(lang, "left-3", "right-3"),
toggle ? '-rotate-180' : ''
toggle ? '' : '-rotate-180'
],
" "
)}
@ -66,7 +66,7 @@ export default function SelectRadio(props) {
<div
className={_.join(
[
"w-full absolute top-12 left-0 flex flex-col border rounded-sm bg-white z-20",
"w-full absolute top-12 left-0 flex flex-col border rounded-md bg-white z-20",
toggle ? "select-search__listActive" : "",
],
" "

@ -3,11 +3,11 @@ import React from "react";
export default function Col({ data, colLength }) {
const length = data?.length;
return (
<li className="h-full w-40 flex flex-col px-2">
<li className="h-full flex flex-col px-2 w-40 bg-white">
{data?.map((product, i) => (
<>
<li
className="flex items-center text-right w-full cursor-pointer text-md"
className="flex items-center text-right cursor-pointer text-md"
style={{ minHeight: `calc(100% / ${colLength})` }}
>
{product.name}
@ -15,8 +15,8 @@ export default function Col({ data, colLength }) {
{product.list.map((item1, i) => (
<li
key={i}
className="w-full text-normal justify-center cursor-pointer flex items-center text-sm font-normal text-gray-400 hover:bg-blue-50"
style={{ minHeight: "calc(100% / 9)" }}
className="text-normal justify-center cursor-pointer items-center text-sm font-normal text-gray-400 hover:bg-blue-50"
style={{ minHeight: `calc(100% / ${colLength})`, }}
>
{item1.name}
</li>

@ -10,7 +10,7 @@ export default function SidebarCategoryHover() {
return (
<div
className="flex flex-col w-60 relative"
className="flex flex-col w-60 relative my-2 bg-white"
onMouseOut={() => setActiveItem(null)}
>
<ul className="list-none w-full divide-y border divide-gray-200">

@ -104,19 +104,20 @@ export default function List({ activeItem, item, setActiveItem, colLength }) {
<ul
className={_.join(
[
"absolute right-60 top-0 h-full border flex-row",
"absolute right-60 top-0 h-full border flex flex-row justify-between",
activeItem === item.id ? "flex" : "hidden",
],
" "
)}
// style={{minWidth : 'calc(100vw - 260px )'}}
onMouseOver={() => setActiveItem(item.id)}
>
{cols?.col1.length > 0 && <Col data={cols?.col1} colLength={colLength} />}
{cols?.col2.length > 0 && <Col data={cols?.col2} colLength={colLength} />}
{cols?.col3.length > 0 && <Col data={cols?.col3} colLength={colLength} />}
{cols?.col4.length > 0 && <Col data={cols?.col4} colLength={colLength} />}
{cols?.col5.length > 0 && <Col data={cols?.col5} colLength={colLength} />}
{cols?.col6.length > 0 && <Col data={cols?.col6} colLength={colLength} />}
{cols?.col1.length > 0 && <Col data={cols?.col1} colLength={colLength} key={0} />}
{cols?.col2.length > 0 && <Col data={cols?.col2} colLength={colLength} key={1} />}
{cols?.col3.length > 0 && <Col data={cols?.col3} colLength={colLength} key={2} />}
{cols?.col4.length > 0 && <Col data={cols?.col4} colLength={colLength} key={3} />}
{cols?.col5.length > 0 && <Col data={cols?.col5} colLength={colLength} key={4} />}
{cols?.col6.length > 0 && <Col data={cols?.col6} colLength={colLength} key={5} />}
</ul>
);
}

@ -0,0 +1,8 @@
import React from "react";
import Slider from "rc-slider";
function RcSlider({}) {
return <Slider />;
}
export default RcSlider;

@ -0,0 +1,16 @@
import React, { useState } from "react";
import StarRatingComponent from "react-star-rating-component";
function StarRating() {
const [rate, setRating] = useState(2);
return (
<StarRatingComponent
name="rate1"
starCount={5}
value={rate}
onStarHover={(value) => setRating(value)}
/>
);
}
export default StarRating;

@ -0,0 +1,84 @@
import React from "react";
function Stepper({
direction,
activeColor,
deactiveColor,
count,
currentStep,
}) {
const array = Array(count);
return (
<div
className={`flex items-center ${
direction === "horizontal" ? "flex-row" : "flex-col"
}`}
>
{[1,2,3,4,5,6,7].map((item, index) => (
<Step
index={index}
currentStep={currentStep}
direction={direction}
activeColor={activeColor}
deactiveColor={deactiveColor}
count={count}
/>
))}
</div>
);
}
const Step = ({
index,
currentStep,
direction,
activeColor,
deactiveColor,
count,
}) => {
return (
<div
className={`flex items-center relative ${
direction === "horizontal" ? "flex-row" : "flex-col"
}`}
>
<div
className="w-12 h-12 text-white text-sm rounded-full flex justify-center items-center"
style={{
backgroundColor:
currentStep === Number(index) ? activeColor : deactiveColor,
}}
>
{Number(index) + 1}
</div>
{count !== (Number(index) + 1) && (
<span
className={`transform ${
direction === "horizontal"
? "w-10 h-1"
: "h-10 w-1"
}`}
style={{
borderTop: direction === "horizontal" ? `2px dotted ${
currentStep === Number(index) ? activeColor : deactiveColor
}` : '',
borderRight: direction === "vertical" ? `2px dotted ${
currentStep === Number(index) ? activeColor : deactiveColor
}` : '',
transform : `${direction === "horizontal" ? 'translateY(1px)' : 'translateX(-1px)'}`
}}
></span>
)}
</div>
);
};
export default Stepper;
Stepper.defaultProps = {
direction: "vertical",
activeColor: "#06BACE",
deactiveColor: "#DBDBDB",
count: 7,
currentStep : 4,
};

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="10.471" height="10.471" viewBox="0 0 10.471 10.471">
<g id="vuesax_linear_card-remove" data-name="vuesax/linear/card-remove" transform="translate(-252.46 -511.461)">
<g id="card-remove" transform="translate(253.309 512.31)">
<path id="Vector" d="M0,8.774,8.774,0" fill="none" stroke="#707070" stroke-linecap="round" stroke-width="1.2"/>
<path id="Vector-2" data-name="Vector" d="M8.774,8.774,0,0" fill="none" stroke="#707070" stroke-linecap="round" stroke-width="1.2"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 558 B

@ -0,0 +1,25 @@
import React from "react";
import blackCancleIcon from "./black-cancle-icon.svg";
const ProductTags = ({ titleColor,title, tagBgColor, tagBorderColor, icon }) => {
return (
<button
className={`flex flex-row items-center rounded border-2 m-1 px-2 py-0.5 text-base ${titleColor} ${tagBorderColor} ${tagBgColor} `}
>
{title}
{icon && <img src={icon} alt="" className="mr-5 w-2.5" />}
</button>
);
};
export default ProductTags;
ProductTags.defaultProps = {
title : 'کتاب',
titleColor: "text-blue-600",
tagBgColor: "bg-blue-300 bg-opacity-10",
tagBorderColor: "border-blue-200",
// for icons
icon: blackCancleIcon,
};

@ -0,0 +1,11 @@
import React from 'react'
function Toast({}) {
return (
<div>
</div>
)
}
export default Toast

@ -20,7 +20,7 @@ export default function VerticalExpandableProductFilter(props) {
}, [text]);
return (
<div className="flex flex-col w-full border rounded-md pt-6 bg-transparent max-h-screen">
<div className="flex flex-col w-full border rounded-md pt-6 bg-transparent max-h-screen bg-white my-2">
<strong className="text-md text-gray-500 w-full mb-3 text-right px-3">
دسته بندی
</strong>
@ -31,7 +31,7 @@ export default function VerticalExpandableProductFilter(props) {
[langDetector(props.lang, "جستجو...", "Search...")],
" "
)}
className="border rounded-sm py-1 px-2 w-full placeholder-gray-300 outline-none text-gray-500"
className="border rounded-md py-1 px-2 w-full placeholder-gray-300 outline-none text-gray-500"
onChange={(e) => setText(e.target.value)}
/>
<span

@ -18,13 +18,13 @@ export default function PopularSearch(props) {
return (
<div
className={_.join(
["flex flex-col relative search", langDetector(lang, "fa", "en")],
["flex flex-col relative search my-2", langDetector(lang, "fa", "en")],
" "
)}
>
<input
type="search"
className="transition py-2 pr-4 pl-2 mx-0 border rounded-sm outline-none focus:ring-1 placeholder-gray-500 placeholder-opacity-40 focus:placeholder-blue-300"
className="transition py-2 pr-4 pl-2 mx-0 border rounded-md outline-none focus:ring-1 placeholder-gray-500 placeholder-opacity-40 focus:placeholder-blue-300"
onChange={(e) => onChange(e.target.value)}
value={value}
placeholder={langDetector(
@ -53,7 +53,7 @@ export default function PopularSearch(props) {
<div
className={_.join(
[
"search__populars w-full mt-0 border rounded-sm top-12 left-0 absolute z-10 px-4 bg-white",
"search__populars w-full mt-0 border rounded-md top-12 left-0 absolute z-10 px-4 bg-white",
popularsToggle ? "flex flex-col" : "hidden",
"transition",
],

@ -0,0 +1,12 @@
const components = {
list:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "components/list", data }),
activeComponent:
(data = {}) =>
async (dispatch) =>
await dispatch({ type: "components/activeComponent", data }),
};
export default components;

@ -0,0 +1 @@
export { default as components} from './components';

@ -0,0 +1,450 @@
import Button from '../components/Button';
import Tag from '../components/Tag';
import Counter from '../components/Counter';
import Input from "../components/Input";
import Search from "../components/Search";
import SearchWidthSuggest from "../components/search-with-suggest";
import Radio from "../components/Radio";
import Checkbox from "../components/Checkbox";
import SelectRadio from "../components/SelectRadio";
import SelectCheckbox from "../components/SelectCheckbox";
import Switch from "../components/Switch";
import VerticalExpandableProductFilter from "../components/VerticalExpandableProductFilter";
import SidebarCategoryHover from "../components/SidebarCategoryHover";
import Slider from '../components/Slider';
import Range from "../components/Range";
import Alert from "../components/Alert";
import Toast from "../components/Toast";
import StarRating from '../components/StarRating';
import Chart from "../components/Recharts";
import CircularProgressbar from "../components/CircularProgressbar";
import Stepper from "../components/Stepper";
const components = [
{
name : "Button",
props : [
],
content : {
name : "Button",
component : <Button buttonBgColor="bg-blue-500" />,
code : null,
}
},
{
name : "Tag",
props : [
],
content : {
name : "Tag",
component : <Tag />,
code : null,
}
},
{
name: "Input",
props: [
{
name: "maxLength",
type: "string",
required: "false",
description: "بیشترین تعداد کاراکتری که میتوان استفاده کرد.",
defaultValue: "",
},
{
name: "lang",
type: "string",
required: "false",
description: "زبان سایت",
defaultValue: "fa",
},
{
name: "inputMode",
type: "string",
required: "false",
description: "با تعیین این مقدار نوع کیبرد مشخص میشود.",
defaultValue: "text",
},
{
name: "label",
type: "string",
required: "false",
description: "",
defaultValue: "label",
},
],
content: {
name: "Input",
component: <Input />,
code: `import React, { useState } from "react";
import _ from "lodash";
import "./index.scss";
import tick from "./tick.png";
import danger from "./danger.png";
const langDetector = (lang, option1, option2) => {
return lang === "fa" ? option1 : option2;
};
const inputStatusHandler = (value, focus, status, primary, success, danger) => {
if (!focus) {
return "";
} else {
if (!value) {
return primary;
} else {
if (status) {
return success;
} else {
return danger;
}
}
}
};
export default function Input(props) {
const [value, setValue] = useState("");
const [focusToggle, setFocusToggle] = useState(false);
const { lang, theme, inputMode, label, status, maxLength, message } = props;
const onChange = (val) => {
setValue(val);
};
return (
<div
className={_.join(
["input flex flex-col relative my-2", langDetector(lang, "fa", "en")],
" "
)}
>
<label
className={_.join(
[
"absolute top-1/2 transform -translate-y-1/2 text-gray-500 bg-white px-2 text-xs transition-all duration-300",
langDetector(lang, "right-2", "left-2"),
inputStatusHandler(
value,
focusToggle,
status,
"input__labelFocus",
"input__labelSuccess",
"input__labelDanger"
),
],
" "
)}
onClick={() => setFocusToggle(true)}
>
{label}
</label>
<input
type="text"
inputMode={inputMode}
className={_.join(
[
"flex-1 border rounded-md outline-none p-2",
inputStatusHandler(
value,
focusToggle,
status,
"input__inputActive",
"input__inputSuccess",
"input__inputDanger"
),
"transition",
],
" "
)}
onChange={(e) => onChange(e.target.value)}
value={value}
onFocus={() => setFocusToggle(true)}
onBlur={() => !value ? setFocusToggle(false) : setFocusToggle(true)}
maxLength={maxLength}
/>
{!status && value && (
<img
src={danger}
alt={langDetector(lang, "اشتباه", "wrong")}
className={_.join(
[
"w-4 h-4 absolute top-1/2 transform -translate-y-1/2",
langDetector(lang, "left-2", "right-2"),
],
" "
)}
/>
)}
{status && value && (
<img
src={tick}
alt={langDetector(lang, "درست", "right")}
className={_.join(
[
"w-4 h-4 absolute top-1/2 transform -translate-y-1/2",
langDetector(lang, "left-2", "right-2"),
],
" "
)}
/>
)}
{value && !status && (
<span
className={_.join(
[
"input__message text-xs absolute -bottom-5",
langDetector(lang, "right-2", "left-2"),
inputStatusHandler(
value,
focusToggle,
status,
"",
"input__messageSuccess",
"input__messageDanger"
),
"transition",
],
" "
)}
>
{message}
</span>
)}
{value && (
<span
className={_.join(
[
"input__length absolute -bottom-5 text-xs",
langDetector(lang, "left-2", "right-2"),
inputStatusHandler(
value,
focusToggle,
status,
"",
"input__lengthSuccess",
"input__lengthDanger"
),
"transition",
],
" "
)}
>
{value.length + "/" + maxLength}
</span>
)}
</div>
);
}
Input.defaultProps = {
lang : 'fa',
inputMode : 'string',
label : '',
status : '',
maxLength : '',
message : '',
}`,
},
},
{
name: "Search",
props: [],
content: {
name: "Search",
component: <Search />,
code: null,
},
},
{
name: "Search with suggestion",
props: [],
content: {
name: "Search with suggestion",
component: <SearchWidthSuggest />,
code: null,
},
},
{
name : "Radio",
props : [
],
content : {
name : "Radio",
component : <Radio />,
code : null,
}
},
{
name : "Checkbox",
props : [
],
content : {
name : "Checkbox",
component : <Checkbox />,
code : null,
}
},
{
name : "Select box - Radio",
props : [
],
content : {
name : "Select box - Radio",
component : <SelectRadio />,
code : null,
}
},
{
name : "Select box - Checkbox",
props : [
],
content : {
name : "Select box - Checkbox",
component : <SelectCheckbox />,
code : null,
}
},
{
name : "Switch",
props : [
],
content : {
name : "Switch",
component : <Switch />,
code : null,
}
},
{
name : "Expandable products filter",
props : [
],
content : {
name : "Expandable products filter",
component : <VerticalExpandableProductFilter />,
code : null,
}
},
{
name : "Sidebar catergory",
props : [
],
content : {
name : "Sidebar category",
component : <SidebarCategoryHover />,
code : null,
}
},
{
name : "Slider",
props : [
],
content : {
name : "Slider",
component : <Slider />,
code : null,
}
},
{
name : "Range",
props : [
],
content : {
name : "Range",
component : <Range />,
code : null,
}
},
{
name : "Counter",
props : [
],
content : {
name : "Counter",
component : <Counter />,
code : null,
}
},
{
name : "Alert",
props : [
],
content : {
name : "Alert",
component : <Alert />,
code : null,
}
},
{
name : "Toast",
props : [
],
content : {
name : "Toast",
component : <Toast />,
code : null,
}
},
{
name : "Star rating",
props : [
],
content : {
name : "Star rating",
component : <StarRating />,
code : null,
}
},
{
name : "Chart",
props : [
],
content : {
name : "Chart",
component : <Chart />,
code : null,
}
},
{
name : "Circular progressbar",
props : [
],
content : {
name : "Circular progressbar",
component : <CircularProgressbar />,
code : null,
}
},
{
name : "Stepper",
props : [
],
content : {
name : "Stepper",
component : <Stepper />,
code : null,
}
},
];
export default components;

@ -0,0 +1,6 @@
// @create-index
export { default as actions } from './actions';
export { default as reducers } from './reducers';
export { default as store } from './store.js';

@ -0,0 +1,16 @@
import data from '../data';
const initialState = {
list: data,
activeComponent : {},
};
export default function components(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "components/list":
return { ...state, list : data };
case "components/activeComponent":
return {...state, activeComponent : data}
default:
return state;
}
}

@ -0,0 +1 @@
export { default as components} from './components';

@ -0,0 +1,14 @@
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import { combineReducers } from 'redux';
import * as reducers from './reducers';
import thunk from 'redux-thunk';
const initialState = {};
const middleware = [thunk];
const store = createStore(
combineReducers(reducers),
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;

@ -0,0 +1,45 @@
import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import _ from "lodash";
import Home from './Views/Home';
// import VideoTube from "./views/Home/VideoTube";
function Router({ isDark }) {
return (
<div className={_.join([isDark ? "dark" : ""], " ")}>
<div
className={_.join(
[
"min-h-screen min-w-screen rtl overflow-x-hidden",
isDark ? "bg-dark" : "bg-white",
],
" "
)}
>
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
{/* <Route path="/vod" element={<VideoTube />} /> */}
<Route
path="*"
element={
<main>
<h1>No matches routes.</h1>
</main>
}
/>
</Routes>
</BrowserRouter>
</div>
</div>
);
}
Router.defaultProps = {
isDark : false,
}
export default Router;

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save