reza added blogs and blog

master
RezaAshrafi77 3 years ago
parent ed1bd15f99
commit d481fdd9da
  1. 11
      src/AppRouter.js
  2. 4
      src/Redux/actions/public.js
  3. 6
      src/Redux/reducers/public.js
  4. 57
      src/views/Blog/BreadCrumb/index.js
  5. 8
      src/views/Blog/BreadCrumb/index.scss
  6. 143
      src/views/Blog/index.js
  7. 129
      src/views/Blog/index.scss
  8. 46
      src/views/Blogs/BreadCrumb/index.js
  9. 8
      src/views/Blogs/BreadCrumb/index.scss
  10. 94
      src/views/Blogs/index.js
  11. 89
      src/views/Blogs/index.scss
  12. 13
      src/views/QR/VideoBox/React-video-js-player/index.js
  13. 7
      src/views/QR/VoiceBox/Material-audio-player/index.js
  14. 13
      src/views/QR/VoiceBox/index.js

@ -28,6 +28,8 @@ import AR from "./views/AR/index";
import Support from "./views/Support/index"; import Support from "./views/Support/index";
import Callback from "./views/Callback/index"; import Callback from "./views/Callback/index";
import NewProfile from "./views/NewProfile/index"; import NewProfile from "./views/NewProfile/index";
import Blogs from "./views/Blogs/index";
import Blog from "./views/Blog/index";
class AppRouter extends Component { class AppRouter extends Component {
constructor(props) { constructor(props) {
@ -62,7 +64,7 @@ class AppRouter extends Component {
{home} {home}
<Route exact path={"/faq"}> <Route exact path={"/faq"}>
{mobile ? ( {mobile ? (
window.innerWiproxy.status() ? ( proxy.status() ? (
<Faq /> <Faq />
) : ( ) : (
<Redirect <Redirect
@ -93,6 +95,12 @@ class AppRouter extends Component {
<Route exact path={"/callback"}> <Route exact path={"/callback"}>
<Callback /> <Callback />
</Route> </Route>
<Route exact path={"/blogs"}>
<Blogs />
</Route>
<Route exact path={"/blogs/:id"}>
<Blog />
</Route>
<Route exact path={"/about"}> <Route exact path={"/about"}>
<About /> <About />
</Route> </Route>
@ -123,7 +131,6 @@ class AppRouter extends Component {
<Route exact path={"/qr-scan"}> <Route exact path={"/qr-scan"}>
<QRScan /> <QRScan />
</Route> </Route>
<Route exact path={"/activation"}> <Route exact path={"/activation"}>
<Activation /> <Activation />
</Route> </Route>

@ -14,6 +14,10 @@ const publicApi = {
await proxy.get("public/contact", data, { history, dispatch }), await proxy.get("public/contact", data, { history, dispatch }),
getArList: (data, history) => async (dispatch) => getArList: (data, history) => async (dispatch) =>
await proxy.get("public/ar", data, { history, dispatch }), await proxy.get("public/ar", data, { history, dispatch }),
getBlogList: (data, history) => async (dispatch) =>
await proxy.get("public/blogList", data, { history, dispatch }),
getBlogInfo: (data, history) => async (dispatch) =>
await proxy.get("public/blogInfo", data, { history, dispatch }),
}; };
export default publicApi; export default publicApi;

@ -6,6 +6,8 @@ const initialState = {
searchResult: [], searchResult: [],
contactData: null, contactData: null,
arList: [], arList: [],
blogList: [],
blog: null,
}; };
export default function publicApi(state = initialState, action) { export default function publicApi(state = initialState, action) {
let { type, data } = action; let { type, data } = action;
@ -41,6 +43,10 @@ export default function publicApi(state = initialState, action) {
return { ...state, loading: false, error: null, contactData: data }; return { ...state, loading: false, error: null, contactData: data };
case "public/ar": case "public/ar":
return { ...state, loading: false, error: null, arList: data }; return { ...state, loading: false, error: null, arList: data };
case "public/blogList":
return { ...state, loading: false, error: null, blogList: data };
case "public/blogInfo":
return { ...state, loading: false, error: null, blog: data };
case "loading": case "loading":
return { ...state, loading: true }; return { ...state, loading: true };
case "error": case "error":

@ -0,0 +1,57 @@
import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import { Link } from "react-router-dom";
import "./index.scss";
function handleClick(event) {
event.preventDefault();
console.info("You clicked a breadcrumb.");
}
const maxDesktopSize = 1250;
const maxMobileSize = 650;
const fontSize = {
desktop: window.innerWidth > maxDesktopSize ? 12 : window.innerWidth / 90,
mobile: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 25,
};
export default function ActiveLastBreadcrumb(props) {
const { name } = props;
return (
<Breadcrumbs aria-label="breadcrumb">
<Link
style={{
fontSize:
window.innerWidth > 1000 ? fontSize.desktop : fontSize.mobile,
}}
to={"/"}
>
صفحه اصلی
</Link>
<Link
style={{
fontSize:
window.innerWidth > 1000 ? fontSize.desktop : fontSize.mobile,
}}
to={"/blogs"}
>
وبلاگ
</Link>
<Link
style={{
fontSize:
window.innerWidth > 1000 ? fontSize.desktop : fontSize.mobile,
color: "#00CC69",
}}
to={`/blogs/${window.location.pathname.slice(
window.location.pathname.lastIndexOf("/") + 1,
window.location.pathname.length
)}`}
>
{name}
</Link>
</Breadcrumbs>
);
}

@ -0,0 +1,8 @@
.MuiBreadcrumbs-li{
a {
text-decoration: none;
font-family: numeralLight;
color: #6F7074;
letter-spacing: -1px;
}
}

@ -0,0 +1,143 @@
import React, { Component, Fragment } from "react";
import Loader from "~/components/Loader/index";
import Footer from "../Home/Footer/index";
import Navbar from "../Home/Navbar/index";
import BreadCrumb from "./BreadCrumb/index";
import Image from "../QR/Image/index";
import VideoBox from "../QR/VideoBox/index";
import VoiceBox from "../QR/VoiceBox/index";
import { connect } from "react-redux";
import { publicApi } from "~/Redux/actions";
import "./index.scss";
const maxDesktopSize = 1250;
class Blog extends Component {
componentDidMount() {
this.props.getBlogInfo({
id: window.location.pathname.slice(
window.location.pathname.lastIndexOf("/") + 1,
window.location.pathname.length
),
});
}
render() {
const fontSize = {
desktop: {
sidebar: {
h1: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 95,
h2: window.innerWidth > maxDesktopSize ? 12 : window.innerWidth / 120,
div:
window.innerWidth > maxDesktopSize ? 12 : window.innerWidth / 120,
},
content: {
h1: window.innerWidth > maxDesktopSize ? 18 : window.innerWidth / 75,
p: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 90,
h2: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 90,
},
},
};
const { blog } = this.props;
return (
<>
{window.innerWidth > 1000 ? (
<>
{blog ? (
<div className="landscape-blog d-flex flex-column">
<Navbar />
<div className="landscape-blog__header d-flex flex-column">
<BreadCrumb name={blog.title} />
<div className="landscape-blog__header--top d-flex">
<h1>{blog.title}</h1>
</div>
<div className="landscape-blog__header--bottom d-flex">
<h2></h2>
<div>{blog.date}</div>
</div>
</div>
<div className="landscape-blog__body d-flex flex-column">
<div className="landscape-blog__body--image d-flex">
<Identifier data={blog} fontSize={fontSize} />
</div>
<p className="landscape-blog__body--text d-flex">
{blog.text}
</p>
</div>
</div>
) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div>
)}
<Footer />
</>
) : null}
{window.innerWidth < 1000 ? (
blog ? (
<div className="portrait-blog d-flex flex-column">
<Navbar />
<div className="portrait-blog__header d-flex flex-column">
<BreadCrumb name={blog.title} />
<div className="portrait-blog__header--top d-flex">
<h1>{blog.title}</h1>
</div>
<div className="portrait-blog__header--bottom d-flex">
<h2>{blog.subTitle}</h2>
<div>{blog.date}</div>
</div>
</div>
<div className="portrait-blog__body d-flex flex-column">
<div className="portrait-blog__body--image d-flex">
<Identifier data={blog} />
</div>
<p className="portrait-blog__body--text d-flex">{blog.text}</p>
</div>
</div>
) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div>
)
) : null}
</>
);
}
}
export default connect(
(state) => ({
blog: state.publicApi.blog,
}),
{ getBlogInfo: publicApi.getBlogInfo }
)(Blog);
const Identifier = (props) => {
const { data } = props;
console.log(data);
return (
<>
{data.type === "audio" ? (
<VoiceBox fontSize={props.fontSize} data={data} />
) : null}
{data.type === "video" ? (
<VideoBox fontSize={props.fontSize} data={data} />
) : null}
{data.type === "image" ? (
<img
src={"https://dnvn.ir/api/v1/file/" + data.fileIds}
alt={data.fileIds}
/>
) : null}
</>
);
};

@ -0,0 +1,129 @@
.portrait-blog {
width: 100vw;
// height: 100vh;
padding: 0px 10px;
position: relative;
&__header {
direction: rtl;
width: 100%;
margin-top: 80px;
&--top {
width: 100%;
text-align: right;
align-items: center;
margin-top: 20px;
h1 {
font-size: 24px;
// color : $dusk;
margin-bottom: 10px;
letter-spacing: -2px;
}
}
&--bottom {
align-items: center;
direction: rtl;
width: 100%;
justify-content: space-between;
h2 {
font-size: 14px;
// color : $dusk;
margin-bottom: 5px;
letter-spacing: -1px;
}
& div {
font-size: 14px;
// color : $dusk;
margin-bottom: 0px;
letter-spacing: -1px;
font-family: IRANSansNumeral;
}
}
}
&__body {
width: 100%;
margin-top: 15px;
&--image {
width: 100%;
& img {
width: 100%;
height: 100%;
border-radius: 10px;
}
}
&--text {
margin-top: 10px;
width: 100%;
direction: rtl;
text-align: justify !important;
// color: $dusk;
color: #4e4e4e;
font-size: 14px;
letter-spacing: -1px;
font-family: numeralLight;
}
}
}
.landscape-blog {
width: 100vw;
padding: 0px 10px;
position: relative;
text-align: right;
max-width: 1250px;
margin: 0px auto;
&__header {
direction: rtl;
width: 100%;
margin-top: 100px;
max-width: 800px;
&--top {
width: 100%;
text-align: right;
align-items: center;
margin-top: 20px;
h1 {
font-size: 28px;
// color : $dusk;
margin-bottom: 10px;
letter-spacing: -1px;
}
}
&--bottom {
align-items: center;
direction: rtl;
width: 100%;
justify-content: space-between;
h2 {
font-size: 14px;
// color : $dusk;
margin-bottom: 5px;
letter-spacing: -1px;
}
& div {
font-size: 16px;
// color : $dusk;
margin-bottom: 5px;
letter-spacing: -1px;
font-family: IRANSansNumeral;
}
}
}
&__body {
width: 100%;
&--image {
width: 100%;
max-height: 300px;
}
&--text {
margin-top: 40px;
width: 100%;
direction: rtl;
text-align: justify;
// color: $dusk;
color: #4e4e4e;
font-size: 18px;
letter-spacing: -1px;
font-family: numeralLight;
}
}
}

@ -0,0 +1,46 @@
import React from "react";
import Breadcrumbs from "@material-ui/core/Breadcrumbs";
import { Link } from "react-router-dom";
import "./index.scss";
function handleClick(event) {
event.preventDefault();
console.info("You clicked a breadcrumb.");
}
const maxDesktopSize = 1250;
const maxMobileSize = 650;
const fontSize = {
desktop: window.innerWidth > maxDesktopSize ? 12 : window.innerWidth / 90,
mobile: window.innerWidth > maxDesktopSize ? 14 : window.innerWidth / 25,
};
export default function ActiveLastBreadcrumb() {
return (
<Breadcrumbs aria-label="breadcrumb">
<Link
to={"/"}
style={{
fontSize:
window.innerWidth > 1000 ? fontSize.desktop : fontSize.mobile,
}}
// onClick={handleClick}
>
صفحه اصلی
</Link>
<Link
to={"/blogs"}
style={{
fontSize:
window.innerWidth > 1000 ? fontSize.desktop : fontSize.mobile,
color: "#00CC69",
}}
// onClick={handleClick}
>
وبلاگ
</Link>
</Breadcrumbs>
);
}

@ -0,0 +1,8 @@
.MuiBreadcrumbs-li{
a {
text-decoration: none;
font-family: numeralLight;
color: #6F7074;
letter-spacing: -1px;
}
}

@ -1,40 +1,67 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { Link } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi } from "~/Redux/actions";
import Navbar from "../Home/Navbar";
import Footer from "../Home/Footer";
import BreadCrumb from "./BreadCrumb/index";
import Loader from "~/components/Loader/index";
import "./index.scss"; import "./index.scss";
class Blogs extends Component { class Blogs extends Component {
componentDidMount() { componentDidMount() {
// this.props.contentList(1, 100, CONTENT_LIST_3); this.props.getBlogList();
} }
render() { render() {
const { blogs } = this.props; const { list } = this.props;
return ( return (
<> <>
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
<>
{list.length > 0 ? (
<div className="landscape-blogs d-flex flex-column"> <div className="landscape-blogs d-flex flex-column">
<div className="landscape-blogs__header d-flex"> <Navbar />
<span></span> <BreadCrumb />
<h3>اخبار</h3>
</div>
<div className="landscape-blogs__scroll d-flex flex-column"> <div className="landscape-blogs__scroll d-flex flex-column">
{blogs.map((item) => ( {list.map((item) => (
<Item item={item} key={item.id} getSingle={getSingle} /> <Item item={item} key={item.id} />
))} ))}
</div> </div>
</div> </div>
) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div>
)}
<Footer />
</>
) : null} ) : null}
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
<div className="portrait-blogs d-flex flex-column"> <div className="portrait-blogs d-flex flex-column">
<div className="portrait-blogs__header d-flex"> {list.length > 0 ? (
<span></span> <>
<h3>اخبار</h3> <Navbar />
</div> <BreadCrumb />
<div className="portrait-blogs__scroll d-flex flex-column"> <div className="portrait-blogs__scroll d-flex flex-column">
{blogs.map((item) => ( {list.map((item) => (
<Item item={item} key={item.id} getSingle={getSingle} /> <Item item={item} key={item.id} />
))} ))}
</div> </div>
</>
) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div>
)}
</div> </div>
) : null} ) : null}
</> </>
@ -42,9 +69,42 @@ class Blogs extends Component {
} }
} }
const Item = (props) => {
const { item } = props;
return (
<>
{window.innerWidth > 1000 ? (
<Link to={"/blogs/" + item.id} className="landscape-blogs-item d-flex">
<div className="landscape-blogs-item__pic">
<img src={`https://dnvn.ir/api/v1/file/${item.id}`} alt={item.id} />
</div>
<div className="landscape-blogs-item__left d-flex flex-column">
<h1>{item.title}</h1>
<span>مطالعه کامل</span>
</div>
</Link>
) : null}
{window.innerWidth < 1000 ? (
<Link
to={"/blogs/" + item.id}
className="portrait-blogs-item d-flex flex-column"
>
<img
src={`https://dnvn.ir/api/v1/file/${item.id}`}
alt={item.title}
/>
<h1>{item.title}</h1>
{/* <p>{item.text}</p> */}
<span>مطالعه کامل</span>
</Link>
) : null}
</>
);
};
export default connect( export default connect(
(state) => ({ (state) => ({
all: state.content.all, list: state.publicApi.blogList,
}), }),
{} { getBlogList: publicApi.getBlogList }
)(Blogs); )(Blogs);

@ -26,11 +26,59 @@
width: 0px; width: 0px;
} }
} }
&-item {
width: calc(100% - 8px);
height: 200px;
max-width: 800px;
max-height: 300px;
padding: 10px 10px 10px;
direction: rtl;
text-align: right;
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 16%);
border-radius: 8px;
position: relative;
margin: 20px auto 0px;
transform: translateY(-10px);
text-decoration: none;
&__pic {
width: 300px;
height: 100%;
& img {
width: 100%;
height: 100%;
border-radius: 10px;
}
}
&__left {
margin-right: 20px;
padding-top: 20px;
justify-content: flex-start;
h1 {
padding-right: 2px;
font-size: 28px;
margin-bottom: 0px;
letter-spacing: -2px;
color: #4e4e4e;
font-family: numeralLight;
text-decoration: none;
}
span {
font-family: numeralLight;
position: absolute;
font-size: 15px;
bottom: 10px;
left: 10px;
margin-bottom: 0px;
border-radius: 10px;
color: #6cbe44;
}
}
}
} }
.portrait-blogs { .portrait-blogs {
width: 100vw; width: 100vw;
padding: 90px 10px 10px; padding: 70px 10px 10px;
max-width: 680px; max-width: 680px;
margin: 0px auto; margin: 0px auto;
direction: rtl; direction: rtl;
@ -44,7 +92,7 @@
margin-bottom: 20px; margin-bottom: 20px;
letter-spacing: -1px; letter-spacing: -1px;
margin-right: 10px; margin-right: 10px;
color: $bright-cerulean; // color: $bright-cerulean;
} }
} }
&__scroll { &__scroll {
@ -56,4 +104,41 @@
width: 0px; width: 0px;
} }
} }
&-item {
font-family: numeralLight;
text-decoration: none;
width: calc(100% - 8px);
padding: 10px 10px 10px;
direction: rtl;
text-align: right;
box-shadow: 0 3px 8px 0 rgb(0 0 0 / 16%);
border-radius: 8px;
position: relative;
margin: 20px 4px 0px;
transform: translateY(-10px);
height: 330px;
& img {
width: 100%;
height: 220px;
border-radius: 10px;
}
h1 {
padding-right: 2px;
font-size: 28px;
margin-bottom: 0px;
margin-top: 10px;
// color: $smalt;
text-decoration: none;
color: #4e4e4e;
}
span {
position: absolute;
font-size: 18px;
bottom: 5px;
left: 10px;
margin-bottom: 0px;
border-radius: 10px;
color: #6cbe44;
}
}
} }

