From dc4463800a50d45e62f865721bf91e2b4df8c219 Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Mon, 13 Nov 2017 18:39:08 -0500 Subject: [PATCH] Working on the editor UI. Needs some refactoring components and wire up api middleware. --- JoyceEditor_Mock.pdf | Bin 0 -> 28105 bytes TODO.txt | 3 +- package.json | 1 + src/actions/actions.js | 22 ---- src/actions/index.js | 114 +++++++++++++++++++ src/assets/glyphicons-102-italic.png | Bin 0 -> 1332 bytes src/assets/glyphicons-103-bold.png | Bin 0 -> 1368 bytes src/assets/glyphicons-104-text-underline.png | Bin 0 -> 1267 bytes src/assets/glyphicons-111-align-left.png | Bin 0 -> 1258 bytes src/assets/glyphicons-112-align-center.png | Bin 0 -> 1251 bytes src/assets/glyphicons-113-align-right.png | Bin 0 -> 1243 bytes src/assets/glyphicons-151-edit.png | Bin 0 -> 1369 bytes src/assets/glyphicons-191-plus-sign.png | Bin 0 -> 1372 bytes src/assets/glyphicons-192-minus-sign.png | Bin 0 -> 1351 bytes src/assets/glyphicons-193-remove-sign.png | Bin 0 -> 1381 bytes src/assets/glyphicons-194-ok-sign.png | Bin 0 -> 1391 bytes src/assets/glyphicons-224-chevron-right.png | Bin 0 -> 1265 bytes src/assets/glyphicons-225-chevron-left.png | Bin 0 -> 1257 bytes src/assets/glyphicons-352-book-open.png | Bin 0 -> 1388 bytes src/assets/index.js | 30 +++++ src/components/editorButtonGroup.js | 11 -- src/components/editorSidebar.js | 14 +++ src/components/newChapterButton.js | 13 +++ src/containers/chapterListContainer.js | 2 +- src/containers/editorContainer.js | 4 +- src/containers/highlightButtonContainer.js | 2 +- src/containers/newChapterButtonContainer.js | 18 +++ src/containers/pageContainer.js | 2 +- src/containers/readerContainer.js | 2 +- src/containers/readerSidebarContainer | 0 src/containers/textEditorContainer.js | 55 +++++++-- src/editor.js | 12 +- src/reader.js | 2 +- src/reducers/editor.js | 15 ++- src/stylesheets/_custom.scss | 3 + src/stylesheets/editor.scss | 41 ++++++- webpack.config.js | 22 ++-- 37 files changed, 322 insertions(+), 66 deletions(-) create mode 100644 JoyceEditor_Mock.pdf delete mode 100644 src/actions/actions.js create mode 100644 src/actions/index.js create mode 100644 src/assets/glyphicons-102-italic.png create mode 100644 src/assets/glyphicons-103-bold.png create mode 100644 src/assets/glyphicons-104-text-underline.png create mode 100644 src/assets/glyphicons-111-align-left.png create mode 100644 src/assets/glyphicons-112-align-center.png create mode 100644 src/assets/glyphicons-113-align-right.png create mode 100644 src/assets/glyphicons-151-edit.png create mode 100644 src/assets/glyphicons-191-plus-sign.png create mode 100644 src/assets/glyphicons-192-minus-sign.png create mode 100644 src/assets/glyphicons-193-remove-sign.png create mode 100644 src/assets/glyphicons-194-ok-sign.png create mode 100644 src/assets/glyphicons-224-chevron-right.png create mode 100644 src/assets/glyphicons-225-chevron-left.png create mode 100644 src/assets/glyphicons-352-book-open.png create mode 100644 src/assets/index.js delete mode 100644 src/components/editorButtonGroup.js create mode 100644 src/components/editorSidebar.js create mode 100644 src/components/newChapterButton.js create mode 100644 src/containers/newChapterButtonContainer.js create mode 100644 src/containers/readerSidebarContainer diff --git a/JoyceEditor_Mock.pdf b/JoyceEditor_Mock.pdf new file mode 100644 index 0000000000000000000000000000000000000000..eec5bff6e17bea9c8a2decab82ec9ec8803a38de GIT binary patch literal 28105 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 Ap8x;= literal 0 HcmV?d00001 diff --git a/TODO.txt b/TODO.txt index 3fa6c64..5ebf463 100644 --- a/TODO.txt +++ b/TODO.txt @@ -9,13 +9,14 @@ Short List: - Some Testing +- Font Awesome / Better Glyphicons - Env Configs - Collapsable Button Lists - Draft.JS - DRY up Sass Modules - Async API Middleware - CombineReducers in App.js -- Import Actions into Reducers +- Import Action consts into Reducers - PropTypes - Loading Indicators diff --git a/package.json b/package.json index f27d458..9795b0d 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "clean-webpack-plugin": "^0.1.17", "css-loader": "^0.28.7", "extract-text-webpack-plugin": "^3.0.2", + "file-loader": "^1.1.5", "manifest-revision-webpack-plugin": "^0.4.1", "node-sass": "^4.6.0", "postcss-loader": "^2.0.8", diff --git a/src/actions/actions.js b/src/actions/actions.js deleted file mode 100644 index c0b2896..0000000 --- a/src/actions/actions.js +++ /dev/null @@ -1,22 +0,0 @@ -const setCurrentChapter = id => - ({ - type: 'GET_TEXT_DATA', - id: id - }) - -const toggleHighlight = () => - ({ - type: 'TOGGLE_HIGHLIGHT' - }) - -const updateEditorState = editorState => - ({ - type: 'UPDATE_EDITOR_STATE', - payload: editorState - }) - -export { - setCurrentChapter, - toggleHighlight, - updateEditorState -} \ No newline at end of file diff --git a/src/actions/index.js b/src/actions/index.js new file mode 100644 index 0000000..cb0fce6 --- /dev/null +++ b/src/actions/index.js @@ -0,0 +1,114 @@ +import axios from 'axios' +import EditorState from 'draft-js' + +let apiRoute = '/api/chapters/' + +const SELECT_CHAPTER = 'SELECT_CHAPTER' +const GET_CHAPTER_DATA = 'GET_CHAPTER_DATA' +const GET_CHAPTER_DATA_RECEIVED = 'GET_CHAPTER_DATA_RECEIVED' +const GET_CHAPTER_DATA_ERROR = 'GET_CHAPTER_DATA_ERROR' +const GET_TEXT_DATA = 'GET_TEXT_DATA' +const GET_TEXT_DATA_RECEIVED = 'GET_TEXT_DATA_RECEIVED' +const GET_TEXT_DATA_ERROR = 'GET_TEXT_DATA_ERROR' +const UPDATE_EDITOR_STATE = 'UPDATE_EDITOR_STATE' +const TOGGLE_HIGHLIGHT = 'TOGGLE_HIGHLIGHT' +const UPDATE_CHAPTER_TITLE = 'UPDATE_CHAPTER_TITLE' + +export const setCurrentChapter = id => + ({ + type: GET_TEXT_DATA, + id: id + }) + +export const toggleHighlight = () => + ({ + type: TOGGLE_HIGHLIGHT + }) + +export const updateChapterTitleInput = chapterTitleInput => { + return ({ + type: UPDATE_CHAPTER_TITLE, + data: chapterTitleInput.target.value + }) +} + +export const updateEditorState = editorState => + ({ + type: UPDATE_EDITOR_STATE, + data: editorState + }) + +export const chapterDataReceived = data => + ({ + type: GET_CHAPTER_DATA_RECEIVED, + data + }) + +export const chapterDataError = error => + ({ + type: GET_CHAPTER_DATA_ERROR, + error + }) + +export const textDataReceived = data => + ({ + type: GET_TEXT_DATA_RECEIVED, + data + }) + +export const textDataError = error => + ({ + type: GET_TEXT_DATA_ERROR, + error + }) + +export const setChapterEditor = chapter => + ({ + type: SET_EDITED_CHAPTER, + chapter + }) + +export const logger = store => next => action => { + console.group(action.type) + console.info('dispatching', action) + let result = next(action) + console.log('next state', store.getState()) + console.log('chapter count', store.getState().chapters.length) + console.groupEnd(action.type) + return result +} + +export const joyceAPIService = store => next => action => { + next(action) + switch(action.type) { + case GET_CHAPTER_DATA: + axios.get(apiRoute).then(res => { + const data = res.data + return next(chapterDataReceived(data)) + }).catch(error => { + return next(chapterDataError(error)) + }) + break + case GET_TEXT_DATA: + axios.get(apiRoute + action.id).then(res=> { + const data = res.data + return next(textDataReceived(data)) + }).catch(error => { + return next(textDataError(error)) + }) + break + case CREATE_CHAPTER: + const nextNumber = store.getState().chapters.length + 1 + const chapter = { + number: nextNumber, + title: '', + text: EditorState.createEmpty(), + } + store.dispatch(setChapterEditor(chapter)) + break + defaut: + break + } +} + +export const foo = 'bar' \ No newline at end of file diff --git a/src/assets/glyphicons-102-italic.png b/src/assets/glyphicons-102-italic.png new file mode 100644 index 0000000000000000000000000000000000000000..376363c11ff5547199cc0859a0a26220e7eff5ae GIT binary patch literal 1332 zcmaJ>OKcle6rCh3O{}&eg++pdG@Y;rqT~5^#`BS##P-;&QJuQ3r5F&%&-0$`Y39ew zGj_5HEeLf{A`nzmNGL@tSRqkpgHF1*9H}{m?wjD% zG_yylRw~muFF>>$PqHSTRA@zu3$mg}$_ZNJ1)1X$T!LrCgf8*AB+`S2A<+WZ)GJ0| z5R2T>OdDfg=eTaS8}BCKUeMwMP187DcWWij<7&0iP4%Jm)x3UVZBjSI~VL53~-eYd+#CDD*mkN&3;8 z8-hvg9v*0D2+fh5-wEt~p3vlwjU43SkdPAkj0ki6Okj})0^9J+PV}{Cq?t~~f_hTU zCleZDv?Z;hbm~uN}|aO@Ni%0 z_QsiLNGAS}kZww_2?gF{O%utiAP|>8Qz5y+rm3l#2AVv>5sJ{%v4w3knBI(y2a;_? z6QtX~ZIM#35H&%^#>_&?Uh~_Q>A7Kwi>A}I2%szd5uO zjMwC>tZZ4&Z=Cq$wQVidzI$*!l}f&}^x0YJxeumaxKp3n+Fa_4fA`;MRhr$JdU0vx z;*XovUw1anC&gn|g9ESry>REo^v6@_dkY_~-ukn8;pdOOEF8)nfA+1*^VedBXUf;t zH?Lfoz4Yny?>FE0;`-6Yw0m>6Z%_Pj{waHouOHiZCpC7lyfprKZD(^rsXudk=Gxo6 ev77T_lRQ=4e*d4>-(4Gv{>O^>W#f}<{lfnx{IJFV literal 0 HcmV?d00001 diff --git a/src/assets/glyphicons-103-bold.png b/src/assets/glyphicons-103-bold.png new file mode 100644 index 0000000000000000000000000000000000000000..ec61fd9c2c50ef0e4a11cf6087f30f472df07034 GIT binary patch literal 1368 zcmaJ>U1%It6dp7+-P#{)9$FWzB{y^LCS&H$ znY+m*4@N{0t*EtDeX&%nR!~EU5h@CXRH~Nx(1t=$6e?<{U|Wkn=!1A?vzz9jbYSP6 zd**!SeCKbUE%oo&ur9uiqNojpK4XBK9ptxl?QPNfwNsnOaVO4K@Ss=46CglT7J9>o zE;wKW4Ils~ANv}0Q&ihpt6agA;zOG0ISCNiBB2B-SV=G2&}LT2|ay1T9s2M)r3t~<6HYV{1$@T(CyQgaO5 zFu`LPW|>r_SfX_=K(v%dvnHRGX<1DOk}QkzgLIM?B#uvUDV|NHG?CZDB;9-%5-osL zZNTVl#v->2Gm5dVaoohjL}DV9@PZLeP*s)VlUy>%5(_q*bTO#2ZrIuKV4%@D!SRd56~}JaEEFjjR|h^PBzVqoqP!Z`As#^2Y245{EKmA~8$h8~ z3ry0FYG(^fYIpNMEkkIo*!i`_~&7K{v2 zt65M>OZjw4< zJBq-x+(@}I>SmKK3aoJidjrp*8|~1n8?Yc_A@h;~SeTR*Rut2a1&Tr>Q{kZkh9x;w zWtw=ns&vcaOf)1DzePwhMOcLbZ?dL|BvufJOQ0%{Tw&Ez6;%aQp5X{ZXlmHPHfm09 z*2YcAwxS8rY~YTNQn3(KLCwa@t`U3EAGJ)+4ZFE$I&F&p8qzYBTjjB#UNz1wOR^)8 zxU!t&va;UDB|9CE<=yjZdX_ByF9jo8u7CT%A#le@di~SkU@6wuliOatW%Em=*g-ya zh>!KX-gXx}x@G*GqPyL>yl;B$VrS2`HPn3n&u{HLpc@yS8y2YdbGMp5;`ZYUpS^No z=k$*F{vS@yK6B6W?e87GTO2!|InsIhi8JSaJ9+l)+fN<1{M6*d?~lFu_?L%2S!}<$ zBrd%xi5FrIe4#JKhuY$szVqKq!WTCl8(KL0O>Wy8N3V=iOKa|xKkWExL6KwsoIN*p zr1I$O!t77$yUy(I*t&7P%bERS-wWB_@4xoO^n+_6gDi-)vCQAu?0bmD+Gu-{)rv`u-R^6J0vPuwrQm1n90l}vDWq&d(wDU z9CkVIQz0R7-~tCO+z=9HkXR}X%c&eHfsl~k2ECL@t%MNLGWI564^=J2^XB<|?|ttt z?{96sc4p=26^`T1w3=>*olmmg>hcrp{m-Reud(AS^?LLQ8PX|8FjqrlfcaJkM!16k z+IjN_yvA{lE&JUb?X_RGAqh($w<%>|%+MUSb}@?q+{Tn2;E^9yg*#t=EAT$53Rm^E z+>RYQ_M5v2zOuX7g}d9(Lc+y$el4?^gAh}|XJHVfc2*S%zc!O|wIuL`3Ei#=$E14g zE#4ss=JirVgmT5;4XdQ+hM^f3cvV((NiIueSyaomCfl0I&mMtAOVH5nxQ$sXcB=|w zN@H7+rqgL@S}u`fBq^3m$FbSI)96QlI}+=Gi#nD{aENyO(K!GKI?RbWhy zQwZaBd*L`rXN6)VlQIxXN=cT&Fwd*7PH6}KPve2sX?G{aQU|AGl0epv;rTh3)$ZYe z=7tC^?BYoh6nP>j;Q)s?qA4S#6pR>i`;EkB4FrKp;3WUra;w5*;v>7FdzG>!SImmj zP!zXbt9Ytwnug=moVq3(d9d8UNg&gd5W{*}LvcLQG4-;hD4uS5n%r<@Q*kYJ)E3xQ zlu{5uoCnRZKEt|=nxm`rhhuFg!GMyaOGq#um8~(MBps8OcbsB0_?OxM`cbZYIq&9- zFHZbx7&Q_S@UyL7VzCz_aPC1#~6_em+5V0HP5q zm5A^VOadybkAj_e>_ZZzYf?U)fzJSibc~fwcr4T>#(8eZb|e=U%gHW_^~Mp~>4YtB z{okz47Jt9x*1Fj*1Jv*TeRIP*_gXC`m-+jPII H_uu{xy(OE# literal 0 HcmV?d00001 diff --git a/src/assets/glyphicons-111-align-left.png b/src/assets/glyphicons-111-align-left.png new file mode 100644 index 0000000000000000000000000000000000000000..2365b1d9acc39b2f126b217703025e7b0441acaa GIT binary patch literal 1258 zcmaJ>U5Fc16dvg!b+y7mh1!QQ%z|2Qel!0hyCyS%R%l(c@Xt?2+}jPsSj{OdZ7=m~Dq(fIAqV zt+%e>D#Oej^t(OM^HyvahXN>Uggi_rnqjKTc>>@jChP_t_)(4f!TX?n&wGf z;^3iwVmrm_+pAr;y$LPEEibXv+@=mfOaPmQL6q5fjVt}yR4&va$Cf5!v&QX_>UnFd z6Q`Kf1f7SHZm@F5f3qIS52*~*;Tbz1uaRyUAA$}aOg-5Uvk4TN9O!ra< z6VIDDjAmDU;Q;0H7wYMphr5-fIb7LQU$`_W&Vf@$p@9cXHZ z;LI)=r9qh|f+7xZh$E6wQgX?NGPh5qK5ZZf+!&6EuWh%+jYdAQb*-saEJ-(YrzOj7 zqpmj<*E9{MS$7($WE8;)2m66kBOr=x>6W7Ej$>*SRhFBY*;J*LE19xu(W5@Ywxf)I z2;w4Wf%P9?8;``=PKp7E({3CG(@|L)#w5;$al$%IIU4K>9)NySD32H2obbh||29Ug zG!EIa9k%}v7IZ8ONizYD6vO0IRYyE9O)5cCLMGVIj7p!I;L*O)?Ts_l&`gpkAsecw zk7Nn*5Mqs&W$F@GCZbo=hn8tspf7PErHG(Sd=lWv^wtA1kpjP%AUgojfR>6!xDQ4F z;g$x$RxV4xpwWK>zh_mISm)Uybi0*Vsm-nx0PrgSN zKX1GBZvM-?v#-uyW}kA_#V_vs_u=-=#VfadeCemgCGo)D7ry>|@#wq9mhO93@0>b! zyUzgk&%<&%>O-tBXDjoo8!{<`}4 y@T_2PNbuTu~?EDX;%$t}1 literal 0 HcmV?d00001 diff --git a/src/assets/glyphicons-112-align-center.png b/src/assets/glyphicons-112-align-center.png new file mode 100644 index 0000000000000000000000000000000000000000..9a17fe27bcba1808cdf050dd41357f492bb6ec54 GIT binary patch literal 1251 zcmaJ>O^6&-5bkv~gh)^k!R*DRSH!>mo&IMgo7wK^>_}!^Cj+jK!@ha%%}lfXm+m*t z>>fmdhj|#1#6O>b~Nzy*$+c6r_E=6ST z@-15DxJOThy=}JLx!~e7mQd*yF?_!4tYiIfT)P(>sWr&}~QBt_mhET#n+U{)e zUYb+hkW3LPro~&1q#Bl`Td(q(q8hSNlWU5o)m&Y1b&a1r0%Xg{!0r0MEEi}EVZ>PG z%JO6~ktQ`M&4;q;IF77nvZjgPAr^ZHLsKy+R_76XTHrj)SePb!84>l46G^ymt4 z*6Az)C&jE#P%?RnGFg=rIgZPFRo(^b(*J2Z(7WjEWmN9cA|2-#`Y~9YgQ0d0Pc(NV zc;T0g^QgKf!7`0#OcPcBDYaq*%-z@X5E_UgKgHwnYuj%K<8eq_(`cDBM=@>F3slu# zZ<;O5w{6R7HNACRvC3p+fa5^0NCdEf>1ev?E4ES7RkdZyK8$N&qjD@8bHWGxMytdjvz z6)a**4N+AgBywy5Dj8tMb{sTN1Q{q2?6QzWbT+-sh|Q!ZEGNi~P%?y4iG&W&IAX%t zVYHWxLYyW=T`s3H3IR|_M_Bn-#L9eZoadgfBc-@lPEZ!>O%vGZ9G2JI_|JsJzufkl zz3H$0e-97WmbDXCo;Y{+lM8p3eyayxewzJo^XAo;&k5YM8&`iGUjOW1^|1r|$B%z6 zeY5oR@&`+|#hv%QSb1mVPl()97!TX3Yq3RP#VVp91!=(~FaIWg*lC?fX4*k#cbN`!D0}ejdoMF#le{!} z)5-2h^isVEf)^3-=s~atJt$N`4^?^=J?KfOMG!;;1+6dHndu%%1C#f?FW>L`e&4@& zb8F-L@ng>%69nOS??N!(=Slv1a`j>U-u_j2fgew^&WK&4A)CRR2rW!^h}cWum<$NS zdsl9fbwN0~8VyHm)PKc8G*Mt>qm)U;(SopkuFN3XB~08Q<0x%Pzkhy15+mG{E?Irh z&wMh8F6`&z;{L`E?e8KNOXtpt>!rsXB!oe+Oyacg%BEEN^|)NARY|N(*ltrgAT{c5 zi9XGVXekXDfrc&GuA*7CZQ3u2I?yZ?7^(qe-SAA{nYuWCBpxltp*IM+^H}`WlqQU2 zo~q7fGi7EdG#{&)>$)n?Rb7|4g;uj#T1uIr(L|-X!Hao%7{=`RxxdU;L;S zw1(x6zrCZK_!6uh(eC_o_wMyCUb{a1W{tXMZiXwPZg}|-VYB(!m7~{Iq9gD9ee0zg zKYz7mYk#bKzxnQ;GcbMB`0(-D&p-8qa{1f$|2y&N_AlT4P;7twhWFNE|6JX=^wIgX e_P^yrCxvUzo*w`8+$W^^yXkc{f{)v;zWzT_y^qKM literal 0 HcmV?d00001 diff --git a/src/assets/glyphicons-151-edit.png b/src/assets/glyphicons-151-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..bc03d5a457c1e6bca25cc51ffcdc45432b5cd41b GIT binary patch literal 1369 zcmaJ>TZkJ~7>;yzsjFe>gLG@_GEQaP!cOLr%$3b9*-WwL-Ka~%Kf+Bt&XhkuDo;$sg=t)OM6gzB0HLkZv%A(64P zGR#8_G@rTxXF{Q&okn2=tz;imbjONlflZ`gxfmS^&CE4iO|L>k6k*x0xZp<3WOt2$aqUA|c8VmKVjCI8AU2%hODhjxrP%Rbq@1*(Huu%3(9ZWNNZ5GzrXK6g}&|?E;1aO2s~;< zr-tGrX1bMvyLF(xA#nXAC+9iL5^Q>Tq2q5js`K6)pWxS zlm~)t_V_~2cp8GV=U7Cy9g1-i7I-W~hL8k~vSC#2{xPy#HYQ@Rd$ie<4&O_l(@f|4#vvaFRDlExH)t{?-Mus6L46ZIt1 z2qs7|HM@*UMFCjSY9=CQ%VyK97`kKoGjuSWrhx%nX$wnl^Vn5y8|S_y-jP5YEGNDU z)*IS*r#-y9KeGPgc=0zgYNF8iX8n~;_y}?5(az+1yY_X`?$AQ<$cYc8&Of*J%ZFAw zttZ=V_WQBQwTXMrDk_Snb}haX`|a1cjYI42WDfqjzGKYgjvtU;{(1TkIdbWznU5!? zPOkk>d3J2{#3%PHUcV@hzcy?~7|4HAT98hkZ@rK|ccne@n3cQZE$;1&)o|h1^^Gs? zuX1a%SMT|6c=Pb;`>m^|+J9BJwQJtjrydEP9as5@+1TWB0r7+z@_Vl;?K4JnikQ^8a^x80qcOS4HgJG;%+Y>b<=E=sABbIxYR%*~mz z-Q84+w})C&QIH^tsFfm>G-?$TDw;f`w&DdN7V3+nr6_5n(ieU4a%Qu;%|q$H&iT(j z|M&mjf7=&FM|O90Zte_)LS305El1AH!LOs8yie>I{+=8?I90%7P7zmh4}}uY8Anvc z(kD<3>9F?XIn);lwRITz0xo2SRp3~x9@wx|%O&VgsBfU^>R=LKY8*`%cAUO?`YW0; zV4QwL%<@?`iAu)Ml!wNqM)F{45-5-!=%@OsDsf;TtW#CXw0*T2r|W)IA_r=Yrs^hm zGET3NDr85gq~jqc|qj(2p8d*a72yrYBWqW9-2h+U{TF! z=|(Jai_;~HU6tc1l?q#lu#Pvu35ud{e3%P|8DhcsH5=0J!r@Wp5bD{v8lkL zKJJupoF+`yQn1`?w&mFN8-*ez z#cfS6sol*3H4PzX*|}xUtmg>CAoEbx$3-bpq#Jm+ zu5@eTOf)1Dw@F9^QCNfm4;TQD$Or;)sVg!hS6Bp!tSEYsr#V6q0u>wBM2+c9n7ARC zMleCDsoN8zR18E#y=-E-f5NP}B?CCN-^T^hX&MAjm)5Y{I*)brx^Zq=k{t=e)^d_d zYrT<8cG@G$`%l}FL>7M~qb2gyU%uG;Qr8RA?Z=1bJEos`Q~BoT#op=p4tsvnhVGaD z+`Gdu6vMLkh#`?qcWqfeLFxgYn?knbhZ@ssm)ZTdYfn)ES*!X1zTW`;v-E*pIf%@yn2e1A5S^Lb)7UR?>i@z@p zEr36!M^ApYO>7%Q6y8I~pJWiCmD&pEu&LBUu-+fr`-h$2c(N^7~Xog8nwLFMcF##*MYB?$P&nsWBz%o

