Client: calendar init
This commit is contained in:
parent
809687c9b1
commit
a353e3be80
@ -192,3 +192,124 @@ input, textarea {
|
|||||||
0% { transform: rotate(0deg); }
|
0% { transform: rotate(0deg); }
|
||||||
100% { transform: rotate(360deg); }
|
100% { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* calendar */
|
||||||
|
:root {
|
||||||
|
--main-color: #1a8fff;
|
||||||
|
--text-color: #777;
|
||||||
|
--text-color-light: #ccc;
|
||||||
|
--border-color: #eee;
|
||||||
|
--bg-color: #f9f9f9;
|
||||||
|
--neutral-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .col-start {
|
||||||
|
justify-content: flex-start;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .col-center {
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .col-end {
|
||||||
|
justify-content: flex-end;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
background: var(--neutral-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .header {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
/*font-size: 115%;*/
|
||||||
|
padding: 0.5em 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .header .icon {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .15s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .header .icon:hover {
|
||||||
|
transform: scale(1.75);
|
||||||
|
transition: .25s ease-out;
|
||||||
|
color: var(--main-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .header .icon:first-of-type {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .header .icon:last-of-type {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .days {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 400;
|
||||||
|
color: var(--text-color-light);
|
||||||
|
font-size: 70%;
|
||||||
|
padding: .75em 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .cell {
|
||||||
|
position: relative;
|
||||||
|
height: 3em;
|
||||||
|
border-right: 1px solid var(--border-color);
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
background: var(--neutral-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .cell:hover {
|
||||||
|
background: var(--bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .selected {
|
||||||
|
border-left: 10px solid transparent;
|
||||||
|
border-image: linear-gradient(45deg, #1a8fff 0%,#53cbf1 40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .row {
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .row:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .cell:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .cell .number {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 82.5%;
|
||||||
|
line-height: 1;
|
||||||
|
top: .75em;
|
||||||
|
right: .75em;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .disabled {
|
||||||
|
color: var(--text-color-light);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar .body .col {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-basis: calc(100%/7);
|
||||||
|
width: calc(100%/7);
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { Helmet } from 'react-helmet'
|
|||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
import ActivityCard from './ActivityCard'
|
import ActivityCard from './ActivityCard'
|
||||||
|
import Calendar from './../Others/Calendar'
|
||||||
import Records from './Records'
|
import Records from './Records'
|
||||||
import Statistics from './Statistics'
|
import Statistics from './Statistics'
|
||||||
import { getData } from '../../actions'
|
import { getData } from '../../actions'
|
||||||
@ -40,6 +41,7 @@ class DashBoard extends React.Component {
|
|||||||
<div className="container dashboard">
|
<div className="container dashboard">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
|
<Calendar />
|
||||||
<Records records={records} sports={sports} />
|
<Records records={records} sports={sports} />
|
||||||
<Statistics />
|
<Statistics />
|
||||||
</div>
|
</div>
|
||||||
|
118
mpwo_client/src/components/Others/Calendar.jsx
Normal file
118
mpwo_client/src/components/Others/Calendar.jsx
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// eslint-disable-next-line max-len
|
||||||
|
// source: https://blog.flowandform.agency/create-a-custom-calendar-in-react-3df1bfd0b728
|
||||||
|
import dateFns from 'date-fns'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default class Calendar extends React.Component {
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context)
|
||||||
|
this.state = {
|
||||||
|
currentMonth: new Date(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderHeader() {
|
||||||
|
const dateFormat = 'MMM YYYY'
|
||||||
|
return (
|
||||||
|
<div className="header row flex-middle">
|
||||||
|
<div className="col col-start" onClick={() => this.handlePrevMonth()}>
|
||||||
|
<i
|
||||||
|
className="fa fa-chevron-left"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col col-center">
|
||||||
|
<span>
|
||||||
|
{dateFns.format(this.state.currentMonth, dateFormat)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="col col-end" onClick={() => this.handleNextMonth()}>
|
||||||
|
<i
|
||||||
|
className="fa fa-chevron-right"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDays() {
|
||||||
|
const dateFormat = 'ddd'
|
||||||
|
const days = []
|
||||||
|
const startDate = dateFns.startOfWeek(this.state.currentMonth)
|
||||||
|
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
days.push(
|
||||||
|
<div className="col col-center" key={i}>
|
||||||
|
{dateFns.format(dateFns.addDays(startDate, i), dateFormat)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return <div className="days row">{days}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCells() {
|
||||||
|
const { currentMonth, selectedDate } = this.state
|
||||||
|
const monthStart = dateFns.startOfMonth(currentMonth)
|
||||||
|
const monthEnd = dateFns.endOfMonth(monthStart)
|
||||||
|
const startDate = dateFns.startOfWeek(monthStart)
|
||||||
|
const endDate = dateFns.endOfWeek(monthEnd)
|
||||||
|
|
||||||
|
const dateFormat = 'D'
|
||||||
|
const rows = []
|
||||||
|
|
||||||
|
let days = []
|
||||||
|
let day = startDate
|
||||||
|
let formattedDate = ''
|
||||||
|
|
||||||
|
while (day <= endDate) {
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
formattedDate = dateFns.format(day, dateFormat)
|
||||||
|
days.push(
|
||||||
|
<div
|
||||||
|
className={`col cell ${
|
||||||
|
dateFns.isSameMonth(day, monthStart)
|
||||||
|
? dateFns.isSameDay(day, selectedDate) ? 'selected' : ''
|
||||||
|
: 'disabled'
|
||||||
|
}`}
|
||||||
|
key={day}
|
||||||
|
>
|
||||||
|
<span className="number">{formattedDate}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
day = dateFns.addDays(day, 1)
|
||||||
|
}
|
||||||
|
rows.push(
|
||||||
|
<div className="row" key={day}>
|
||||||
|
{days}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
days = []
|
||||||
|
}
|
||||||
|
return <div className="body">{rows}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNextMonth () {
|
||||||
|
this.setState({
|
||||||
|
currentMonth: dateFns.addMonths(this.state.currentMonth, 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePrevMonth () {
|
||||||
|
this.setState({
|
||||||
|
currentMonth: dateFns.subMonths(this.state.currentMonth, 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="card activity-card">
|
||||||
|
<div className="calendar">
|
||||||
|
{this.renderHeader()}
|
||||||
|
{this.renderDays()}
|
||||||
|
{this.renderCells()}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user