11// @flow
22import 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 '
66import { Card } from '../components/card'
77import * 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
1014const 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