m2*BiD^Z zZz;A$h^O;>v)PO`V^PwwTBTyYyD z#ZsobDb&3}q3_rUx`m=8<6F?<#i+p7>tS9U>wuK-|1|Dv9hBQ1=1Vwm8$P1_sEqZ% zv~~{;)H5_u-_C3Jb|+60@z}<7?2v$x5<842bN!fa(FQ`>a8V=tnm1BxqhXo4oXE;C zO^{VNlM_W_IxS}Cc! zwiQm0ZbPR^OU0SE0vk4AC#!bbt69i(f+QbKr)^O{N7}{mdpvg3d&aqENp~a^`^!l$ z{q@EU-Dy8u-Vf8K=;GhX8|iZE&gbvF9{CasXFq;S-56_~*5_tU4CH5zdH9Xn*9$>}k%!LkUx{lY#&7w* zhh`tW{_n(iW^)Q;XCC?E+x>@6UViq{(g%NmkKVsMH2%xhkt08DY=H60VBY|=M&HGs z{Q6V$&fF^hV&uY`uO4j|cP^x|muk)J(>Fi8yLlGfyEU(DpItln!&YeP|nH7|&*rEE;D8LAO7=U57aJzVdNjZCaCD+NLbEWKk=)+3WkhX^vj*u6J*2 zQbk=5+!)NN`(n<2v?!BNwcGr|4)hP1PIOGBh%#|7v8_%9P80>j_tK>6A7cl(_j#Xt ze$VrJzOs90urD0i5DEkW;cUN_C+7zL7rdFgj}B}-OOCs7W*Bd?i+ECZQ6LHJQAB0S z`WVV19o8n!psqlmEoc;m@o;Xd3hXkg`!;N~>=1My(A86QbTE!EHHyXzD?wkG|A?jx zn4lkv=lGnHMkS+v%0=6z1`A+n94L_P>884>DsfOoSf{FG)AH16f^PU#iR`O6nrfKf z@dUk0YB)DUrEM2caaLpiFG`f8utHptV$y?Dgcsr*ALXJv6N#!ZUX4Yl=0lTcE-b2f zt+yGA+!AyNV@Kt<$;nA}GRoTS7$+!-!toI<5@Co1&WE~ij-a=8`9me(v4DH&JQ9Zq0*u3Yx>YFK+XkFL?UuC-UFIf%<6&#t(D z^rP6(0+ZU^I8e(Ff)zWb;+l;-A>fdS%E-bVAtf{z5$5W{u0a~8o0<(O{@1LQpeq#v zs$x7NMipL^#dNPAXsM)_iD}hipCHxLtuaz62BM-~F)`geX4agN0c^|b;{53}4FYIL%UEue$A)^EH7+GxKMEc_4vuN;H&w~wN2vX%DKhoPJHnG-uo|&bc`HO=STSm>|bvgKVSdi@HIrJ o_2z{?CVqc+;lS~!hn{V_D^QFuv-Qq(r~N;^Y-UiKO^ww52hFtASpWb4 literal 0 HcmV?d00001 diff --git a/src/assets/glyphicons-194-ok-sign.png b/src/assets/glyphicons-194-ok-sign.png new file mode 100644 index 0000000000000000000000000000000000000000..bcd36a9de66949f2a6b90393241a317c34af4117 GIT binary patch literal 1391 zcmaJ>eP|nH7{9JgN|!-fP_RRMy;kTpFL#$*avwBnJ}y}!OV_obR#EWs-kavkeeLdz zNdtpz`iCDl>ePWc#DRZocE~_wI5&n9ru)N*1(^!YG0@>;IEw!`6@4#Fy8bbCkb9r^ zx##yhzvnA2O-^jz*gM!uQPjr#xH?77!Qj_(FL@t(Y{x}%Jb<&ac-krBy5=D&r8^}A z@|HG-rjVx3@4kRWDe9gcqd1Fa3p*6(SYa)&2{$a4pebr}tl?^~iZCdlIm1rSe|&b9 z28N!XACDEdf}24VW4!61>E=WcHmgw9>9K8Kw4o3O7Qz~6Sf=eOjRf8Ds}MO*vovU# z;A(X6b1275aIY3%SG8J$3&uvz$romv>%#8^YpSZ zrRLhP$SpxvFm@G|t=H?}dNk~Kb1W~*GRsBSNQ5C4j6ZKKWhqqSe0cM&^r_dp#(9j@BBHP3A2sY4c-$U-*u2`RqCh%i@ndIo8rW~vUX1z+=Og09sJ zU5UrC@u95;NIUCM|Gc5G-)87DzN$VdE3XD4N(v@z#6x){9Un1#zPu*yrScnol%*rIN0$kjterG)@Xo{ zf(8vcP;L&o+2)Hp<2j_~JjVj9b|}W3Sje)-#Uzc=E z+jxCV=~l*>Xhfn5loO`YW5r{6{DlFRx>fZZO)u`D+Y9If0PZT(=-U6C9PoDH6B~)HRIf|Bs&s_ ztIJ6)tLu$yveO<}-hMx%k;VTvucnHPA5S0Z>i+_SvafUxgChf5w1EX~^LX;y`^9ww z*TK-q6Y%5Y-UF9^Xg=I!0NSD8L=e);Iv(!Nj9 zAAmjI9(wn|K9J*Ur&2Jk;6rU&%g_hE&5}*X3jJ7~PV!a>UZ^ccW-8FGlhsbqR3oeXj#`Y@v)!lLJ zHQrf>iWQUT?_g#+Ar;|3?hiFVep-5jc}*I8)#8n*2P=e=jUA@%Q@KyQ}(h#A_v!hrkemf zwH&nCtlhZm;3O)c!lpEeQjP{-b8D0$yiXbI&|VN%gulQ2PJjWa2-oz6+(=#84|WbS zdgXApg%9_!O@yrraC78v2N7imj-oKmol!-Y_;t8ks3ieTOxS)!I40F@>_IolDAY@a zh-Jfsrd?8W)6~p2p(-o7B$uVKEUINklO0Wk(?{UZGSYRLUTqqS-zq|%vDA^I;c!?Q zmP<+2lN8&wC0UhJRpb_8eh@P>665^*%!5aBoCPThk{A{qQ70L&iols3rx2x$#@un7 zPYcCMCXG-kDJ5Boq9U(}b*W-)sRi4FeoO-2~phRr4kA4qCv=n3%&3l z?FTrC^G&Ik&M@GBiFAyWPI#QCPmJ@-lJ7_%&X<#4=Ic#kzS9|B-hb`#J-+zw*S%_M z^k?V42M@LupIxjjtel3Q-T&dIwHJZ%$@LG~i@)jrZybSe?WQqaxb@eTy)+(!J4@eR zhW7y3_&fyPtnaAcUAPi~+k3D40$y9X1b+Xjabx_&%U8+9xlg~`cy;xoXKsO)zFz+E sxr_e#Kegxo_;}&yXywk+@Zxv@xbFz(e!Y~OF8+k-{;qd>`@Ihz0)@DY7XSbN literal 0 HcmV?d00001 diff --git a/src/assets/glyphicons-225-chevron-left.png b/src/assets/glyphicons-225-chevron-left.png new file mode 100644 index 0000000000000000000000000000000000000000..2fffbd355c8ccd05c9633e784593c059370c911c GIT binary patch literal 1257 zcmaJ>-HRJl6d!f5Yw235;-(@v+(og}$$VtKNxIF>%yt82UDH5Q=z}-+-bsd?ug=_< zWI!Z~&pmT~=lsrBKHAy7 zvU2*R(;UaGw6@$1JI}J;i_1^5_bX?AJI{{u)a%i!iBHEcBU}?FeZsdQI3OJY@$}|B zQs=m(<)GW6z4n_nN}?((Y^sweWoVA8uTN5lb_wPCWDvv+@bJf<03YB6xTdwGcIuE} zu(g+wt9#pBw6}{a4Aw94^@+_KM1(?q5`}SYPa2@~Ycsh}i-0dp=xzfXlj^m1cqhpS zuT^ycNxH!sR#nyvLp9#u6-m}asV3GWL8;lQWUC54djN};Vc+h!o3mK#)&N6FQ(F|r z<8gIdt0vh%lr75=B}G&efmsOoG^TJO#QECXgG+Lh1t|@Zm@hoSelnsBz?dGV5T)(* z!f~9>3dKq$PGBm^RY{DZBCpaqrycS?jYnGN-Dyh14#|^IhFCxRwK~1u5 zPjOAtaJ;6op-M&(tZ;A=$TU^Vu%0PvyB0f|3v4USDU1;* zf)?1Iz$&V#I>zI%wv!P^ldPL0;e1qfh6zpbVUqHWQ;r7zdK;o3E|eFFZqE3UEO?jT z%`A!dvK@Bt2o`KC3`sMgfEB|OR8_|UG)*QUQ^F?fYevlnGdw;~y5n(X8kR{qCuAcP z`&gEcfDq9HS!OPwWny;4KC(>9g1!VqMiC>M1~eqI>1~E|CWS#UL3Rk^0V|b&i4R91 z1(yclG#v&giSxQxOlKG{Kq(z##S_c<=$B>{(M^Aw)@@2J0JW9nskjI literal 0 HcmV?d00001 diff --git a/src/assets/glyphicons-352-book-open.png b/src/assets/glyphicons-352-book-open.png new file mode 100644 index 0000000000000000000000000000000000000000..5108d41d5b966c5553b34e28f972cc3225edd2af GIT binary patch literal 1388 zcmaJ>Z)_7~7%z$w7p4}1n}G3hi$fBxch_Eff6~IbUb{7}b#^sdh?>2-_w9Q2dUv~f zYi~=yKv4dO_yrOZ!xuosM2#AQqN1CT1QJE|#Q^@rNF)(~kVuSQ^u4Yf`#`v)_df4) z&+mDD&%f>(%J+A)uWk&B&C*oE z1XmLDJgL##5S6kVL`6d}M&n{4CCVW_DvE;m7!~IDD9c6I2*-pYiohvCm})*WiRQqP zQcyF^Smc(V%NW}V%hv1lP(2c|oC%hfWtru|Y&gsi3&x!?G4L4E?QVHck*hhnjdjbU ze2-w)oQZ~HVz&q>ngC0X=QKvsP?X_$;u6RbBv)9{WJ#7miKAIU5o!w7v4NV? zn>27!GIW1}6a$zOq*M$P6$+vLrj= ziwnz1E(`08OtRAsS>BJQt__mK|2L~9i{AOmPtA2~&&>z3GT|e=L^6H)~d)}S>eyq~FZ`})HFAnktFL#69Lfe6@neJ!q?D_Pq zBmevtTq3Tm%^c4hzPj?KyFN&a4emJBlQ-V^(hudE6{O;n1Z(q6ziEa4|CdeY)%W_ww*3!`ch{=` literal 0 HcmV?d00001 diff --git a/src/assets/index.js b/src/assets/index.js new file mode 100644 index 0000000..a9aa556 --- /dev/null +++ b/src/assets/index.js @@ -0,0 +1,30 @@ +const glyphiconItalic = require('./glyphicons-102-italic.png') +const glyphiconBold = require('./glyphicons-103-bold.png') +const glyphiconUnderline = require('./glyphicons-104-text-underline.png') + +const glyphiconAlignLeft = require('./glyphicons-111-align-left.png') +const glyphiconAlignCenter = require('./glyphicons-112-align-center.png') +const glyphiconAlignRight = require('./glyphicons-113-align-right.png') + +const glyphiconChevronLeft = require('./glyphicons-225-chevron-left.png') +const glyphiconChevronRight = require('./glyphicons-224-chevron-right.png') + +const glyphiconPlusSign = require('./glyphicons-191-plus-sign.png') +const glyphiconMinusSign = require('./glyphicons-192-minus-sign.png') +const glyphiconRemoveSign = require('./glyphicons-193-remove-sign.png') +const glyphiconOKSign = require('./glyphicons-194-ok-sign.png') + +export { + glyphiconItalic, + glyphiconBold, + glyphiconUnderline, + glyphiconAlignLeft, + glyphiconAlignCenter, + glyphiconAlignRight, + glyphiconChevronLeft, + glyphiconChevronRight, + glyphiconPlusSign, + glyphiconMinusSign, + glyphiconRemoveSign, + glyphiconOKSign +} diff --git a/src/components/editorButtonGroup.js b/src/components/editorButtonGroup.js deleted file mode 100644 index ec8d95a..0000000 --- a/src/components/editorButtonGroup.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' - -const EditorButtonGroup = () => -

