| 
									
										
										
										
											2015-07-03 17:40:12 -07:00
										 |  |  | import React from 'react'; | 
					
						
							| 
									
										
										
										
											2016-03-02 19:45:54 -08:00
										 |  |  | import { RouterContext } from 'react-router'; | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  | import debug from 'debug'; | 
					
						
							| 
									
										
										
										
											2016-05-04 16:46:19 -07:00
										 |  |  | import { renderToString } from 'redux-epic'; | 
					
						
							| 
									
										
										
										
											2015-12-22 19:28:07 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-14 17:22:56 -07:00
										 |  |  | import createApp from '../../common/app'; | 
					
						
							| 
									
										
										
										
											2016-12-16 08:10:08 -08:00
										 |  |  | import provideStore from '../../common/app/provide-store'; | 
					
						
							| 
									
										
										
										
											2016-10-29 00:46:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  | const log = debug('fcc:react-server'); | 
					
						
							| 
									
										
										
										
											2015-07-01 15:14:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // add routes here as they slowly get reactified
 | 
					
						
							|  |  |  | // remove their individual controllers
 | 
					
						
							| 
									
										
										
										
											2015-06-29 12:01:56 -07:00
										 |  |  | const routes = [ | 
					
						
							| 
									
										
										
										
											2016-03-14 17:22:56 -07:00
										 |  |  |   '/challenges', | 
					
						
							| 
									
										
										
										
											2016-04-18 18:58:29 -07:00
										 |  |  |   '/challenges/*', | 
					
						
							| 
									
										
										
										
											2016-07-15 14:32:42 -07:00
										 |  |  |   '/map', | 
					
						
							| 
									
										
										
										
											2016-07-19 16:36:34 -07:00
										 |  |  |   '/settings', | 
					
						
							|  |  |  |   '/settings/*' | 
					
						
							| 
									
										
										
										
											2015-10-19 23:16:56 -07:00
										 |  |  | ]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-22 19:28:07 -08:00
										 |  |  | const devRoutes = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-29 12:01:56 -07:00
										 |  |  | export default function reactSubRouter(app) { | 
					
						
							| 
									
										
										
										
											2015-07-02 23:44:34 -07:00
										 |  |  |   var router = app.loopback.Router(); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-17 12:35:10 -07:00
										 |  |  |   router.get('/videos', (req, res) => res.redirect('/map')); | 
					
						
							|  |  |  |   router.get( | 
					
						
							|  |  |  |     '/videos/:dashedName', | 
					
						
							|  |  |  |     (req, res) => res.redirect(`/challenges/${req.params.dashedName}`) | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-29 17:55:42 -07:00
										 |  |  |   // These routes are in production
 | 
					
						
							|  |  |  |   routes.forEach((route) => { | 
					
						
							|  |  |  |     router.get(route, serveReactApp); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-10-19 23:16:56 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 11:09:34 -07:00
										 |  |  |   if (process.env.NODE_ENV === 'development') { | 
					
						
							| 
									
										
										
										
											2015-10-19 23:16:56 -07:00
										 |  |  |     devRoutes.forEach(function(route) { | 
					
						
							| 
									
										
										
										
											2015-08-13 11:09:34 -07:00
										 |  |  |       router.get(route, serveReactApp); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-17 12:35:10 -07:00
										 |  |  |   app.use('/:lang', router); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   function serveReactApp(req, res, next) { | 
					
						
							| 
									
										
										
										
											2016-06-17 12:35:10 -07:00
										 |  |  |     const { lang } = req; | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |     const serviceOptions = { req }; | 
					
						
							| 
									
										
										
										
											2016-03-14 17:22:56 -07:00
										 |  |  |     createApp({ | 
					
						
							|  |  |  |       serviceOptions, | 
					
						
							| 
									
										
										
										
											2016-06-17 12:35:10 -07:00
										 |  |  |       location: req.originalUrl, | 
					
						
							| 
									
										
										
										
											2016-08-12 17:19:34 -07:00
										 |  |  |       initialState: { app: { lang } } | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |     }) | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       // if react-router does not find a route send down the chain
 | 
					
						
							| 
									
										
										
										
											2016-03-02 19:45:54 -08:00
										 |  |  |       .filter(({ redirect, props }) => { | 
					
						
							|  |  |  |         if (!props && redirect) { | 
					
						
							| 
									
										
										
										
											2016-04-18 18:58:29 -07:00
										 |  |  |           log('react router found a redirect'); | 
					
						
							|  |  |  |           return res.redirect(redirect.pathname + redirect.search); | 
					
						
							| 
									
										
										
										
											2016-03-02 19:45:54 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-13 18:12:22 -07:00
										 |  |  |         if (!props) { | 
					
						
							| 
									
										
										
										
											2016-03-14 17:22:56 -07:00
										 |  |  |           log(`react tried to find ${req.path} but got 404`); | 
					
						
							| 
									
										
										
										
											2015-07-03 21:46:22 -07:00
										 |  |  |           return next(); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-09-13 18:12:22 -07:00
										 |  |  |         return !!props; | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2016-04-24 21:54:48 -07:00
										 |  |  |       .flatMap(({ props, store, epic }) => { | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |         log('render react markup and pre-fetch data'); | 
					
						
							| 
									
										
										
										
											2016-01-03 19:40:49 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |         return renderToString( | 
					
						
							| 
									
										
										
										
											2016-04-24 21:54:48 -07:00
										 |  |  |           provideStore(React.createElement(RouterContext, props), store), | 
					
						
							|  |  |  |           epic | 
					
						
							| 
									
										
										
										
											2015-12-22 19:28:07 -08:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2016-04-24 21:54:48 -07:00
										 |  |  |           .map(({ markup }) => ({ markup, store, epic })); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2016-06-09 16:02:51 -07:00
										 |  |  |       .filter(({ store, epic }) => { | 
					
						
							|  |  |  |         const { delayedRedirect } = store.getState().app; | 
					
						
							|  |  |  |         if (delayedRedirect) { | 
					
						
							|  |  |  |           res.redirect(delayedRedirect); | 
					
						
							|  |  |  |           epic.dispose(); | 
					
						
							|  |  |  |           return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |       }) | 
					
						
							| 
									
										
										
										
											2016-04-24 21:54:48 -07:00
										 |  |  |       .flatMap(function({ markup, store, epic }) { | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |         log('react markup rendered, data fetched'); | 
					
						
							|  |  |  |         const state = store.getState(); | 
					
						
							| 
									
										
										
										
											2016-12-16 08:10:08 -08:00
										 |  |  |         const { title } = state.app; | 
					
						
							| 
									
										
										
										
											2016-04-24 21:54:48 -07:00
										 |  |  |         epic.dispose(); | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |         res.expose(state, 'data'); | 
					
						
							| 
									
										
										
										
											2016-09-01 17:37:30 -07:00
										 |  |  |         res.expose(req.flash(), 'flash'); | 
					
						
							| 
									
										
										
										
											2015-07-29 10:16:48 -07:00
										 |  |  |         return res.render$( | 
					
						
							|  |  |  |           'layout-react', | 
					
						
							|  |  |  |           { markup, title } | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       }) | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |       .doOnNext(markup => res.send(markup)) | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |       .subscribe( | 
					
						
							| 
									
										
										
										
											2016-01-27 11:34:44 -08:00
										 |  |  |         () => log('html rendered and ready to send'), | 
					
						
							| 
									
										
										
										
											2015-06-29 09:50:25 -07:00
										 |  |  |         next | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-29 12:01:56 -07:00
										 |  |  | } |