@ -43,18 +43,7 @@ class VideoApp extends Component {
render() { render() {
return ( return (
// <div style={{ width: "100%", height: "100%" }}> // <div style={{ width: "100%", height: "100%" }}>
<video <video controls={true} src={this.state.video.src} type="video/mp4" />
controls={true}
src={this.state.video.src}
onReady={this.onPlayerReady.bind(this)}
onPlay={this.onVideoPlay.bind(this)}
onPause={this.onVideoPause.bind(this)}
onTimeUpdate={this.onVideoTimeUpdate.bind(this)}
onSeeking={this.onVideoSeeking.bind(this)}
onSeeked={this.onVideoSeeked.bind(this)}
onEnd={this.onVideoEnd.bind(this)}
type="video/mp4"
/>
// </div> // </div>
); );
} }

@ -3,11 +3,6 @@ import AudioPlayer from "material-ui-audio-player";
const muiTheme = createMuiTheme({}); const muiTheme = createMuiTheme({});
const src = [
"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3",
];
export default function MaterialAudioPlayer(props) { export default function MaterialAudioPlayer(props) {
return ( return (
<ThemeProvider theme={muiTheme}> <ThemeProvider theme={muiTheme}>
@ -21,7 +16,7 @@ export default function MaterialAudioPlayer(props) {
order="standart" order="standart"
preload="auto" preload="auto"
loop={false} loop={false}
src={src} src={"https://dnvn.ir/api/v1/file/" + props.data}
/> />
</ThemeProvider> </ThemeProvider>
); );

@ -1,10 +1,9 @@
import React from "react"; import React from "react";
import MaterialAudioPlayer from './Material-audio-player/index'; import MaterialAudioPlayer from "./Material-audio-player/index";
import "./index.scss"; import "./index.scss";
export default function VoiceBox(props) { export default function VoiceBox(props) {
const { data } = props;
return ( return (
<> <>
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
@ -14,9 +13,9 @@ export default function VoiceBox(props) {
className="d-flex align-items-center" className="d-flex align-items-center"
> >
<span></span> <span></span>
{props.data.title} {data.title}
</h2> </h2>
<MaterialAudioPlayer /> <MaterialAudioPlayer data={data.fileIds} />
</div> </div>
) : null} ) : null}
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
@ -25,9 +24,7 @@ export default function VoiceBox(props) {
<span></span> <span></span>
{props.data.title} {props.data.title}
</h2> </h2>
<MaterialAudioPlayer data={data.fileIds} />
<MaterialAudioPlayer />
</div> </div>
) : null} ) : null}
</> </>

Loading…
Cancel
Save