-
- - -
-
- -export default EditorButtonGroup \ No newline at end of file diff --git a/src/components/editorSidebar.js b/src/components/editorSidebar.js new file mode 100644 index 0000000..b623675 --- /dev/null +++ b/src/components/editorSidebar.js @@ -0,0 +1,14 @@ +import React from 'react' +import ChapterListContainer from '../containers/chapterListContainer' +import NewChapterButtonContainer from '../containers/newChapterButtonContainer' +import SidebarSpacer from './sidebarSpacer' + +const EditorSidebar = () => + + +export default EditorSidebar \ No newline at end of file diff --git a/src/components/newChapterButton.js b/src/components/newChapterButton.js new file mode 100644 index 0000000..c3c4d60 --- /dev/null +++ b/src/components/newChapterButton.js @@ -0,0 +1,13 @@ +import React from 'react' +import { glyphiconPlusSign } from '../assets' + +const NewChapterButton = () => +
+
+ +
+
+ +export default NewChapterButton \ No newline at end of file diff --git a/src/containers/chapterListContainer.js b/src/containers/chapterListContainer.js index 16e411e..8d851c3 100644 --- a/src/containers/chapterListContainer.js +++ b/src/containers/chapterListContainer.js @@ -1,7 +1,7 @@ import React from 'react' import { connect } from 'react-redux' -import { setCurrentChapter } from '../actions/actions' +import { setCurrentChapter } from '../actions' import ChapterList from '../components/chapterList' diff --git a/src/containers/editorContainer.js b/src/containers/editorContainer.js index 2761490..a7d120c 100644 --- a/src/containers/editorContainer.js +++ b/src/containers/editorContainer.js @@ -2,7 +2,7 @@ import React from 'react' import TextEditorContainer from '../containers/textEditorContainer' import Navbar from '../components/navbar' -import Sidebar from '../components/sidebar' +import EditorSidebar from '../components/editorSidebar' import Content from '../components/content' const EditorContainer = () => @@ -10,7 +10,7 @@ const EditorContainer = () =>
- + diff --git a/src/containers/highlightButtonContainer.js b/src/containers/highlightButtonContainer.js index 573e55a..b7b6010 100644 --- a/src/containers/highlightButtonContainer.js +++ b/src/containers/highlightButtonContainer.js @@ -1,7 +1,7 @@ import React from 'react' import { connect } from 'react-redux' -import { toggleHighlight } from '../actions/actions' +import { toggleHighlight } from '../actions' import HighlightButton from '../components/highlightButton' diff --git a/src/containers/newChapterButtonContainer.js b/src/containers/newChapterButtonContainer.js new file mode 100644 index 0000000..f9c80ec --- /dev/null +++ b/src/containers/newChapterButtonContainer.js @@ -0,0 +1,18 @@ +import React from 'react' +import { connect } from 'react-redux' + +import { createNewChapter } from '../actions' + +import NewChapterButton from '../components/newChapterButton' + +const mapDispatchToProps = dispatch => { + return { + onNewChapterClick: () => { + dispatch(createNewChapter()) + } + } +} + +const NewChapterButtonContainer = connect(mapDispatchToProps)(NewChapterButton) + +export default NewChapterButtonContainer \ No newline at end of file diff --git a/src/containers/pageContainer.js b/src/containers/pageContainer.js index fa0160a..5a0385a 100644 --- a/src/containers/pageContainer.js +++ b/src/containers/pageContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { connect } from 'react-redux' -import { setCurrentChapter } from '../actions/actions' +import { setCurrentChapter } from '../actions' class Page extends React.Component { render() { diff --git a/src/containers/readerContainer.js b/src/containers/readerContainer.js index 048e947..043204f 100644 --- a/src/containers/readerContainer.js +++ b/src/containers/readerContainer.js @@ -1,7 +1,7 @@ import React from 'react' import { connect } from 'react-redux' -import { setCurrentChapter } from '../actions/actions' +import { setCurrentChapter } from '../actions' import PageContainer from '../containers/pageContainer' import Content from '../components/content' diff --git a/src/containers/readerSidebarContainer b/src/containers/readerSidebarContainer new file mode 100644 index 0000000..e69de29 diff --git a/src/containers/textEditorContainer.js b/src/containers/textEditorContainer.js index a78d2cc..8d329cf 100644 --- a/src/containers/textEditorContainer.js +++ b/src/containers/textEditorContainer.js @@ -1,21 +1,57 @@ import React from 'react' import { connect } from 'react-redux' -import { updateEditorState } from '../actions/actions' +import { updateEditorState, updateChapterTitleInput } from '../actions' import { Editor, convertToRaw } from 'draft-js'; -import EditorButtonGroup from '../components/editorButtonGroup' +import { glyphiconBold, glyphiconItalic, glyphiconUnderline, glyphiconAlignLeft, glyphiconAlignCenter, glyphiconAlignRight } from '../assets' -const TextEditor = ({editorState, onSaveEditorState}) => -
- - - {JSON.stringify(editorState.getSelection())} +const TextEditor = ({editorState, onSaveEditorState, chapterTitleInput, onChapterTitleChange}) => +
+
+
+
+

Chapter 1:

+
+
+ +
+ +
+
+
+ + + +
+
+ + + +
+
+
+ +
+ +
+ +
+
+
+ +
+
+ +
+
+
const mapStateToProps = state => { return { - editorState: state.editorState + editorState: state.editorState, + chapterTitleInput: state.chapterTitleInput } } @@ -23,6 +59,9 @@ const mapDispatchToProps = dispatch => { return { onSaveEditorState: editorState => { dispatch(updateEditorState(editorState)) + }, + onChapterTitleChange: chapterTitleInput => { + dispatch(updateChapterTitleInput(chapterTitleInput)) } } } diff --git a/src/editor.js b/src/editor.js index d0735dc..41e9611 100644 --- a/src/editor.js +++ b/src/editor.js @@ -4,22 +4,26 @@ import { createStore, combineReducers, applyMiddleware } from 'redux' import { Provider } from 'react-redux' import 'bootstrap' -import { chapters, highlightActive, currentChapter, editorState } from './reducers/editor' -import joyceAPIService from './middleware' +import { chapters, highlightActive, currentChapter, chapterTitleInput, editorState } from './reducers/editor' +import { joyceAPIService, logger } from './actions' import EditorContainer from './containers/editorContainer' const reduceEditor = combineReducers({ chapters, currentChapter, + chapterTitleInput, highlightActive, editorState }) -let store = createStore(reduceEditor, applyMiddleware(joyceAPIService)) +let store = createStore(reduceEditor, applyMiddleware(joyceAPIService, logger)) ReactDOM.render( , document.getElementById('wrapper') -) \ No newline at end of file +) + +store.dispatch({type: 'GET_CHAPTER_DATA'}) +store.dispatch({type: 'GET_TEXT_DATA', id: 1}) \ No newline at end of file diff --git a/src/reader.js b/src/reader.js index ba0aa75..4aec6c4 100644 --- a/src/reader.js +++ b/src/reader.js @@ -5,7 +5,7 @@ import { Provider } from 'react-redux' import 'bootstrap' import { chapters, currentChapter, highlightActive } from './reducers/reader' -import joyceAPIService from './middleware' +import { joyceAPIService } from './actions' import { ReaderContainer } from './containers/readerContainer' const reduceReader = combineReducers({ diff --git a/src/reducers/editor.js b/src/reducers/editor.js index 7717e0a..cd8ac74 100644 --- a/src/reducers/editor.js +++ b/src/reducers/editor.js @@ -1,6 +1,6 @@ import { EditorState } from 'draft-js' import objectAssign from 'object-assign' // Object.assign() polyfill for older browsers -import actions from '../actions/actions' +import actions from '../actions' const chapters = (state=[], action) => { switch(action.type) { @@ -32,8 +32,16 @@ const currentChapter = (state={}, action) => { const editorState = (state=(EditorState.createEmpty()), action) => { switch(action.type) { case 'UPDATE_EDITOR_STATE': - console.log(action.payload.getSelection()) - return action.payload + return action.data + default: + return state + } +} + +const chapterTitleInput = (state='', action) => { + switch(action.type) { + case 'UPDATE_CHAPTER_TITLE': + return action.data default: return state } @@ -43,5 +51,6 @@ export { chapters, highlightActive, currentChapter, + chapterTitleInput, editorState } \ No newline at end of file diff --git a/src/stylesheets/_custom.scss b/src/stylesheets/_custom.scss index 340f6a4..ce18c85 100644 --- a/src/stylesheets/_custom.scss +++ b/src/stylesheets/_custom.scss @@ -1,4 +1,7 @@ $theme-colors: ( + "info": #537577, + "danger": #72030a, + "success": #118734, "dark": #07383a, "primary": #824500 ); \ No newline at end of file diff --git a/src/stylesheets/editor.scss b/src/stylesheets/editor.scss index 90ff14b..87843d6 100644 --- a/src/stylesheets/editor.scss +++ b/src/stylesheets/editor.scss @@ -108,13 +108,50 @@ nav a:hover { border-radius: 5px; } -#text_editor { +#editor_topbar { + margin: 0.8% 0; +} + +#editor_topbar input { + width: 100%; +} + +#editor_topbar button img { + width: 100%; + height: 100%; +} + +#editor_content { height: 100%; background-color: rgba(256,256,256,.8); box-shadow: 2px 5px 10px 1px rgba(0, 0, 0, 0.3); - padding: 3% 8%; + margin: 0.8% 0; border: 1px solid $border_color; border-radius: 5px; + padding: 3% 8%; +} + +#editor_content div { + height: 100%; + overflow: scroll; +} + +#editor_topbar button img { + width: 60%; +} + +#editor_bottombar { + margin: 0.8% 0; +} + +#editor_delete { + float: left; + width: 100%; +} + +#editor_save { + float: right; + width: 100%; } #page { diff --git a/webpack.config.js b/webpack.config.js index 27d41c8..855c594 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,10 +1,10 @@ -const HtmlWebpackPlugin = require('html-webpack-plugin'); +const HtmlWebpackPlugin = require('html-webpack-plugin') const CleanWebpackPlugin = require('clean-webpack-plugin') -const ManifestRevisionPlugin = require('manifest-revision-webpack-plugin'); -const webpack = require('webpack'); -const path = require('path'); +const ManifestRevisionPlugin = require('manifest-revision-webpack-plugin') +const webpack = require('webpack') +const path = require('path') -const rootAssetPath = './src/'; +const rootAssetPath = './src/' let pathsToClean = [ 'static/' @@ -25,7 +25,7 @@ module.exports = { }, output: { publicPath: "/static/js/", - filename: '[name].[chunkhash].js', + filename: '[name].[hash].js', path: path.resolve(__dirname, 'static/js/') }, watch: true, @@ -44,6 +44,12 @@ module.exports = { } } }, + { + test: /\.(png)$/, + use: { + loader: 'file-loader' + } + }, { test: /\.(scss)$/, use: [{ @@ -75,6 +81,6 @@ module.exports = { 'window.jQuery': 'jquery', Popper: ['popper.js', 'default'] }), - new CleanWebpackPlugin(pathsToClean) - ], + new CleanWebpackPlugin(pathsToClean), + ], }; \ No newline at end of file