Add files via upload

This commit is contained in:
Jerry Yasir 2020-10-30 22:46:07 -04:00 committed by GitHub
parent c2c82059d9
commit 4df4a75818
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 562 additions and 0 deletions

View File

@ -0,0 +1 @@
// A file is required to be in the root of the /src directory by the TypeScript compiler

View File

@ -0,0 +1,27 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "0d3e8554-de4b-4b8c-bf6c-71591ffb926a",
"alias": "ReactSpFxWebPart",
"componentType": "WebPart",
// The "*" signifies that the version should be taken from the package.json
"version": "*",
"manifestVersion": 2,
// If true, the component can only be installed on sites where Custom Script is allowed.
// Components that allow authors to embed arbitrary script code should set this to true.
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
"requiresCustomScript": false,
"supportedHosts": ["SharePointWebPart"],
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": { "default": "Entertainment" },
"title": { "default": "Soccer Hightlights" },
"description": { "default": "Soccer Hightlights Web Parts show latest hightlights from around the world." },
"officeFabricIconFontName": "Soccer",
"properties": {
"tile": "Soocer Highlights"
}
}]
}

View File

@ -0,0 +1,80 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField,
PropertyPaneSlider,
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import * as strings from 'ReactSpFxWebPartStrings';
import ReactSpFx from './components/ReactSpFx';
import { IReactSpFxProps } from './components/IReactSpFxProps';
import { DisplayMode } from '@microsoft/sp-core-library';
export interface IReactSpFxWebPartProps {
title: string;
pageSize: number;
displayMode: DisplayMode;
updateProperty: (value: string) => void;
}
export default class ReactSpFxWebPart extends BaseClientSideWebPart<IReactSpFxWebPartProps> {
public render(): void {
const element: React.ReactElement<IReactSpFxProps> = React.createElement(
ReactSpFx,
{
title: this.properties.title,
displayMode: this.properties.displayMode,
pageSize: this.properties.pageSize,
updateProperty: (value: string) => {this.properties.title = value;},
onConfigure: () => {
this.context.propertyPane.open();
},
}
);
ReactDom.render(element, this.domElement);
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('title', {
label: strings.DescriptionFieldLabel
}),
PropertyPaneSlider('pageSize',{
label:"Highlights Per Page",
min:1,
max:20,
value:2,
showValue:true,
step:1
})
]
}
]
}
]
};
}
}

View File

@ -0,0 +1,57 @@
import { DisplayMode } from '@microsoft/sp-core-library';
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
export interface IReactSpFxProps {
title: string;
displayMode: DisplayMode;
pageSize: number;
updateProperty: (value: string) => void;
onConfigure: () => void;
}
export interface IVidesList {
videos: IVideo[];
}
export interface IVideo {
title: string;
embed: string;
}
export interface ISportsHighlightsState {
sportHighlightState: [];
}
export interface ISportsHighlightPagingState {
currentPage: number;
indexOfLastHighlight: number;
indexOfFirstHighlight: number;
highLightsPerPage: number;
}
export interface ISportsHightLightsProps {
pageSize:number;
sportsHighlights: [];
}
export interface ISide {
name: string;
}
export interface ICompetition{
name: string;
id: number;
}
export interface ISportsHighlightProps {
title: string;
id: string;
date: Date;
side1: ISide;
side2: ISide;
competition: ICompetition;
thumbnail: string;
videos: IVideo[];
}

View File

@ -0,0 +1,25 @@
import React from "react";
const Pagination = ({ highLightsPerPage, totalHighlights, paginate }) => {
const pageNumbers = [];
for (let i = 1; i <= Math.ceil(totalHighlights / highLightsPerPage); i++) {
pageNumbers.push(i);
}
return (
<nav>
<ul className="pagination" style={{ marginLeft: "10px" }}>
{pageNumbers.map((number) => (
<li key={number} className="page-item">
<a onClick={() => paginate(number)} href="#" className="page-link">
{number}
</a>
</li>
))}
</ul>
</nav>
);
};
export default Pagination;

View File

