@ -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); |
||||
} |
||||
} |
@ -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; |
After Width: | Height: | Size: 658 B |
After Width: | Height: | Size: 642 B |
After Width: | Height: | Size: 658 B |
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, |
||||
}; |
After Width: | Height: | Size: 343 B |
After Width: | Height: | Size: 587 B |
After Width: | Height: | Size: 655 B |
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; |
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 |
@ -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 }, |
||||
], |
||||
}; |
@ -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, |
||||
}; |
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 |
@ -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; |