Skip to content

Commit 6fdc717

Browse files
committed
some translations and improved apt modals
1 parent 13190eb commit 6fdc717

File tree

6 files changed

+215
-178
lines changed

6 files changed

+215
-178
lines changed

src/components/appointments/Appointments.js

Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React, { Component } from 'react'
22
import {Link, Route} from 'react-router-dom'
33
import ReactTooltip from 'react-tooltip'
4-
import format from 'date-fns/format'
54
import {colour_contrast, group_by} from '../../utils'
65
import {If} from '../shared/Tools'
7-
import {CalendarTimes, CalendarPlus} from '../shared/Svgs' // CalendarCheck
6+
import {CalendarCheck, CalendarPlus, CalendarTimes} from '../shared/Svgs'
87
import AptModal from './AptModal'
98

9+
const LS_KEY = '_tcs_user_data_'
10+
1011
const group_appointments = apts => {
1112
// group appointments by month then day
1213
return group_by(apts, a => a.start.match(/\d{4}-\d{2}/)[0])
@@ -16,41 +17,47 @@ const group_appointments = apts => {
1617
}))
1718
}
1819

19-
const Apt = ({apt, props}) => {
20+
const Apt = ({apt, props, appointment_attendees}) => {
2021
const full = apt.attendees_max === apt.attendees_count
2122
const colour = full ? '#CCC' : apt.service_colour
22-
const tip = full ? 'Lesson fully subscribed' : null
23-
let Icon = full ? CalendarTimes : CalendarPlus
23+
let Icon, tip
24+
const spaces_ctx = {spaces: apt.attendees_max - apt.attendees_count}
25+
if (appointment_attendees && appointment_attendees[apt.id] !== undefined) {
26+
Icon = CalendarCheck
27+
tip = props.config.get_text(full ? 'no_spaces_attending' : 'spaces_attending', spaces_ctx)
28+
} else {
29+
Icon = full ? CalendarTimes : CalendarPlus
30+
tip = props.config.get_text(full ? 'no_spaces' : 'spaces', spaces_ctx)
31+
}
2432
return (
2533
<Link to={props.root.url(`appointment/${apt.link}`)} className="tcs-item">
2634
<div className={`tcs-apt ${colour_contrast(colour)}`} style={{background: colour}} data-tip={tip}>
2735
<div>
2836
<Icon/>
29-
<span>{format(apt.start, 'HH:mm')}</span>
37+
<span>{props.config.date_fns.format(apt.start, 'HH:mm')}</span>
3038
<span>{apt.topic} ({apt.service_name})</span>
3139
</div>
3240
<div>
3341
<span>{props.config.format_time_diff(apt.finish, apt.start)}</span>&bull;
3442
<span>{props.config.format_money(apt.price)}</span>
3543
</div>
3644
</div>
37-
<ReactTooltip effect="solid"/>
3845
</Link>
3946
)
4047
}
4148

42-
const AptDayGroup = ({appointments, props}) => {
49+
const AptDayGroup = ({appointments, props, appointment_attendees}) => {
4350
const first_apt = appointments[0]
4451
return (
4552
<div className="tcs-apt-group-day">
4653
<div className="tcs-day">
47-
{format(first_apt.start, 'Do')}
54+
{props.config.date_fns.format(first_apt.start, 'Do')}
4855
<br/>
49-
{format(first_apt.start, 'ddd')}
56+
{props.config.date_fns.format(first_apt.start, 'ddd')}
5057
</div>
5158
<div>
52-
{appointments.map((apt, i) => (
53-
<Apt key={i} apt={apt} props={props}/>
59+
{appointments.map(apt => (
60+
<Apt key={apt.id} apt={apt} props={props} appointment_attendees={appointment_attendees}/>
5461
))}
5562
</div>
5663
</div>
@@ -64,13 +71,19 @@ class Appointments extends Component {
6471
appointments: null,
6572
page: 1,
6673
more_pages: false,
74+
display_data: null,
75+
appointment_attendees: null,
6776
}
77+
this.sso_args = null
6878
this.update = this.update.bind(this)
79+
this.signin = this.signin.bind(this)
80+
this.signout = this.signout.bind(this)
6981
this.root_url = this.props.root.url('')
7082
}
7183

72-
async componentDidMount () {
73-
await this.update()
84+
componentDidMount () {
85+
this.update_display_data()
86+
this.update()
7487
}
7588

7689
page_url (page) {
@@ -83,23 +96,69 @@ class Appointments extends Component {
8396
}
8497

8598
async update () {
86-
const mj = this.props.history.location.pathname.match(/job\/(\d+)/)
87-
const job_id = mj ? parseInt(mj[1], 10) : null
88-
8999
const mp = this.props.history.location.pathname.match(/page\/(\d+)/)
90100
const page = mp ? parseInt(mp[1], 10) : 1
91-
this.setState({job_id, page})
92101
const appointments = await this.props.root.requests.get('appointments', {
93-
service: job_id,
94-
page: page,
95-
pagination: this.props.config.pagination,
102+
page, pagination: this.props.config.pagination,
96103
})
97104
this.props.config.event_callback('updated_appointments', appointments)
98105
const on_previous_pages = (page - 1) * this.props.config.pagination
106+
this.sso_args && await this.update_attendees()
99107
this.setState({
100108
appointments,
101109
more_pages: appointments.count > appointments.results.length + on_previous_pages,
102110
})
111+
ReactTooltip.rebuild()
112+
}
113+
114+
signin () {
115+
const process_message = event => {
116+
try {
117+
JSON.parse(event.data)
118+
} catch (e) {
119+
return
120+
}
121+
event.source.close()
122+
window.sessionStorage[LS_KEY] = event.data
123+
this.update_display_data()
124+
this.update_attendees()
125+
}
126+
window.addEventListener('message', process_message, false)
127+
window.open(
128+
`${this.props.config.auth_url}?site=${encodeURIComponent(window.location.href)}`,
129+
'Auth',
130+
'width=1000,height=700,left=100,top=100,scrollbars,toolbar=0,resizable'
131+
)
132+
}
133+
134+
signout () {
135+
this.setState({
136+
display_data: null,
137+
appointment_attendees: null,
138+
})
139+
this.sso_args = null
140+
window.sessionStorage.removeItem(LS_KEY)
141+
}
142+
143+
update_display_data () {
144+
const raw_data = window.sessionStorage[LS_KEY]
145+
if (raw_data) {
146+
this.sso_args = JSON.parse(raw_data)
147+
this.setState({display_data: JSON.parse(this.sso_args.sso_data)})
148+
}
149+
}
150+
151+
async update_attendees () {
152+
try {
153+
const r = await this.props.root.requests.get('check-client', this.sso_args, {set_app_state: false})
154+
this.setState({appointment_attendees: r.appointment_attendees})
155+
} catch (e) {
156+
if (e.xhr.status === 401) {
157+
this.signout()
158+
} else {
159+
this.props.root.setState({error: e.msg})
160+
}
161+
}
103162
}
104163

105164
render () {
@@ -109,13 +168,15 @@ class Appointments extends Component {
109168
<div className="tcs-app tcs-appointments">
110169
{months.map(({date, appointments}, i) => (
111170
<div className="tcs-apt-group-month" key={i}>
112-
<div className="tcs-title">{format(date, 'MMMM')}</div>
113-
{appointments.map((appointments, i) => (
114-
<AptDayGroup appointments={appointments} key={i} props={this.props}/>
171+
<div className="tcs-title">{this.props.config.date_fns.format(date, 'MMMM')}</div>
172+
{appointments.map((appointments, j) => (
173+
<AptDayGroup key={j} appointments={appointments} props={this.props}
174+
appointment_attendees={this.state.appointment_attendees}/>
115175
))}
116176
</div>
117177
))}
118178

179+
<ReactTooltip effect="solid"/>
119180
<If v={this.state.page > 1 || this.state.more_pages}>
120181
<div className="tcs-pagination">
121182
<Link
@@ -137,9 +198,14 @@ class Appointments extends Component {
137198
last_url={this.root_url}
138199
appointments={this.state.appointments && this.state.appointments.results}
139200
got_data={Boolean(this.state.appointments)}
201+
display_data={this.state.display_data}
202+
appointment_attendees={this.state.appointment_attendees}
203+
sso_args={this.sso_args}
140204
root={this.props.root}
141205
config={this.props.config}
142-
update_apts={this.update}
206+
update={this.update}
207+
signin={this.signin}
208+
signout={this.signout}
143209
history={props.history}/>
144210
)}/>
145211
</div>

0 commit comments

Comments
 (0)