@ -0,0 +1,85 @@
@import '~office-ui-fabric-react/dist/sass/References.scss';
.reactSpFx {
.container {
max-width: 700px;
margin: 0px auto;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.paginationDiv{
border: 1px solid lightblue;
height: 100px;
padding: 10px 0;
display: flex;
justify-content: center;
}
.row {
@include ms-Grid-row;
@include ms-fontColor-white;
background-color: $ms-color-themeDark;
padding: 20px;
}
.column {
@include ms-Grid-col;
@include ms-lg10;
@include ms-xl8;
@include ms-xlPush2;
@include ms-lgPush1;
}
.title {
font-size: large;
font-weight: bold;
font-style: normal;
@include ms-font-xl;
@include ms-fontColor-white;
}
.subTitle {
@include ms-font-l;
@include ms-fontColor-white;
}
.description {
@include ms-font-l;
@include ms-fontColor-white;
}
.button {
// Our button
text-decoration: none;
height: 32px;
// Primary Button
min-width: 80px;
background-color: $ms-color-themePrimary;
border-color: $ms-color-themePrimary;
color: $ms-color-white;
// Basic Button
outline: transparent;
position: relative;
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
-webkit-font-smoothing: antialiased;
font-size: $ms-font-size-m;
font-weight: $ms-font-weight-regular;
border-width: 0;
text-align: center;
cursor: pointer;
display: inline-block;
padding: 0 16px;
.label {
font-weight: $ms-font-weight-semibold;
font-size: $ms-font-size-m;
height: 32px;
line-height: 32px;
margin: 0 4px;
vertical-align: top;
display: inline-block;
}
}
}

View File

@ -0,0 +1,17 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'button': string;
'column': string;
'container': string;
'description': string;
'label': string;
'ms-Grid': string;
'paginationDiv': string;
'reactSpFx': string;
'row': string;
'subTitle': string;
'title': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@ -0,0 +1,66 @@
import * as React from "react";
import styles from "./ReactSpFx.module.scss";
import { IReactSpFxProps, ISportsHighlightsState } from "./IReactSpFxProps";
import { escape } from "@microsoft/sp-lodash-subset";
import SportsHighlightsList from "./SportsHighlightsList";
import { WebPartTitle } from "@pnp/spfx-controls-react/lib/WebPartTitle";
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder";
import axios from "axios";
import { setVirtualParent } from "office-ui-fabric-react";
import SportsHighlights from "./SportsHighlightsList";
import "bootstrap/dist/css/bootstrap.css";
export default class ReactSpFx extends React.Component<
IReactSpFxProps,
ISportsHighlightsState
> {
public constructor(props: IReactSpFxProps, state: ISportsHighlightsState) {
super(props);
this.state = {
sportHighlightState: [],
};
}
GetData = async () => {
const resp = await axios.get(`https://www.scorebat.com/video-api/v1/`);
const data = await resp.data;
this.setState({ sportHighlightState: data });
};
async componentDidMount() {
this.GetData();
}
public render(): React.ReactElement<IReactSpFxProps> {
const globalComponent = this;
console.log(this.props.pageSize);
return (
<div className={styles.container}>
{!this.props.title && (
<Placeholder
iconName="Soccer Highlights"
iconText="Configure your web part"
description="Set Web Part Title and choose Page Size to hide this section."
buttonLabel="Configure the Web Part"
onConfigure={this.props.onConfigure}
/>
)}
{typeof this.props.title !== "undefined" && (
<div id="mainDiv">
<WebPartTitle
displayMode={this.props.displayMode}
title={this.props.title}
updateProperty={this.props.updateProperty}
/>
</div>
)}
<span></span>
<SportsHighlightsList
sportsHighlights={this.state.sportHighlightState}
pageSize={this.props.pageSize}
/>
</div>
);
}
}

View File

@ -0,0 +1,45 @@
import { videoProperties } from "office-ui-fabric-react";
import React from "react";
import ReactDOM from "react-dom";
import { ISportsHighlightProps } from "./IReactSpFxProps";
import SportsVideoList from "./SportsVideoList";
export default class SportsHighlight extends React.Component<
ISportsHighlightProps
> {
public render() {
const options = {
year: "2-digit",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
};
const {
title,
id,
date,
side1,
side2,
competition,
thumbnail,
videos,
} = this.props;
return (
<div style={{ margin: "2px" }}>
<div style={{ display: "inline-block", marginLeft: "12px" }}>
<div style={{ fontSize: "1.25rem", fontWeight: "bold" }}>{title}</div>
<div style={{ fontSize: "16px", fontWeight: "bold" }}>
{competition.name}
</div>
<div style={{ fontSize: "14px", fontWeight: "normal" }}>
Date & Time: <b>{new Date(date.toString()).toLocaleString("en-US", options)}</b>
</div>
<div>{id}</div>
<SportsVideoList videos={videos} />
</div>
</div>
);
}
}

View File

@ -0,0 +1,94 @@
import React from "react";
import ReactDOM from "react-dom";
import {
ISportsHightLightsProps,
ISportsHighlightPagingState,
IVideo,
} from "./IReactSpFxProps";
import SportsHighlight from "./SportsHighlight";
import Paging from "react-paging";
import Pagination from "./Pagination";
export default class SportsHighlightsList extends React.Component<
ISportsHightLightsProps,
ISportsHighlightPagingState
> {
constructor(props) {
super(props);
this.state = {
currentPage: 1,
indexOfFirstHighlight: 1,
indexOfLastHighlight: 5,
highLightsPerPage: this.props.pageSize,
};
}
paginate = (page) => {
console.clear();
const indexOfLastHighlight =
this.state.currentPage * this.state.highLightsPerPage;
const indexOfFirstHighlight =
indexOfLastHighlight - this.state.highLightsPerPage;
this.setState({
currentPage: page,
indexOfLastHighlight: indexOfLastHighlight,
indexOfFirstHighlight: indexOfFirstHighlight,
});
};
//paginate = (pageNumber) => setCurrentPage(pageNumber);
render(): React.ReactElement<ISportsHightLightsProps> {
const sportsHighlights = this.props.sportsHighlights;
var {
currentPage,
indexOfFirstHighlight,
indexOfLastHighlight,
} = this.state;
if (typeof indexOfFirstHighlight === "undefined" || indexOfFirstHighlight == 0)
{
indexOfFirstHighlight=1
}
if (
typeof indexOfFirstHighlight === "undefined" ||
indexOfFirstHighlight == 0
) {
indexOfFirstHighlight = 1;
}
const CurrentsportsHighlights = this.props.sportsHighlights.slice(
indexOfFirstHighlight,
indexOfLastHighlight
);
console.clear();
console.log("indexOfFirstHighlight:" + indexOfFirstHighlight);
console.log("indexOfLastHighlight : " + indexOfLastHighlight);
console.log("currentPage :" + currentPage);
console.log("Page Size :" + this.props.pageSize);
//this.updateLastPage(currentPage);
return (
<div>
<div className="paginationDiv">
<Pagination
highLightsPerPage={10}
totalHighlights={sportsHighlights.length}
paginate={this.paginate}
/>
</div>
<div>
{CurrentsportsHighlights.map((highLight, i) => (
<SportsHighlight {...highLight} key={i} />
))}
</div>
</div>
);
}
}

View File

@ -0,0 +1,26 @@
import React from "react";
import ReactDOM from "react-dom";
import { IVideo } from "./IReactSpFxProps";
import ReactMarkdownWithHtml from "react-markdown/with-html";
import { body } from "@pnp/pnpjs";
export default class SportsVideo extends React.Component<IVideo> {
public render() {
const { title, embed } = this.props;
return (
<div>
<div
style={{ fontSize: "12px", fontWeight: "bold", textAlign: "center", color:"blue" }}
title={"click to play " + title}
>
{title}
</div>
<div id={"video" + title}
dangerouslySetInnerHTML={{ __html: embed }}
style={{ width: 500, padding: "8px" }}
title={"click to play " + title}
/>
</div>
);
}
}

View File

@ -0,0 +1,22 @@
import React from "react";
import ReactDOM from "react-dom";
import { IVidesList } from "./IReactSpFxProps";
import SportsVideo from "./SportsVideo";
import ReactMarkdownWithHtml from "react-markdown/with-html";
export default class SportsVideoList extends React.Component<IVidesList> {
public render() {
const videos = this.props.videos;
return (
<div style={{ margin: "1px" }}>
{this.props.videos.map((video, i) => (
<SportsVideo
key={i}
embed={video.embed}
title={video.title}
/>
))}
</div>
);
}
}

View File

@ -0,0 +1,7 @@
define([], function() {
return {
"PropertyPaneDescription": "Title",
"BasicGroupName": "General",
"DescriptionFieldLabel": "Title"
}
});

View File

@ -0,0 +1,10 @@
declare interface IReactSpFxWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
DescriptionFieldLabel: string;
}
declare module 'ReactSpFxWebPartStrings' {
const strings: IReactSpFxWebPartStrings;
export = strings;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B