UNPKG

@themesberg/volt-react-dashboard

Version:

Volt React Dashboard is a free and open source admin dashboard template powered by React.js and Bootstrap 5

402 lines (372 loc) 15.2 kB
import React from "react"; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faAngleDown, faAngleUp, faChartArea, faChartBar, faChartLine, faFlagUsa, faFolderOpen, faGlobeEurope, faPaperclip, faUserPlus } from '@fortawesome/free-solid-svg-icons'; import { faAngular, faBootstrap, faReact, faVuejs } from "@fortawesome/free-brands-svg-icons"; import { Col, Row, Card, Image, Button, ListGroup, ProgressBar } from '@themesberg/react-bootstrap'; import { CircleChart, BarChart, SalesValueChart, SalesValueChartphone } from "./Charts"; import Profile1 from "../assets/img/team/profile-picture-1.jpg"; import ProfileCover from "../assets/img/profile-cover.jpg"; import teamMembers from "../data/teamMembers"; export const ProfileCardWidget = () => { return ( <Card border="light" className="text-center p-0 mb-4"> <div style={{ backgroundImage: `url(${ProfileCover})` }} className="profile-cover rounded-top" /> <Card.Body className="pb-5"> <Card.Img src={Profile1} alt="Neil Portrait" className="user-avatar large-avatar rounded-circle mx-auto mt-n7 mb-4" /> <Card.Title>Neil Sims</Card.Title> <Card.Subtitle className="fw-normal">Senior Software Engineer</Card.Subtitle> <Card.Text className="text-gray mb-4">New York, USA</Card.Text> <Button variant="primary" size="sm" className="me-2"> <FontAwesomeIcon icon={faUserPlus} className="me-1" /> Connect </Button> <Button variant="secondary" size="sm">Send Message</Button> </Card.Body> </Card> ); }; export const ChoosePhotoWidget = (props) => { const { title, photo } = props; return ( <Card border="light" className="bg-white shadow-sm mb-4"> <Card.Body> <h5 className="mb-4">{title}</h5> <div className="d-xl-flex align-items-center"> <div className="user-avatar xl-avatar"> <Image fluid rounded src={photo} /> </div> <div className="file-field"> <div className="d-flex justify-content-xl-center ms-xl-3"> <div className="d-flex"> <span className="icon icon-md"> <FontAwesomeIcon icon={faPaperclip} className="me-3" /> </span> <input type="file" /> <div className="d-md-block text-start"> <div className="fw-normal text-dark mb-1">Choose Image</div> <div className="text-gray small">JPG, GIF or PNG. Max size of 800K</div> </div> </div> </div> </div> </div> </Card.Body> </Card> ); }; export const CounterWidget = (props) => { const { icon, iconColor, category, title, period, percentage } = props; const percentageIcon = percentage < 0 ? faAngleDown : faAngleUp; const percentageColor = percentage < 0 ? "text-danger" : "text-success"; return ( <Card border="light" className="shadow-sm"> <Card.Body> <Row className="d-block d-xl-flex align-items-center"> <Col xl={5} className="text-xl-center d-flex align-items-center justify-content-xl-center mb-3 mb-xl-0"> <div className={`icon icon-shape icon-md icon-${iconColor} rounded me-4 me-sm-0`}> <FontAwesomeIcon icon={icon} /> </div> <div className="d-sm-none"> <h5>{category}</h5> <h3 className="mb-1">{title}</h3> </div> </Col> <Col xs={12} xl={7} className="px-xl-0"> <div className="d-none d-sm-block"> <h5>{category}</h5> <h3 className="mb-1">{title}</h3> </div> <small>{period}, <FontAwesomeIcon icon={faGlobeEurope} size="xs" /> WorldWide</small> <div className="small mt-2"> <FontAwesomeIcon icon={percentageIcon} className={`${percentageColor} me-1`} /> <span className={`${percentageColor} fw-bold`}> {percentage}% </span> Since last month </div> </Col> </Row> </Card.Body> </Card> ); }; export const CircleChartWidget = (props) => { const { title, data = [] } = props; const series = data.map(d => d.value); return ( <Card border="light" className="shadow-sm"> <Card.Body> <Row className="d-block d-xl-flex align-items-center"> <Col xs={12} xl={5} className="text-xl-center d-flex align-items-center justify-content-xl-center mb-3 mb-xl-0"> <CircleChart series={series} /> </Col> <Col xs={12} xl={7} className="px-xl-0"> <h5 className="mb-3">{title}</h5> {data.map(d => ( <h6 key={`circle-element-${d.id}`} className="fw-normal text-gray"> <FontAwesomeIcon icon={d.icon} className={`icon icon-xs text-${d.color} w-20 me-1`} /> {` ${d.label} `}{`${d.value}%`} </h6> ))} </Col> </Row> </Card.Body> </Card> ); }; export const BarChartWidget = (props) => { const { title, value, percentage, data = [] } = props; const labels = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; const series = data.map(d => d.value); const percentageIcon = percentage < 0 ? faAngleDown : faAngleUp; const percentageColor = percentage < 0 ? "text-danger" : "text-success"; return ( <Card border="light" className="shadow-sm"> <Card.Body className="d-flex flex-row align-items-center flex-0 border-bottom"> <div className="d-block"> <h6 className="fw-normal text-gray mb-2">{title}</h6> <h3>{value}</h3> <small className="mt-2"> <FontAwesomeIcon icon={percentageIcon} className={`${percentageColor} me-1`} /> <span className={`${percentageColor} fw-bold`}> {percentage}% </span> </small> </div> <div className="d-block ms-auto"> {data.map(d => ( <div key={`bar-element-${d.id}`} className="d-flex align-items-center text-end mb-2"> <span className={`shape-xs rounded-circle bg-${d.color} me-2`} /> <small className="fw-normal">{d.label}</small> </div> ))} </div> </Card.Body> <Card.Body className="p-2"> <BarChart labels={labels} series={series} /> </Card.Body> </Card> ); }; export const TeamMembersWidget = () => { const TeamMember = (props) => { const { name, statusKey, image, icon, btnText } = props; const status = { online: { color: "success", label: "Online" }, inMeeting: { color: "warning", label: "In a meeting" }, offline: { color: "danger", label: "Offline" } }; const statusColor = status[statusKey] ? status[statusKey].color : 'danger' , statusLabel = status[statusKey] ? status[statusKey].label : 'Offline'; return ( <ListGroup.Item className="px-0"> <Row className="align-items-center"> <Col className="col-auto"> <a href="#top" className="user-avatar"> <Image src={image} className="rounded-circle" /> </a> </Col> <Col className="ms--2"> <h4 className="h6 mb-0"> <a href="#!">{name}</a> </h4> <span className={`text-${statusColor}`}></span> <small>{statusLabel}</small> </Col> <Col className="col-auto"> <Button variant="tertiary" size="sm"> <FontAwesomeIcon icon={icon} className="me-1" /> {btnText} </Button> </Col> </Row> </ListGroup.Item> ); }; return ( <Card border="light" className="shadow-sm"> <Card.Header className="border-bottom border-light d-flex justify-content-between"> <h5 className="mb-0">Team members</h5> <Button variant="secondary" size="sm">See all</Button> </Card.Header> <Card.Body> <ListGroup className="list-group-flush list my--3"> {teamMembers.map(tm => <TeamMember key={`team-member-${tm.id}`} {...tm} />)} </ListGroup> </Card.Body> </Card> ); }; export const ProgressTrackWidget = () => { const Progress = (props) => { const { title, percentage, icon, color, last = false } = props; const extraClassName = last ? "" : "mb-2"; return ( <Row className={`align-items-center ${extraClassName}`}> <Col xs="auto"> <span className={`icon icon-md text-${color}`}> <FontAwesomeIcon icon={icon} className="me-1" /> </span> </Col> <Col> <div className="progress-wrapper"> <div className="progress-info"> <h6 className="mb-0">{title}</h6> <small className="fw-bold text-dark"> <span>{percentage} %</span> </small> </div> <ProgressBar variant={color} now={percentage} min={0} max={100} /> </div> </Col> </Row> ); }; return ( <Card border="light" className="shadow-sm"> <Card.Header className="border-bottom border-light"> <h5 className="mb-0">Progress track</h5> </Card.Header> <Card.Body> <Progress title="Rocket - SaaS Template" color="purple" icon={faBootstrap} percentage={34} /> <Progress title="Pixel - Design System" color="danger" icon={faAngular} percentage={60} /> <Progress title="Spaces - Listings Template" color="tertiary" icon={faVuejs} percentage={45} /> <Progress title="Stellar - Dashboard" color="info" icon={faReact} percentage={35} /> <Progress last title="Volt - Dashboard" color="purple" icon={faBootstrap} percentage={34} /> </Card.Body> </Card> ); }; export const RankingWidget = () => { return ( <Card border="light" className="shadow-sm"> <Card.Body> <div className="d-flex align-items-center justify-content-between border-bottom border-light pb-3"> <div> <h6><FontAwesomeIcon icon={faGlobeEurope} className="icon icon-xs me-3" /> Global Rank</h6> </div> <div> <Card.Link href="#" className="text-primary fw-bold"> #755 <FontAwesomeIcon icon={faChartLine} className="ms-2" /> </Card.Link> </div> </div> <div className="d-flex align-items-center justify-content-between border-bottom border-light py-3"> <div> <h6 className="mb-0"><FontAwesomeIcon icon={faFlagUsa} className="icon icon-xs me-3" />Country Rank</h6> <div className="small card-stats"> United States <FontAwesomeIcon icon={faAngleUp} className="icon icon-xs text-success ms-2" /> </div> </div> <div> <Card.Link href="#top" className="text-primary fw-bold"> #32 <FontAwesomeIcon icon={faChartLine} className="ms-2" /> </Card.Link> </div> </div> <div className="d-flex align-items-center justify-content-between pt-3"> <div> <h6 className="mb-0"><FontAwesomeIcon icon={faFolderOpen} className="icon icon-xs me-3" />Category Rank</h6> <Card.Link href="#top" className="small card-stats"> Travel &gt; Accomodation </Card.Link> </div> <div> <Card.Link href="#top" className="text-primary fw-bold"> #16 <FontAwesomeIcon icon={faChartLine} className="ms-2" /> </Card.Link> </div> </div> </Card.Body> </Card> ); }; export const SalesValueWidget = (props) => { const { title, value, percentage } = props; const percentageIcon = percentage < 0 ? faAngleDown : faAngleUp; const percentageColor = percentage < 0 ? "text-danger" : "text-success"; return ( <Card className="bg-secondary-alt shadow-sm"> <Card.Header className="d-flex flex-row align-items-center flex-0"> <div className="d-block"> <h5 className="fw-normal mb-2"> {title} </h5> <h3>${value}</h3> <small className="fw-bold mt-2"> <span className="me-2">Yesterday</span> <FontAwesomeIcon icon={percentageIcon} className={`${percentageColor} me-1`} /> <span className={percentageColor}> {percentage}% </span> </small> </div> <div className="d-flex ms-auto"> <Button variant="secondary" size="sm" className="me-2">Month</Button> <Button variant="primary" size="sm" className="me-3">Week</Button> </div> </Card.Header> <Card.Body className="p-2"> <SalesValueChart /> </Card.Body> </Card> ); }; export const SalesValueWidgetPhone = (props) => { const { title, value, percentage } = props; const percentageIcon = percentage < 0 ? faAngleDown : faAngleUp; const percentageColor = percentage < 0 ? "text-danger" : "text-success"; return ( <Card className="bg-secondary-alt shadow-sm"> <Card.Header className="d-md-flex flex-row align-items-center flex-0"> <div className="d-block mb-3 mb-md-0"> <h5 className="fw-normal mb-2"> {title} </h5> <h3>${value}</h3> <small className="fw-bold mt-2"> <span className="me-2">Yesterday</span> <FontAwesomeIcon icon={percentageIcon} className={`${percentageColor} me-1`} /> <span className={percentageColor}> {percentage}% </span> </small> </div> <div className="d-flex ms-auto"> <Button variant="secondary" size="sm" className="me-2">Month</Button> <Button variant="primary" size="sm" className="me-3">Week</Button> </div> </Card.Header> <Card.Body className="p-2"> <SalesValueChartphone /> </Card.Body> </Card> ); }; export const AcquisitionWidget = () => { return ( <Card border="light" className="shadow-sm"> <Card.Body> <h5>Acquisition</h5> <p>Tells you where your visitors originated from, such as search engines, social networks or website referrals.</p> <div className="d-block"> <div className="d-flex align-items-center pt-3 me-5"> <div className="icon icon-shape icon-sm icon-shape-danger rounded me-3"> <FontAwesomeIcon icon={faChartBar} /> </div> <div className="d-block"> <label className="mb-0">Bounce Rate</label> <h4 className="mb-0">33.50%</h4> </div> </div> <div className="d-flex align-items-center pt-3"> <div className="icon icon-shape icon-sm icon-shape-quaternary rounded me-3"> <FontAwesomeIcon icon={faChartArea} /> </div> <div className="d-block"> <label className="mb-0">Sessions</label> <h4 className="mb-0">9,567</h4> </div> </div> </div> </Card.Body> </Card> ); };