🔨 - [react-personal-anniversary-counter] built sample
This commit is contained in:
parent
aa06723974
commit
182fc19319
|
@ -12,31 +12,31 @@
|
|||
"test": "gulp test"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": "2.3.1",
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"@fluentui/react": "^8.106.4",
|
||||
"@microsoft/sp-core-library": "1.18.2",
|
||||
"@microsoft/sp-component-base": "1.18.2",
|
||||
"@microsoft/sp-core-library": "1.18.2",
|
||||
"@microsoft/sp-lodash-subset": "1.18.2",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.18.2",
|
||||
"@microsoft/sp-property-pane": "1.18.2",
|
||||
"@microsoft/sp-webpart-base": "1.18.2",
|
||||
"@microsoft/sp-lodash-subset": "1.18.2",
|
||||
"@microsoft/sp-office-ui-fabric-core": "1.18.2"
|
||||
"react": "17.0.1",
|
||||
"react-dom": "17.0.1",
|
||||
"tslib": "2.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
|
||||
"@rushstack/eslint-config": "2.5.1",
|
||||
"@microsoft/eslint-plugin-spfx": "1.18.2",
|
||||
"@microsoft/eslint-config-spfx": "1.18.2",
|
||||
"@microsoft/eslint-plugin-spfx": "1.18.2",
|
||||
"@microsoft/rush-stack-compiler-4.7": "0.1.0",
|
||||
"@microsoft/sp-build-web": "1.18.2",
|
||||
"@microsoft/sp-module-interfaces": "1.18.2",
|
||||
"@rushstack/eslint-config": "2.5.1",
|
||||
"@types/react": "17.0.45",
|
||||
"@types/react-dom": "17.0.17",
|
||||
"@types/webpack-env": "~1.15.2",
|
||||
"ajv": "^6.12.5",
|
||||
"eslint": "8.7.0",
|
||||
"gulp": "4.0.2",
|
||||
"typescript": "4.7.4",
|
||||
"@types/react": "17.0.45",
|
||||
"@types/react-dom": "17.0.17",
|
||||
"eslint-plugin-react-hooks": "4.3.0",
|
||||
"@microsoft/sp-module-interfaces": "1.18.2"
|
||||
"gulp": "4.0.2",
|
||||
"typescript": "4.7.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
@import '~@fluentui/react/dist/sass/References.scss';
|
||||
|
||||
|
||||
.wrapper {
|
||||
background:
|
||||
radial-gradient(circle at 100% 100%, #ffffff 0, #ffffff 6px, transparent 6px) 0% 0%/11px 11px no-repeat,
|
||||
radial-gradient(circle at 0 100%, #ffffff 0, #ffffff 6px, transparent 6px) 100% 0%/11px 11px no-repeat,
|
||||
radial-gradient(circle at 100% 0, #ffffff 0, #ffffff 6px, transparent 6px) 0% 100%/11px 11px no-repeat,
|
||||
radial-gradient(circle at 0 0, #ffffff 0, #ffffff 6px, transparent 6px) 100% 100%/11px 11px no-repeat,
|
||||
linear-gradient(#ffffff, #ffffff) 50% 50% / calc(100% - 10px) calc(100% - 22px) no-repeat,
|
||||
linear-gradient(#ffffff, #ffffff) 50% 50% / calc(100% - 22px) calc(100% - 10px) no-repeat,
|
||||
linear-gradient(325deg, #dfc5e4 0%, #cae4f0 100%);
|
||||
border-radius: 11px;
|
||||
padding: 15px;
|
||||
box-sizing: content-box;
|
||||
align-items: "center";
|
||||
display: "flex";
|
||||
flex-direction: "column";
|
||||
}
|
|
@ -1,11 +1,49 @@
|
|||
import * as React from 'react';
|
||||
import useLocalStorage from '../hooks/useLocalStorage';
|
||||
import { DatePicker, PrimaryButton, Stack, Text } from '@fluentui/react';
|
||||
import styles from './PersonalAnniversary.module.scss';
|
||||
|
||||
export interface IPersonalAnniversaryProps {}
|
||||
export interface IPersonalAnniversaryProps { }
|
||||
|
||||
export const PersonalAnniversary: React.FunctionComponent<IPersonalAnniversaryProps> = (props: React.PropsWithChildren<IPersonalAnniversaryProps>) => {
|
||||
const [date, setDate] = useLocalStorage<{ AnniversaryDate: Date }>('personalAnniversary', null)
|
||||
const [tempDate, setTempDate] = React.useState<Date>(null)
|
||||
|
||||
|
||||
if (date === null)
|
||||
return <>
|
||||
<div className={styles.wrapper}>
|
||||
<DatePicker
|
||||
label="When did you join the company?"
|
||||
onSelectDate={(date) => setTempDate(date)}
|
||||
value={tempDate}
|
||||
formatDate={(date) => {
|
||||
if (date === null)
|
||||
return ''
|
||||
return date.toLocaleDateString()
|
||||
}}
|
||||
isRequired={true}
|
||||
/>
|
||||
<PrimaryButton
|
||||
text="Save"
|
||||
onClick={() => setDate({ AnniversaryDate: tempDate })}
|
||||
disabled={tempDate === null}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
|
||||
const DateDiff: number = new Date().getTime() - date.AnniversaryDate.getTime()
|
||||
return (
|
||||
<>
|
||||
|
||||
<div className={styles.wrapper} >
|
||||
<Text variant="xLarge">You' ve been working here for:</Text>
|
||||
<Stack tokens={{ childrenGap: 5 }} styles={{ root: { marginTop: "2em", alignItems: "center", } }}>
|
||||
<Text variant='large'><b>{Math.floor(DateDiff / (1000 * 3600 * 24 * 365))}</b> Years</Text>
|
||||
<Text variant='large'><b>{Math.floor(DateDiff / ((1000 * 3600 * 24 * 365) / 12))}</b> Months</Text>
|
||||
<Text variant='large'><b>{Math.floor(DateDiff / (1000 * 3600 * 24))}</b> Days</Text>
|
||||
</Stack>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
import { useState } from 'react';
|
||||
import { ObjectHelper } from '../utils/Objecthelper';
|
||||
|
||||
export default function useLocalStorage<T>(key: string, initialValue?: T): [T, (value: T) => void] {
|
||||
const [value, setValue] = useState<T>(() => {
|
||||
const item = window.localStorage.getItem(key);
|
||||
return item ? ObjectHelper.ParseItem(JSON.parse(item)) : initialValue;
|
||||
});
|
||||
|
||||
|
||||
const setItem: (newValue: T) => void = (newValue: T) => {
|
||||
window.localStorage.setItem(key, JSON.stringify(newValue));
|
||||
setValue(newValue);
|
||||
};
|
||||
|
||||
|
||||
return [
|
||||
value, setItem
|
||||
];
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export interface IPersonalAnniversary {
|
||||
Title: string;
|
||||
AnniversaryDate: Date;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* eslint-disable */
|
||||
export namespace ObjectHelper {
|
||||
const RemoveODataProperties = (obj: any) => {
|
||||
for (let prop of Object.keys(obj))
|
||||
if (prop.indexOf("odata.") == 0)
|
||||
delete obj[prop];
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
const ISO_8601_FULL = /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?(([+-]\d\d:\d\d)|Z)?$/i
|
||||
const isISO8601 = (str: string) => (str + "").match(ISO_8601_FULL);
|
||||
|
||||
const ParseAllDates = (obj: any) => {
|
||||
for (let prop of Object.keys(obj))
|
||||
if (isISO8601(obj[prop]))
|
||||
obj[prop] = new Date(obj[prop]);
|
||||
return obj;
|
||||
}
|
||||
|
||||
const RemoveProps: string[] = ["Attachments", "ComplianceAssetId", "FileSystemObjectType", "GUID", "ID", "OData__ColorTag", "OData__UIVersionString", "ServerRedirectedEmbedUri", "ServerRedirectedEmbedUrl"];
|
||||
const RemoveDefaultFields = (obj: any) => {
|
||||
for (let prop of RemoveProps)
|
||||
delete obj[prop];
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
export const ParseItem: <T>(item: T) => T = <T>(item: any) => {
|
||||
if (Array.isArray(item)) {
|
||||
for (let i of item) {
|
||||
i = RemoveODataProperties(i);
|
||||
i = ParseAllDates(i);
|
||||
i = RemoveDefaultFields(i);
|
||||
}
|
||||
} else {
|
||||
item = RemoveODataProperties(item);
|
||||
item = ParseAllDates(item);
|
||||
item = RemoveDefaultFields(item);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue