Skip to content

Commit 8fefb6f

Browse files
authored
Merge pull request #991 from StoDevX/no-presence-orgs
Port student orgs to st. olaf
2 parents 8b897d1 + 8104fe1 commit 8fefb6f

File tree

8 files changed

+383
-357
lines changed

8 files changed

+383
-357
lines changed

source/views/components/html-view.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export class HtmlView extends React.Component {
88
props: {
99
html: string,
1010
baseUrl?: ?string,
11+
style?: number | Object | Array<number | Object>,
1112
}
1213
_webview: WebView
1314

@@ -33,6 +34,7 @@ export class HtmlView extends React.Component {
3334
render() {
3435
return (
3536
<WebView
37+
style={this.props.style}
3638
ref={ref => (this._webview = ref)}
3739
source={{html: this.props.html, baseUrl: this.props.baseUrl}}
3840
onNavigationStateChange={this.onNavigationStateChange}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// @flow
2+
import type {StudentOrgType} from './types'
3+
4+
export default function cleanOrg(org: StudentOrgType): StudentOrgType {
5+
const name = org.name.trim()
6+
7+
const advisors = org.advisors
8+
.map(c => ({
9+
...c,
10+
name: c.name.trim(),
11+
}))
12+
.filter(c => c.name.length)
13+
14+
const contacts = org.contacts.map(c => ({
15+
...c,
16+
title: c.title.trim(),
17+
firstName: c.firstName.trim(),
18+
lastName: c.lastName.trim(),
19+
}))
20+
21+
const category = org.category.trim()
22+
const meetings = org.meetings.trim()
23+
const description = org.description.trim()
24+
let website = org.website.trim()
25+
if (website && /^https?:\/\//.test(website)) {
26+
website = `http://${website}`
27+
}
28+
29+
return {
30+
...org,
31+
name,
32+
advisors,
33+
contacts,
34+
category,
35+
meetings,
36+
description,
37+
website,
38+
}
39+
}

source/views/student-orgs/detail-wrapper.js

Lines changed: 0 additions & 79 deletions
This file was deleted.

source/views/student-orgs/detail.android.js

Lines changed: 116 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
// @flow
22
import React from 'react'
3-
import {ScrollView, Text, View, StyleSheet} from 'react-native'
4-
5-
import {Cell} from 'react-native-tableview-simple'
3+
import {ScrollView, Text, StyleSheet} from 'react-native'
4+
import moment from 'moment'
5+
import {HtmlView} from '../components/html-view'
66
import {Card} from '../components/card'
77
import * as c from '../components/colors'
8-
import type {StudentOrgInfoType, StudentOrgAbridgedType} from './types'
8+
import type {StudentOrgType} from './types'
9+
import type {TopLevelViewPropsType} from '../types'
10+
import Communications from 'react-native-communications'
11+
import openUrl from '../components/open-url'
12+
import cleanOrg from './clean-org'
913

1014
const styles = StyleSheet.create({
1115
name: {
@@ -28,123 +32,137 @@ const styles = StyleSheet.create({
2832
paddingRight: 16,
2933
fontSize: 16,
3034
},
35+
description: {
36+
paddingTop: 13,
37+
paddingBottom: 13,
38+
paddingLeft: 16,
39+
paddingRight: 16,
40+
backgroundColor: c.white,
41+
height: 200,
42+
},
3143
footer: {
3244
fontSize: 10,
3345
color: c.iosDisabledText,
3446
textAlign: 'center',
47+
},
48+
lastUpdated: {
49+
paddingBottom: 10,
50+
},
51+
poweredBy: {
3552
paddingBottom: 20,
3653
},
3754
})
3855

39-
export class StudentOrgsDetailRenderView extends React.Component {
40-
props: {
41-
loaded: boolean,
42-
base: StudentOrgAbridgedType,
43-
full: ?StudentOrgInfoType,
56+
export class StudentOrgsDetailView extends React.Component {
57+
props: TopLevelViewPropsType & {
58+
org: StudentOrgType,
4459
}
4560

46-
displayContact(contactInfo: string) {
47-
return (
48-
<Card header="Contact" style={styles.card}>
49-
<Text selectable={true} style={styles.cardBody}>{contactInfo}</Text>
50-
</Card>
51-
)
61+
// Using Communications because `mailTo` complains about
62+
// the lack of an available Activity...
63+
openEmail = (email: string, org: string) => {
64+
Communications.email([email], null, null, org, '')
5265
}
5366

54-
displayDescription(description: string) {
55-
return (
56-
<Card header="Description" style={styles.card}>
57-
<Text selectable={true} style={styles.cardBody}>{description}</Text>
58-
</Card>
59-
)
60-
}
61-
62-
displayMeetings(meetingTime: string, meetingLocation: string) {
63-
let contents = null
64-
if (meetingTime && meetingLocation) {
65-
contents = (
66-
<Cell
67-
cellStyle="Subtitle"
68-
title={meetingTime}
69-
detail={meetingLocation}
70-
/>
71-
)
72-
} else if (meetingTime) {
73-
contents = (
74-
<Cell cellStyle="Basic" title={meetingTime} detail={meetingLocation} />
75-
)
76-
} else if (meetingLocation) {
77-
contents = <Cell cellStyle="Basic" title={meetingLocation} />
78-
}
79-
80-
return (
81-
<Card header="Meetings" style={styles.card}>
82-
{contents}
83-
</Card>
84-
)
85-
}
67+
render() {
68+
const {
69+
name: orgName,
70+
category,
71+
meetings,
72+
website,
73+
contacts,
74+
advisors,
75+
description,
76+
lastUpdated: orgLastUpdated,
77+
} = cleanOrg(this.props.org)
8678

87-
displayFooter() {
8879
return (
89-
<Text selectable={true} style={styles.footer}>Powered by Presence</Text>
90-
)
91-
}
80+
<ScrollView>
81+
<Text style={styles.name}>{orgName}</Text>
9282

93-
renderBody = (data: StudentOrgInfoType) => {
94-
const {
95-
regularMeetingTime = '',
96-
regularMeetingLocation = '',
97-
description = '',
98-
contactName = '',
99-
} = data
83+
{category
84+
? <Card header="Category" style={styles.card}>
85+
<Text style={styles.cardBody}>{category}</Text>
86+
</Card>
87+
: null}
10088

101-
const showMeetingSection = regularMeetingTime && regularMeetingLocation
89+
{meetings
90+
? <Card header="Meetings" style={styles.card}>
91+
<Text style={styles.cardBody}>{meetings}</Text>
92+
</Card>
93+
: null}
10294

103-
return (
104-
<View>
105-
{showMeetingSection
106-
? this.displayMeetings(regularMeetingTime, regularMeetingLocation)
95+
{website
96+
? <Card header="Website" style={styles.card}>
97+
<Text onPress={() => openUrl(website)} style={styles.cardBody}>
98+
{website}
99+
</Text>
100+
</Card>
107101
: null}
108-
{contactName ? this.displayContact(contactName) : null}
109-
{description ? this.displayDescription(description) : null}
110-
</View>
111-
)
112-
}
113102

114-
render() {
115-
let knownData = this.props.base
116-
let orgName = knownData.name.trim()
117-
let orgCategory = knownData.categories.join(', ')
103+
{contacts.length
104+
? <Card header="Contact" style={styles.card}>
105+
{contacts.map((c, i) => (
106+
<Text
107+
key={i}
108+
selectable={true}
109+
style={styles.cardBody}
110+
onPress={() => this.openEmail(c.email, orgName)}
111+
>
112+
{c.title ? c.title + ': ' : ''}
113+
{c.firstName} {c.lastName} ({c.email})
114+
</Text>
115+
))}
116+
</Card>
117+
: null}
118118

119-
let contents
120-
if (!this.props.loaded) {
121-
contents = (
122-
<Card header="Organization" style={styles.card}>
123-
<Text selectable={true} style={styles.cardBody}>Loading…</Text>
124-
</Card>
125-
)
126-
} else if (!this.props.full) {
127-
contents = (
128-
<Card header="Organization" style={styles.card}>
129-
<Text selectable={true} style={styles.cardBody}>
130-
No information found.
131-
</Text>
132-
</Card>
133-
)
134-
} else {
135-
contents = this.renderBody(this.props.full)
136-
}
119+
{advisors.length
120+
? <Card
121+
header={advisors.length === 1 ? 'Advisor' : 'Advisors'}
122+
style={styles.card}
123+
>
124+
{advisors.map((c, i) => (
125+
<Text
126+
key={i}
127+
selectable={true}
128+
style={styles.cardBody}
129+
onPress={() => this.openEmail(c.email, orgName)}
130+
>
131+
{c.name} ({c.email})
132+
</Text>
133+
))}
134+
</Card>
135+
: null}
137136

138-
return (
139-
<ScrollView>
140-
<Text style={styles.name}>{orgName}</Text>
137+
{description
138+
? <Card header="Description" style={styles.card}>
139+
<HtmlView
140+
style={styles.description}
141+
html={`
142+
<style>
143+
body {
144+
margin: 10px 15px 10px;
145+
font-family: -apple-system;
146+
}
147+
* {
148+
max-width: 100%;
149+
}
150+
</style>
151+
${description}
152+
`}
153+
/>
154+
</Card>
155+
: null}
141156

142-
<Card header="Category" style={styles.card}>
143-
<Text style={styles.cardBody}>{orgCategory}</Text>
144-
</Card>
157+
<Text selectable={true} style={[styles.footer, styles.lastUpdated]}>
158+
Last updated:
159+
{' '}
160+
{moment(orgLastUpdated, 'MMMM, DD YYYY HH:mm:ss').calendar()}
161+
</Text>
145162

146-
{contents}
147-
{this.displayFooter()}
163+
<Text selectable={true} style={[styles.footer, styles.poweredBy]}>
164+
Powered by the St. Olaf Student Orgs Database
165+
</Text>
148166
</ScrollView>
149167
)
150168
}

0 commit comments

Comments
 (0)