From 3ecc9ef95d34520a23a78b521f037c0497f098d4 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:27:33 -0400 Subject: [PATCH 01/48] Refactor CSS reset to its own file. Standardize naming conventions --- src/App.tsx | 3 +- src/css_reset.css | 48 ++++++++++++++++++ src/{SectionView.css => section_view.css} | 60 ----------------------- 3 files changed, 50 insertions(+), 61 deletions(-) create mode 100644 src/css_reset.css rename src/{SectionView.css => section_view.css} (63%) diff --git a/src/App.tsx b/src/App.tsx index 441be5b..2976d35 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,6 @@ import './App.css'; -import './SectionView.css'; +import './css_reset.css' +import './section_view.css'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; diff --git a/src/css_reset.css b/src/css_reset.css new file mode 100644 index 0000000..e29c0f5 --- /dev/null +++ b/src/css_reset.css @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/src/SectionView.css b/src/section_view.css similarity index 63% rename from src/SectionView.css rename to src/section_view.css index a51ea31..8bafce4 100644 --- a/src/SectionView.css +++ b/src/section_view.css @@ -1,63 +1,3 @@ -/* http://meyerweb.com/eric/tools/css/reset/ - v2.0 | 20110126 - License: none (public domain) -*/ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} -/* HTML5 display-role reset for older browsers */ -article, aside, details, figcaption, figure, -footer, header, hgroup, menu, nav, section { - display: block; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} -table { - border-collapse: collapse; - border-spacing: 0; -} - - - - - - - - - -/* END OF CSS RESET */ - - * { From b94780452e275d2d8dd082b5d4d0db63c8902cc7 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:30:19 -0400 Subject: [PATCH 02/48] Change .parent to .root --- src/App.tsx | 2 +- src/section_view.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 2976d35..274e62c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,7 +6,7 @@ import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; function App() { return ( -
+

Intro

diff --git a/src/section_view.css b/src/section_view.css index 8bafce4..1d996b0 100644 --- a/src/section_view.css +++ b/src/section_view.css @@ -7,7 +7,7 @@ html {font-size: 62.5%;} -.parent { +.root { display: flex; background-color: rgb(95, 193, 208); justify-content: center; From 51192788cc794a3285a0cbb190ab3a77b11971fd Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:30:30 -0400 Subject: [PATCH 03/48] Make sectionData, currentChordProgression, files, and comments, data driven --- src/App.tsx | 72 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 15 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 274e62c..c6b9078 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,39 +5,81 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; function App() { + + + + const sectionData = { + name: 'Intro', + description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', + numRevisions: 42, +}; + + const currentChordProgression = ['C', 'Dm', 'F', 'G'] + + const files = [ + {title: 'Bass.mp3', + numComments: 2, + }, + {title: 'Drums.mp3', + numComments: 2, + }, + {title: 'Yodeling.mp3', + numComments: 2, + }, + {title: 'Tuba.mp3', + numComments: 2, + }, + ] + + + const comments = [ + {name: 'Jerry', + commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' + }, + {name: 'Lerry', + commentText: 'jokes on you! Im deaf.' + }, + {name: 'Jerry', + commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' + } + ] + + + + return (
-

Intro

-

This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers

+

{sectionData.name}

+

{sectionData.description}

- - + +
    -
  1. C
  2. -
  3. Dm
  4. -
  5. F
  6. -
  7. G
  8. +
  9. {currentChordProgression[0]}
  10. +
  11. {currentChordProgression[1]}
  12. +
  13. {currentChordProgression[2]}
  14. +
  15. {currentChordProgression[3]}
+ Files -
Bass.mp3



2 Comments
-
Drums.mp3



2 Comments
-
Yodeling.mp3



2 Comments
-
Tuba.mp3



2 Comments
+
{files[0].title}



{files[0].numComments} Comments
+
{files[1].title}



{files[1].numComments} Comments
+
{files[2].title}



{files[2].numComments} Comments
+
{files[3].title}



{files[3].numComments} Comments
3 Comments
-

Jerry: My name is Schmoopie and I love this song. It reminds me of my grandpa

-

Larry: jokes on you! Im deaf.

-

Terry: Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...

+

{comments[0].name}: {comments[0].commentText}

+

{comments[1].name}: {comments[1].commentText}

+

{comments[2].name}: {comments[2].commentText}

From ad77205478eadbec03a370c736dbf3f705013938 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 13 Apr 2024 12:53:55 -0400 Subject: [PATCH 04/48] Refactor files to be its own component --- src/App.tsx | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c6b9078..90afa5c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -45,6 +45,24 @@ function App() { ] + // Components + + function Files() { + return <> + + Files + {files.map((file) => +
+ {file.title} +



+ {file.numComments + ' '} + Comments +
)} + + } + + + + return ( @@ -68,11 +86,7 @@ function App() {
- + Files -
{files[0].title}



{files[0].numComments} Comments
-
{files[1].title}



{files[1].numComments} Comments
-
{files[2].title}



{files[2].numComments} Comments
-
{files[3].title}



{files[3].numComments} Comments
+
3 Comments From 69a671d320b343cc78aef3f7d911e75dd098c7b0 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:14:50 -0400 Subject: [PATCH 05/48] Refactor ChordProgression into a component --- src/App.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 90afa5c..7d6ac9c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -61,6 +61,12 @@ function App() { } + function ChordProgression() { + return
    + {currentChordProgression.map((chord,index) =>
  1. {chord}
  2. )} +
+ } + @@ -78,12 +84,7 @@ function App() {
-
    -
  1. {currentChordProgression[0]}
  2. -
  3. {currentChordProgression[1]}
  4. -
  5. {currentChordProgression[2]}
  6. -
  7. {currentChordProgression[3]}
  8. -
+
From 627dc8fbb7574f505b229b9d531a8805c49f0775 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:43:39 -0400 Subject: [PATCH 06/48] Refactor Chordprogression for to include the
with class chords --- src/App.tsx | 57 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 7d6ac9c..f0ff44c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,34 +12,41 @@ function App() { name: 'Intro', description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', numRevisions: 42, -}; + }; const currentChordProgression = ['C', 'Dm', 'F', 'G'] const files = [ - {title: 'Bass.mp3', + { + title: 'Bass.mp3', numComments: 2, }, - {title: 'Drums.mp3', + { + title: 'Drums.mp3', numComments: 2, }, - {title: 'Yodeling.mp3', + { + title: 'Yodeling.mp3', numComments: 2, }, - {title: 'Tuba.mp3', + { + title: 'Tuba.mp3', numComments: 2, }, ] const comments = [ - {name: 'Jerry', + { + name: 'Jerry', commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' }, - {name: 'Lerry', + { + name: 'Lerry', commentText: 'jokes on you! Im deaf.' }, - {name: 'Jerry', + { + name: 'Jerry', commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' } ] @@ -52,19 +59,21 @@ function App() { + Files {files.map((file) =>
- {file.title} -



- {file.numComments + ' '} - Comments + {file.title} +



+ {file.numComments + ' '} + Comments
)} - + } function ChordProgression() { - return
    - {currentChordProgression.map((chord,index) =>
  1. {chord}
  2. )} -
+ return
+
    + {currentChordProgression.map((chord, index) =>
  1. {chord}
  2. )} +
+
} @@ -83,23 +92,21 @@ function App() {
-
- -
+
- +
3 Comments
-

{comments[0].name}: {comments[0].commentText}

-

{comments[1].name}: {comments[1].commentText}

-

{comments[2].name}: {comments[2].commentText}

+

{comments[0].name}: {comments[0].commentText}

+

{comments[1].name}: {comments[1].commentText}

+

{comments[2].name}: {comments[2].commentText}

- - + +
); From 233b7e8b53a1a076bfcc0660825619a5137d010d Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:44:43 -0400 Subject: [PATCH 07/48] Refactor Files so
with class 'files' is all together --- src/App.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index f0ff44c..477b523 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -55,7 +55,7 @@ function App() { // Components function Files() { - return <> + return
+ Files {files.map((file) =>
@@ -64,7 +64,7 @@ function App() { {file.numComments + ' '} Comments
)} - +
} @@ -93,9 +93,8 @@ function App() {
-
- -
+ +
3 Comments
From eb84b1152a31fd71e8134b0edb1185a316a24c62 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:51:36 -0400 Subject: [PATCH 08/48] Refactor comments section into its own component --- src/App.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 477b523..efe7d4a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -48,7 +48,7 @@ function App() { { name: 'Jerry', commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' - } + }, ] @@ -77,6 +77,18 @@ function App() { } + function Comments() { + return
+ 3 Comments +
+ {comments.map((comment, index) => { + return <> +

{comments[index].name}: {comments[index].commentText}

+ + })} +
+
+ } @@ -94,15 +106,7 @@ function App() {
- -
- 3 Comments -
-

{comments[0].name}: {comments[0].commentText}

-

{comments[1].name}: {comments[1].commentText}

-

{comments[2].name}: {comments[2].commentText}

-
-
+
From 812d45640b009a45e72d4117256723eea7069f03 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:53:04 -0400 Subject: [PATCH 09/48] Refactor submit section into its own component --- src/App.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index efe7d4a..4d9b0b9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -90,6 +90,12 @@ function App() {
} + function Submit() { + return
+ + +
+ } return ( @@ -107,10 +113,7 @@ function App() { -
- - -
+
); } From 3b2d7e2b07286d779e6a8790932eea7db7b9efc8 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 13 Apr 2024 13:56:13 -0400 Subject: [PATCH 10/48] Refactor Section-Title into its own component --- src/App.tsx | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 4d9b0b9..8ecce3b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -97,19 +97,22 @@ function App() {
} + function SectionTitle() { + return
+
+

{sectionData.name}

+

{sectionData.description}

+
+
+ + +
+
+ } return (
-
-
-

{sectionData.name}

-

{sectionData.description}

-
-
- - -
-
+ From b0cd8b4d016286c94286839c43a4fb63132e479d Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 20 Apr 2024 14:14:58 -0400 Subject: [PATCH 11/48] Give all component return statements pretty parentheses --- src/App.tsx | 84 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 8ecce3b..84ee5b9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -55,59 +55,69 @@ function App() { // Components function Files() { - return
- + Files - {files.map((file) => -
- {file.title} -



- {file.numComments + ' '} - Comments -
)} -
+ return ( +
+ + Files + {files.map((file) => +
+ {file.title} +



+ {file.numComments + ' '} + Comments +
)} +
+ ) } function ChordProgression() { - return
-
    - {currentChordProgression.map((chord, index) =>
  1. {chord}
  2. )} -
-
+ return ( +
+
    + {currentChordProgression.map((chord, index) =>
  1. {chord}
  2. )} +
+
+ ) } function Comments() { - return
- 3 Comments -
- {comments.map((comment, index) => { - return <> -

{comments[index].name}: {comments[index].commentText}

- - })} + return ( +
+ 3 Comments +
+ {comments.map((comment, index) => { + return <> +

{comments[index].name}: {comments[index].commentText}

+ + })} +
-
+ ) } function Submit() { - return
- - -
+ return ( +
+ + +
+ ) } function SectionTitle() { - return
-
-

{sectionData.name}

-

{sectionData.description}

+ return ( +
+
+

{sectionData.name}

+

{sectionData.description}

+
+
+ + +
-
- - -
-
+ ) } return ( From aaeaec01ebe87f7d40805cba6b131cb260446641 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:48:24 -0400 Subject: [PATCH 12/48] Refactor sectionData to be passed in as a prop --- src/App.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 84ee5b9..ff704df 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,7 +6,14 @@ import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; function App() { + type sectionDataProps = { + sectionData: { + name: string, + description: string, + numRevisions: number + } + } const sectionData = { name: 'Intro', @@ -105,7 +112,9 @@ function App() { ) } - function SectionTitle() { + + + const SectionTitle: React.FC = ({ sectionData }) => { return (
@@ -122,7 +131,7 @@ function App() { return (
- + From cf1bde7f443db93c2a9e4a7b4c4ce2b5f7a7edc5 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:49:31 -0400 Subject: [PATCH 13/48] Refactor chord progression component to use props --- src/App.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index ff704df..1a54a01 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,11 @@ function App() { } + type chordProgressionProps = { + chordProgression: string[] + } + + const sectionData = { name: 'Intro', description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', @@ -77,11 +82,11 @@ function App() { } - function ChordProgression() { + const ChordProgression:React.FC = ({chordProgression}) => { return (
    - {currentChordProgression.map((chord, index) =>
  1. {chord}
  2. )} + {chordProgression.map((chord, index) =>
  3. {chord}
  4. )}
) @@ -132,7 +137,7 @@ function App() { return (
- + From 660977ca14afba0d63ad1231d4fd47e30334da1b Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Tue, 23 Apr 2024 14:53:30 -0400 Subject: [PATCH 14/48] Refactor files component to use props --- src/App.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 1a54a01..803bfdb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,6 +20,17 @@ function App() { } + type file = { + title: string, + numComments: number + } + + + type filesProps = { + files: file[] + } + + const sectionData = { name: 'Intro', description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', @@ -66,7 +77,7 @@ function App() { // Components - function Files() { + const Files:React.FC = ({files}) => { return (
+ Files @@ -138,7 +149,7 @@ function App() {
- +
From b494a5249cc47adad0b92c1fbb43d656fc710a5c Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Tue, 23 Apr 2024 15:05:27 -0400 Subject: [PATCH 15/48] Refactor Comments to use props --- src/App.tsx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 803bfdb..7daafe1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -31,6 +31,23 @@ function App() { } + type comment = { + name: string, + commentText: string + } + + type commentsProps = { + comments: comment[] + } + + + + + + + //Data + + const sectionData = { name: 'Intro', description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', @@ -104,7 +121,7 @@ function App() { } - function Comments() { + const Comments:React.FC = ({comments}) => { return (
3 Comments @@ -150,7 +167,7 @@ function App() { - +
); From 4dbcfecc066645933b5f3eac114adaaf7178895f Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:35:19 -0400 Subject: [PATCH 16/48] Add an id for the array of files --- src/App.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 7daafe1..e1e9a4d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,7 +22,8 @@ function App() { type file = { title: string, - numComments: number + numComments: number, + id: string, } @@ -42,9 +43,6 @@ function App() { - - - //Data @@ -60,18 +58,22 @@ function App() { { title: 'Bass.mp3', numComments: 2, + id: 'change me to something better 0 ' }, { title: 'Drums.mp3', numComments: 2, + id: 'change me to something better 1' }, { title: 'Yodeling.mp3', numComments: 2, + id: 'change me to something better 2' }, { title: 'Tuba.mp3', numComments: 2, + id: 'change me to something better 3' }, ] @@ -99,7 +101,7 @@ function App() {
+ Files {files.map((file) => -
+
{file.title}



{file.numComments + ' '} From 22e7c24794f12ec903e2d1b8f9de8238687b0ca6 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 24 Apr 2024 10:54:34 -0400 Subject: [PATCH 17/48] Move type definitions to Types.ts --- src/App.tsx | 45 +++++---------------------------------------- src/types.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 40 deletions(-) create mode 100644 src/types.ts diff --git a/src/App.tsx b/src/App.tsx index e1e9a4d..7fc6bb6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,47 +1,12 @@ import './App.css'; import './css_reset.css' import './section_view.css'; +import * as Types from './types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; function App() { - type sectionDataProps = { - sectionData: { - name: string, - description: string, - numRevisions: number - } - - } - - type chordProgressionProps = { - chordProgression: string[] - } - - - type file = { - title: string, - numComments: number, - id: string, - } - - - type filesProps = { - files: file[] - } - - - type comment = { - name: string, - commentText: string - } - - type commentsProps = { - comments: comment[] - } - - //Data @@ -96,7 +61,7 @@ function App() { // Components - const Files:React.FC = ({files}) => { + const Files:React.FC = ({files}) => { return (
+ Files @@ -112,7 +77,7 @@ function App() { } - const ChordProgression:React.FC = ({chordProgression}) => { + const ChordProgression:React.FC = ({chordProgression}) => { return (
    @@ -123,7 +88,7 @@ function App() { } - const Comments:React.FC = ({comments}) => { + const Comments:React.FC = ({comments}) => { return (
    3 Comments @@ -149,7 +114,7 @@ function App() { - const SectionTitle: React.FC = ({ sectionData }) => { + const SectionTitle: React.FC = ({ sectionData }) => { return (
    diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..f83d28f --- /dev/null +++ b/src/types.ts @@ -0,0 +1,34 @@ +export type sectionDataProps = { + sectionData: { + name: string, + description: string, + numRevisions: number + } + + } + + export type chordProgressionProps = { + chordProgression: string[] + } + + + export type file = { + title: string, + numComments: number, + id: string, + } + + + export type filesProps = { + files: file[] + } + + + export type comment = { + name: string, + commentText: string + } + + export type commentsProps = { + comments: comment[] + } From ae941bd7498144c8690faea2de49d814f5e16f81 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:44:08 -0400 Subject: [PATCH 18/48] Add types to testData.ts --- src/App.tsx | 51 ------------------------------------------------- src/testData.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/types.ts | 43 ++++++++++++++++++++++++----------------- 3 files changed, 74 insertions(+), 69 deletions(-) create mode 100644 src/testData.ts diff --git a/src/App.tsx b/src/App.tsx index 7fc6bb6..65d38e7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,57 +8,6 @@ import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; function App() { - //Data - - - const sectionData = { - name: 'Intro', - description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', - numRevisions: 42, - }; - - const currentChordProgression = ['C', 'Dm', 'F', 'G'] - - const files = [ - { - title: 'Bass.mp3', - numComments: 2, - id: 'change me to something better 0 ' - }, - { - title: 'Drums.mp3', - numComments: 2, - id: 'change me to something better 1' - }, - { - title: 'Yodeling.mp3', - numComments: 2, - id: 'change me to something better 2' - }, - { - title: 'Tuba.mp3', - numComments: 2, - id: 'change me to something better 3' - }, - ] - - - const comments = [ - { - name: 'Jerry', - commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' - }, - { - name: 'Lerry', - commentText: 'jokes on you! Im deaf.' - }, - { - name: 'Jerry', - commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' - }, - ] - - // Components const Files:React.FC = ({files}) => { diff --git a/src/testData.ts b/src/testData.ts new file mode 100644 index 0000000..ebdc6cd --- /dev/null +++ b/src/testData.ts @@ -0,0 +1,49 @@ +import { Type } from 'typescript'; +import * as Types from './types' + +const sectionData:Types.sectionData = { + name: 'Intro', + description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', + numRevisions: 42, + }; + + const currentChordProgression:Types.chordProgression = ['C', 'Dm', 'F', 'G'] + + const files:Types.file[] = [ + { + title: 'Bass.mp3', + numComments: 2, + id: 'change me to something better 0 ' + }, + { + title: 'Drums.mp3', + numComments: 2, + id: 'change me to something better 1' + }, + { + title: 'Yodeling.mp3', + numComments: 2, + id: 'change me to something better 2' + }, + { + title: 'Tuba.mp3', + numComments: 2, + id: 'change me to something better 3' + }, + ] + + + const comments:Types.comment[] = [ + { + name: 'Jerry', + commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' + }, + { + name: 'Lerry', + commentText: 'jokes on you! Im deaf.' + }, + { + name: 'Jerry', + commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' + }, + ] diff --git a/src/types.ts b/src/types.ts index f83d28f..55fc52e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,34 +1,41 @@ + +export type sectionData = { + name: string, + description: string, + numRevisions: number +} + export type sectionDataProps = { - sectionData: { - name: string, - description: string, - numRevisions: number - } + sectionData:sectionData +} + + + + +export type chordProgression = string[] - } +export type chordProgressionProps = { + chordProgression: chordProgression +} - export type chordProgressionProps = { - chordProgression: string[] - } - export type file = { +export type file = { title: string, numComments: number, id: string, - } - +} - export type filesProps = { +export type filesProps = { files: file[] - } +} - export type comment = { +export type comment = { name: string, commentText: string - } +} - export type commentsProps = { +export type commentsProps = { comments: comment[] - } +} From 11c9a6e3e5c3400ec443a7222dedc8d2a44beb00 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:44:55 -0400 Subject: [PATCH 19/48] Remove unnecessary import --- src/testData.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testData.ts b/src/testData.ts index ebdc6cd..e0fe5c0 100644 --- a/src/testData.ts +++ b/src/testData.ts @@ -1,4 +1,4 @@ -import { Type } from 'typescript'; + import * as Types from './types' const sectionData:Types.sectionData = { From ca323bb8b753c880dab0b501676909e033fd0485 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:51:23 -0400 Subject: [PATCH 20/48] Add export keywords to testData.ts --- src/testData.ts | 84 ++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/testData.ts b/src/testData.ts index e0fe5c0..762f4af 100644 --- a/src/testData.ts +++ b/src/testData.ts @@ -1,49 +1,49 @@ import * as Types from './types' -const sectionData:Types.sectionData = { - name: 'Intro', - description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', - numRevisions: 42, - }; +export const sectionData: Types.sectionData = { + name: 'Intro', + description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', + numRevisions: 42, +}; - const currentChordProgression:Types.chordProgression = ['C', 'Dm', 'F', 'G'] +export const currentChordProgression: Types.chordProgression = ['C', 'Dm', 'F', 'G'] - const files:Types.file[] = [ - { - title: 'Bass.mp3', - numComments: 2, - id: 'change me to something better 0 ' - }, - { - title: 'Drums.mp3', - numComments: 2, - id: 'change me to something better 1' - }, - { - title: 'Yodeling.mp3', - numComments: 2, - id: 'change me to something better 2' - }, - { - title: 'Tuba.mp3', - numComments: 2, - id: 'change me to something better 3' - }, - ] +export const files: Types.file[] = [ + { + title: 'Bass.mp3', + numComments: 2, + id: 'change me to something better 0 ' + }, + { + title: 'Drums.mp3', + numComments: 2, + id: 'change me to something better 1' + }, + { + title: 'Yodeling.mp3', + numComments: 2, + id: 'change me to something better 2' + }, + { + title: 'Tuba.mp3', + numComments: 2, + id: 'change me to something better 3' + }, +] - const comments:Types.comment[] = [ - { - name: 'Jerry', - commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' - }, - { - name: 'Lerry', - commentText: 'jokes on you! Im deaf.' - }, - { - name: 'Jerry', - commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' - }, - ] +export const comments: Types.comment[] = [ + { + name: 'Jerry', + commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' + }, + { + name: 'Lerry', + commentText: 'jokes on you! Im deaf.' + }, + { + name: 'Jerry', + commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' + }, +] From 72db333f2d9bdbe3b9abf6102df4a93513a771c2 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 25 Apr 2024 11:53:48 -0400 Subject: [PATCH 21/48] Move all data to testData.tsx --- src/App.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 65d38e7..e68fdb1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,7 @@ import './App.css'; import './css_reset.css' import './section_view.css'; import * as Types from './types'; +import * as testData from './testData' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; @@ -80,10 +81,10 @@ function App() { return (
    - - - - + + + +
    ); From 631ef8ad283cd4560674601e7101e71387e8c8f7 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Fri, 26 Apr 2024 11:36:51 -0400 Subject: [PATCH 22/48] Refactor App.tsx to accept testData as a prop --- src/App.test.tsx | 11 +++++++++-- src/App.tsx | 11 +++++------ src/index.tsx | 8 +++++++- src/types.ts | 10 +++++++++- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/App.test.tsx b/src/App.test.tsx index 2a68616..aa9b389 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,9 +1,16 @@ -import React from 'react'; import { render, screen } from '@testing-library/react'; +import * as testData from './testData' import App from './App'; test('renders learn react link', () => { - render(); + render( + + ); const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); }); diff --git a/src/App.tsx b/src/App.tsx index e68fdb1..58b4169 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,11 +2,10 @@ import './App.css'; import './css_reset.css' import './section_view.css'; import * as Types from './types'; -import * as testData from './testData' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; -function App() { +const App:React.FC = ({sectionData, chordProgression, comments, files}) => { // Components @@ -81,10 +80,10 @@ function App() { return (
    - - - - + + + +
    ); diff --git a/src/index.tsx b/src/index.tsx index 032464f..466f9aa 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; +import * as testData from './testData' import App from './App'; import reportWebVitals from './reportWebVitals'; @@ -9,7 +10,12 @@ const root = ReactDOM.createRoot( ); root.render( - + ); diff --git a/src/types.ts b/src/types.ts index 55fc52e..bac4ece 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,7 +6,7 @@ export type sectionData = { } export type sectionDataProps = { - sectionData:sectionData + sectionData: sectionData } @@ -39,3 +39,11 @@ export type comment = { export type commentsProps = { comments: comment[] } + + +export type appProps = { + sectionData: sectionData, + chordProgression: chordProgression, + files: file[], + comments: comment[] +} From 4a263fc40b1f71fed8d5ac1bed81a62dc78a2c96 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:52:03 -0400 Subject: [PATCH 23/48] Prepare to refactor components to their own files --- src/App.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/App.tsx b/src/App.tsx index 58b4169..b7c42ae 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,7 @@ import * as Types from './types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; + const App:React.FC = ({sectionData, chordProgression, comments, files}) => { @@ -78,6 +79,9 @@ const App:React.FC = ({sectionData, chordProgression, comments, ) } + + + return (
    From 41a8b2e6262cee27bf1f6083181a86f488946929 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:53:53 -0400 Subject: [PATCH 24/48] Refactor components to their own files --- src/App.tsx | 81 +++------------------------------------- src/ChordProgression.tsx | 11 ++++++ src/Comments.tsx | 18 +++++++++ src/Files.tsx | 15 ++++++++ src/SectionTitle.tsx | 16 ++++++++ src/Submit.tsx | 8 ++++ 6 files changed, 74 insertions(+), 75 deletions(-) create mode 100644 src/ChordProgression.tsx create mode 100644 src/Comments.tsx create mode 100644 src/Files.tsx create mode 100644 src/SectionTitle.tsx create mode 100644 src/Submit.tsx diff --git a/src/App.tsx b/src/App.tsx index b7c42ae..15311a1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,84 +2,15 @@ import './App.css'; import './css_reset.css' import './section_view.css'; import * as Types from './types'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; +import { Files } from './Files'; +import { ChordProgression } from './ChordProgression'; +import { Comments } from './Comments'; +import { Submit } from './Submit'; +import { SectionTitle } from './SectionTitle'; -const App:React.FC = ({sectionData, chordProgression, comments, files}) => { - - - // Components - - const Files:React.FC = ({files}) => { - return ( -
    - + Files - {files.map((file) => -
    - {file.title} -



    - {file.numComments + ' '} - Comments -
    )} -
    - ) - } - - - const ChordProgression:React.FC = ({chordProgression}) => { - return ( -
    -
      - {chordProgression.map((chord, index) =>
    1. {chord}
    2. )} -
    -
    - ) - } - - const Comments:React.FC = ({comments}) => { - return ( -
    - 3 Comments -
    - {comments.map((comment, index) => { - return <> -

    {comments[index].name}: {comments[index].commentText}

    - - })} -
    -
    - ) - } - - function Submit() { - return ( -
    - - -
    - ) - } - - - - const SectionTitle: React.FC = ({ sectionData }) => { - return ( -
    -
    -

    {sectionData.name}

    -

    {sectionData.description}

    -
    -
    - - -
    -
    - ) - } - - +const App:React.FC = ({sectionData, chordProgression, comments, files}) => { return ( diff --git a/src/ChordProgression.tsx b/src/ChordProgression.tsx new file mode 100644 index 0000000..d8b4f15 --- /dev/null +++ b/src/ChordProgression.tsx @@ -0,0 +1,11 @@ +import * as Types from './types'; + +export const ChordProgression: React.FC = ({ chordProgression }) => { + return ( +
    +
      + {chordProgression.map((chord, index) =>
    1. {chord}
    2. )} +
    +
    + ); +}; diff --git a/src/Comments.tsx b/src/Comments.tsx new file mode 100644 index 0000000..6c62e19 --- /dev/null +++ b/src/Comments.tsx @@ -0,0 +1,18 @@ +import * as Types from './types'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; + +export const Comments: React.FC = ({ comments }) => { + return ( +
    + 3 Comments +
    + {comments.map((comment, index) => { + return <> +

    {comments[index].name}: {comments[index].commentText}

    + ; + })} +
    +
    + ); +}; diff --git a/src/Files.tsx b/src/Files.tsx new file mode 100644 index 0000000..bd2be82 --- /dev/null +++ b/src/Files.tsx @@ -0,0 +1,15 @@ +import * as Types from './types'; + +export const Files: React.FC = ({ files }) => { + return ( +
    + + Files + {files.map((file) =>
    + {file.title} +



    + {file.numComments + ' '} + Comments +
    )} +
    + ); +}; diff --git a/src/SectionTitle.tsx b/src/SectionTitle.tsx new file mode 100644 index 0000000..526abec --- /dev/null +++ b/src/SectionTitle.tsx @@ -0,0 +1,16 @@ +import * as Types from './types'; + +export const SectionTitle: React.FC = ({ sectionData }) => { + return ( +
    +
    +

    {sectionData.name}

    +

    {sectionData.description}

    +
    +
    + + +
    +
    + ); +}; diff --git a/src/Submit.tsx b/src/Submit.tsx new file mode 100644 index 0000000..989697c --- /dev/null +++ b/src/Submit.tsx @@ -0,0 +1,8 @@ +export function Submit() { + return ( +
    + + +
    + ); +} From 8855891d6e9150b01e74467b4bbb8decdad5f2bb Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:12:35 -0400 Subject: [PATCH 25/48] Add comments as state variable, hoist it --- src/App.tsx | 6 ++++-- src/Comments.tsx | 12 ++++++++++++ src/Submit.tsx | 28 +++++++++++++++++++++++----- src/types.ts | 6 ++++++ 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 15311a1..d4adca3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,19 +7,21 @@ import { ChordProgression } from './ChordProgression'; import { Comments } from './Comments'; import { Submit } from './Submit'; import { SectionTitle } from './SectionTitle'; +import { useState } from 'react'; const App:React.FC = ({sectionData, chordProgression, comments, files}) => { + const [commentsAsState, setCommentsAsState] = useState(comments) return (
    - - + +
    ); } diff --git a/src/Comments.tsx b/src/Comments.tsx index 6c62e19..8d606fc 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -1,6 +1,9 @@ import * as Types from './types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; +import {useState} from 'react' +import {comments as initialComments} from './testData' +import { comment } from './types'; export const Comments: React.FC = ({ comments }) => { return ( @@ -16,3 +19,12 @@ export const Comments: React.FC = ({ comments }) => {
    ); }; + + + +// + + + + +// diff --git a/src/Submit.tsx b/src/Submit.tsx index 989697c..42ef405 100644 --- a/src/Submit.tsx +++ b/src/Submit.tsx @@ -1,8 +1,26 @@ -export function Submit() { +import {useState} from 'react' +import {comments as initialComments} from './testData' +import { CreateCommentProps, comment, commentsProps } from './types'; + +export const Submit:React.FC = ({comments, setComments}) => { + // const [comments, setComment] = useState(initialComments) + + const handleAddComment = (newComment:comment) => { + setComments( + comments => [...comments, newComment] + ) + } + return ( -
    - - +
    + {comments.map((comment, index) => ( +
    +

    {comment.name}: {comment.commentText}

    +
    + ))} +
    ); -} +}; diff --git a/src/types.ts b/src/types.ts index bac4ece..f6f4cc4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,6 @@ +import React, { Dispatch } from "react" + export type sectionData = { name: string, description: string, @@ -40,6 +42,10 @@ export type commentsProps = { comments: comment[] } +export type CreateCommentProps = { + comments: comment[], + setComments: React.Dispatch<(comments: comment[]) => comment[]> +} export type appProps = { sectionData: sectionData, From 7620d1079631df1c467240aa1749cfe771ffb2a6 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:32:48 -0400 Subject: [PATCH 26/48] Remove extra map from .submit --- src/Submit.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Submit.tsx b/src/Submit.tsx index 42ef405..097a53d 100644 --- a/src/Submit.tsx +++ b/src/Submit.tsx @@ -13,11 +13,6 @@ export const Submit:React.FC = ({comments, setComments}) => return (
    - {comments.map((comment, index) => ( -
    -

    {comment.name}: {comment.commentText}

    -
    - ))} From ac1ea6cdc7fc4b36ea4928081641f043300cc87e Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:42:34 -0400 Subject: [PATCH 27/48] Rename Submit component to CreateComment --- src/App.tsx | 4 ++-- src/{Submit.tsx => CreateComment.tsx} | 2 +- src/types.ts | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) rename src/{Submit.tsx => CreateComment.tsx} (85%) diff --git a/src/App.tsx b/src/App.tsx index d4adca3..78c1026 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,7 +5,7 @@ import * as Types from './types'; import { Files } from './Files'; import { ChordProgression } from './ChordProgression'; import { Comments } from './Comments'; -import { Submit } from './Submit'; +import { CreateComment } from './CreateComment'; import { SectionTitle } from './SectionTitle'; import { useState } from 'react'; @@ -21,7 +21,7 @@ const App:React.FC = ({sectionData, chordProgression, comments, - +
    ); } diff --git a/src/Submit.tsx b/src/CreateComment.tsx similarity index 85% rename from src/Submit.tsx rename to src/CreateComment.tsx index 097a53d..5927d5b 100644 --- a/src/Submit.tsx +++ b/src/CreateComment.tsx @@ -2,7 +2,7 @@ import {useState} from 'react' import {comments as initialComments} from './testData' import { CreateCommentProps, comment, commentsProps } from './types'; -export const Submit:React.FC = ({comments, setComments}) => { +export const CreateComment:React.FC = ({comments, setComments}) => { // const [comments, setComment] = useState(initialComments) const handleAddComment = (newComment:comment) => { diff --git a/src/types.ts b/src/types.ts index f6f4cc4..bf12505 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,7 +13,6 @@ export type sectionDataProps = { - export type chordProgression = string[] export type chordProgressionProps = { @@ -42,11 +41,14 @@ export type commentsProps = { comments: comment[] } + + export type CreateCommentProps = { comments: comment[], setComments: React.Dispatch<(comments: comment[]) => comment[]> } + export type appProps = { sectionData: sectionData, chordProgression: chordProgression, From b06a3d4ba6ea8c5f2891e88074111be1253b8b92 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:12:28 -0400 Subject: [PATCH 28/48] Fix comment update bug --- src/Comments.tsx | 2 +- src/CreateComment.tsx | 12 ++++++------ src/types.ts | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Comments.tsx b/src/Comments.tsx index 8d606fc..49c346f 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -5,7 +5,7 @@ import {useState} from 'react' import {comments as initialComments} from './testData' import { comment } from './types'; -export const Comments: React.FC = ({ comments }) => { +export const Comments: React.FC = ({ comments = initialComments }) => { return (
    3 Comments diff --git a/src/CreateComment.tsx b/src/CreateComment.tsx index 5927d5b..034c14c 100644 --- a/src/CreateComment.tsx +++ b/src/CreateComment.tsx @@ -1,14 +1,14 @@ -import {useState} from 'react' -import {comments as initialComments} from './testData' + import { CreateCommentProps, comment, commentsProps } from './types'; export const CreateComment:React.FC = ({comments, setComments}) => { - // const [comments, setComment] = useState(initialComments) + const handleAddComment = (newComment:comment) => { - setComments( - comments => [...comments, newComment] - ) + let result = [...comments] + result.push(newComment) + setComments(result) + console.log(result) } return ( diff --git a/src/types.ts b/src/types.ts index bf12505..77a8d41 100644 --- a/src/types.ts +++ b/src/types.ts @@ -45,7 +45,7 @@ export type commentsProps = { export type CreateCommentProps = { comments: comment[], - setComments: React.Dispatch<(comments: comment[]) => comment[]> + setComments: (comments: comment[]) => void; } From 4fa90a9d1b3b41ed3829250073bb92aa5ed2cd02 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Tue, 30 Apr 2024 10:13:05 -0400 Subject: [PATCH 29/48] Remove unnecessary imports --- src/Comments.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Comments.tsx b/src/Comments.tsx index 49c346f..bbe025a 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -1,9 +1,8 @@ import * as Types from './types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; -import {useState} from 'react' import {comments as initialComments} from './testData' -import { comment } from './types'; + export const Comments: React.FC = ({ comments = initialComments }) => { return ( From 763e61ff0f54e8602a73f2829f652a650ab6152d Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Tue, 30 Apr 2024 13:36:05 -0400 Subject: [PATCH 30/48] Fix overflow issue when adding a new comment --- src/Comments.tsx | 9 --------- src/section_view.css | 4 +++- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Comments.tsx b/src/Comments.tsx index bbe025a..7bddd0c 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -18,12 +18,3 @@ export const Comments: React.FC = ({ comments = initialComm
    ); }; - - - -// - - - - -// diff --git a/src/section_view.css b/src/section_view.css index 1d996b0..f89c0ff 100644 --- a/src/section_view.css +++ b/src/section_view.css @@ -12,9 +12,11 @@ html {font-size: 62.5%;} background-color: rgb(95, 193, 208); justify-content: center; flex-direction: column; - height: 100vh; + min-height: 100vh; } + + div { border: 1px solid black; border-collapse: collapse; From 948eaab39890f9403091bbab535dfcf656af7881 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 1 May 2024 10:18:36 -0400 Subject: [PATCH 31/48] Make all types start with uppercase character --- src/App.tsx | 4 ++-- src/ChordProgression.tsx | 2 +- src/CreateComment.tsx | 38 ++++++++++++++++++++++++++++---------- src/Files.tsx | 2 +- src/SectionTitle.tsx | 2 +- src/testData.ts | 8 ++++---- src/types.ts | 37 ++++++++++++++++++------------------- 7 files changed, 55 insertions(+), 38 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 78c1026..7514b46 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,9 +11,9 @@ import { useState } from 'react'; -const App:React.FC = ({sectionData, chordProgression, comments, files}) => { +const App:React.FC = ({sectionData, chordProgression, comments, files}) => { - const [commentsAsState, setCommentsAsState] = useState(comments) + const [commentsAsState, setCommentsAsState] = useState(comments) return (
    diff --git a/src/ChordProgression.tsx b/src/ChordProgression.tsx index d8b4f15..564d2d7 100644 --- a/src/ChordProgression.tsx +++ b/src/ChordProgression.tsx @@ -1,6 +1,6 @@ import * as Types from './types'; -export const ChordProgression: React.FC = ({ chordProgression }) => { +export const ChordProgression: React.FC = ({ chordProgression }) => { return (
      diff --git a/src/CreateComment.tsx b/src/CreateComment.tsx index 034c14c..cc491f4 100644 --- a/src/CreateComment.tsx +++ b/src/CreateComment.tsx @@ -1,21 +1,39 @@ -import { CreateCommentProps, comment, commentsProps } from './types'; +import { CreateCommentProps, Comment, commentsProps } from './types'; +import {useState} from 'react'; -export const CreateComment:React.FC = ({comments, setComments}) => { +export const CreateComment: React.FC = ({ comments, setComments }) => { + const [name, setName] = useState(''); + const [commentText, setCommentText] = useState(''); - const handleAddComment = (newComment:comment) => { - let result = [...comments] - result.push(newComment) - setComments(result) - console.log(result) + const handleAddComment = () => { + const newComment = { name, commentText }; + const result = [...comments, newComment]; + setComments(result); } return (
      - +
      { + e.preventDefault(); + handleAddComment(); + setCommentText(''); + }}> + setName(e.target.value)} + placeholder='Enter your name' + /> + setCommentText(e.target.value)} + placeholder='Type your thoughts here' + /> + +
      ); }; diff --git a/src/Files.tsx b/src/Files.tsx index bd2be82..7d76017 100644 --- a/src/Files.tsx +++ b/src/Files.tsx @@ -1,6 +1,6 @@ import * as Types from './types'; -export const Files: React.FC = ({ files }) => { +export const Files: React.FC = ({ files }) => { return (
      + Files diff --git a/src/SectionTitle.tsx b/src/SectionTitle.tsx index 526abec..dc2b63e 100644 --- a/src/SectionTitle.tsx +++ b/src/SectionTitle.tsx @@ -1,6 +1,6 @@ import * as Types from './types'; -export const SectionTitle: React.FC = ({ sectionData }) => { +export const SectionTitle: React.FC = ({ sectionData }) => { return (
      diff --git a/src/testData.ts b/src/testData.ts index 762f4af..0673458 100644 --- a/src/testData.ts +++ b/src/testData.ts @@ -1,15 +1,15 @@ import * as Types from './types' -export const sectionData: Types.sectionData = { +export const sectionData: Types.SectionData = { name: 'Intro', description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', numRevisions: 42, }; -export const currentChordProgression: Types.chordProgression = ['C', 'Dm', 'F', 'G'] +export const currentChordProgression: Types.ChordProgression = ['C', 'Dm', 'F', 'G'] -export const files: Types.file[] = [ +export const files: Types.File[] = [ { title: 'Bass.mp3', numComments: 2, @@ -33,7 +33,7 @@ export const files: Types.file[] = [ ] -export const comments: Types.comment[] = [ +export const comments: Types.Comment[] = [ { name: 'Jerry', commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' diff --git a/src/types.ts b/src/types.ts index 77a8d41..3e89fa3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,57 +1,56 @@ -import React, { Dispatch } from "react" -export type sectionData = { +export type SectionData = { name: string, description: string, numRevisions: number } -export type sectionDataProps = { - sectionData: sectionData +export type SectionDataProps = { + sectionData: SectionData } -export type chordProgression = string[] +export type ChordProgression = string[] -export type chordProgressionProps = { - chordProgression: chordProgression +export type ChordProgressionProps = { + chordProgression: ChordProgression } -export type file = { +export type File = { title: string, numComments: number, id: string, } -export type filesProps = { - files: file[] +export type FilesProps = { + files: File[] } -export type comment = { +export type Comment = { name: string, commentText: string } export type commentsProps = { - comments: comment[] + comments: Comment[] } export type CreateCommentProps = { - comments: comment[], - setComments: (comments: comment[]) => void; + comments: Comment[], + setComments: (comments: Comment[]) => void; } -export type appProps = { - sectionData: sectionData, - chordProgression: chordProgression, - files: file[], - comments: comment[] +export type AppProps = { + sectionData: SectionData, + chordProgression: ChordProgression, + files: File[], + comments: Comment[] } From 8413354e5b7805ce67d6abad987ab4669cd29bfc Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 1 May 2024 11:00:48 -0400 Subject: [PATCH 32/48] Move AppProps to App.jsx --- src/App.tsx | 10 +++++++++- src/types.ts | 8 -------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 7514b46..c0392e0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,7 +11,15 @@ import { useState } from 'react'; -const App:React.FC = ({sectionData, chordProgression, comments, files}) => { + +type AppProps = { + sectionData: Types.SectionData, + chordProgression: Types.ChordProgression, + files: Types.File[], + comments: Types.Comment[] +} + +const App:React.FC = ({sectionData, chordProgression, comments, files}) => { const [commentsAsState, setCommentsAsState] = useState(comments) diff --git a/src/types.ts b/src/types.ts index 3e89fa3..41985f2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -46,11 +46,3 @@ export type CreateCommentProps = { comments: Comment[], setComments: (comments: Comment[]) => void; } - - -export type AppProps = { - sectionData: SectionData, - chordProgression: ChordProgression, - files: File[], - comments: Comment[] -} From b18ed6a5e07b63f893fc0889a9f7ea2af566c6f0 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 1 May 2024 11:14:54 -0400 Subject: [PATCH 33/48] Move CreateCommentProps to CreateComment.tsx --- src/CreateComment.tsx | 10 +++++++++- src/types.ts | 7 ------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/CreateComment.tsx b/src/CreateComment.tsx index cc491f4..468cd20 100644 --- a/src/CreateComment.tsx +++ b/src/CreateComment.tsx @@ -1,7 +1,15 @@ -import { CreateCommentProps, Comment, commentsProps } from './types'; +import {Comment} from './types'; import {useState} from 'react'; + +type CreateCommentProps = { + comments: Comment[], + setComments: (comments: Comment[]) => void; +} + + + export const CreateComment: React.FC = ({ comments, setComments }) => { const [name, setName] = useState(''); diff --git a/src/types.ts b/src/types.ts index 41985f2..dd4ee93 100644 --- a/src/types.ts +++ b/src/types.ts @@ -39,10 +39,3 @@ export type Comment = { export type commentsProps = { comments: Comment[] } - - - -export type CreateCommentProps = { - comments: Comment[], - setComments: (comments: Comment[]) => void; -} From b0b6b807b5bea7062ce6bf2e3308ee7e5648046a Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 1 May 2024 11:16:07 -0400 Subject: [PATCH 34/48] Move FilesProps definition to Files.tsx --- src/Files.tsx | 6 +++++- src/types.ts | 3 --- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Files.tsx b/src/Files.tsx index 7d76017..92b395d 100644 --- a/src/Files.tsx +++ b/src/Files.tsx @@ -1,6 +1,10 @@ import * as Types from './types'; -export const Files: React.FC = ({ files }) => { +type FilesProps = { + files: Types.File[] +} + +export const Files: React.FC = ({ files }) => { return (
      + Files diff --git a/src/types.ts b/src/types.ts index dd4ee93..03ce442 100644 --- a/src/types.ts +++ b/src/types.ts @@ -26,9 +26,6 @@ export type File = { id: string, } -export type FilesProps = { - files: File[] -} export type Comment = { From 9390c2d3aefb02a3547c9bb77e2331d2b1d1f68f Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 1 May 2024 11:17:26 -0400 Subject: [PATCH 35/48] Move ChordProgressionProps to ChordProgression.tsx --- src/ChordProgression.tsx | 7 ++++++- src/types.ts | 6 ------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/ChordProgression.tsx b/src/ChordProgression.tsx index 564d2d7..936a7f8 100644 --- a/src/ChordProgression.tsx +++ b/src/ChordProgression.tsx @@ -1,6 +1,11 @@ import * as Types from './types'; -export const ChordProgression: React.FC = ({ chordProgression }) => { +type ChordProgressionProps = { + chordProgression: Types.ChordProgression +} + + +export const ChordProgression: React.FC = ({ chordProgression }) => { return (
        diff --git a/src/types.ts b/src/types.ts index 03ce442..90b93bf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -14,11 +14,6 @@ export type SectionDataProps = { export type ChordProgression = string[] -export type ChordProgressionProps = { - chordProgression: ChordProgression -} - - export type File = { title: string, @@ -27,7 +22,6 @@ export type File = { } - export type Comment = { name: string, commentText: string From b9c09d0d6269923b68af751056727df627be25de Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 1 May 2024 11:18:37 -0400 Subject: [PATCH 36/48] Move SectionDataProps to SectionData.tsx --- src/SectionTitle.tsx | 6 +++++- src/types.ts | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/SectionTitle.tsx b/src/SectionTitle.tsx index dc2b63e..497ccc5 100644 --- a/src/SectionTitle.tsx +++ b/src/SectionTitle.tsx @@ -1,6 +1,10 @@ import * as Types from './types'; -export const SectionTitle: React.FC = ({ sectionData }) => { +type SectionDataProps = { + sectionData: Types.SectionData +} + +export const SectionTitle: React.FC = ({ sectionData }) => { return (
        diff --git a/src/types.ts b/src/types.ts index 90b93bf..0386c73 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,10 +6,6 @@ export type SectionData = { numRevisions: number } -export type SectionDataProps = { - sectionData: SectionData -} - export type ChordProgression = string[] From 4b48b2c9fc87209473fbd539e2f949c9f69b9379 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 1 May 2024 11:22:18 -0400 Subject: [PATCH 37/48] Change 'Types' to 'types' --- src/App.tsx | 12 ++++++------ src/ChordProgression.tsx | 4 ++-- src/Comments.tsx | 4 ++-- src/Files.tsx | 4 ++-- src/SectionTitle.tsx | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c0392e0..8d1bec3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,7 @@ import './App.css'; import './css_reset.css' import './section_view.css'; -import * as Types from './types'; +import * as types from './types'; import { Files } from './Files'; import { ChordProgression } from './ChordProgression'; import { Comments } from './Comments'; @@ -13,15 +13,15 @@ import { useState } from 'react'; type AppProps = { - sectionData: Types.SectionData, - chordProgression: Types.ChordProgression, - files: Types.File[], - comments: Types.Comment[] + sectionData: types.SectionData, + chordProgression: types.ChordProgression, + files: types.File[], + comments: types.Comment[] } const App:React.FC = ({sectionData, chordProgression, comments, files}) => { - const [commentsAsState, setCommentsAsState] = useState(comments) + const [commentsAsState, setCommentsAsState] = useState(comments) return (
        diff --git a/src/ChordProgression.tsx b/src/ChordProgression.tsx index 936a7f8..e197661 100644 --- a/src/ChordProgression.tsx +++ b/src/ChordProgression.tsx @@ -1,7 +1,7 @@ -import * as Types from './types'; +import * as types from './types'; type ChordProgressionProps = { - chordProgression: Types.ChordProgression + chordProgression: types.ChordProgression } diff --git a/src/Comments.tsx b/src/Comments.tsx index 7bddd0c..85cbfbf 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -1,10 +1,10 @@ -import * as Types from './types'; +import * as types from './types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; import {comments as initialComments} from './testData' -export const Comments: React.FC = ({ comments = initialComments }) => { +export const Comments: React.FC = ({ comments = initialComments }) => { return (
        3 Comments diff --git a/src/Files.tsx b/src/Files.tsx index 92b395d..6ad7008 100644 --- a/src/Files.tsx +++ b/src/Files.tsx @@ -1,7 +1,7 @@ -import * as Types from './types'; +import * as types from './types'; type FilesProps = { - files: Types.File[] + files: types.File[] } export const Files: React.FC = ({ files }) => { diff --git a/src/SectionTitle.tsx b/src/SectionTitle.tsx index 497ccc5..a0c14c3 100644 --- a/src/SectionTitle.tsx +++ b/src/SectionTitle.tsx @@ -1,7 +1,7 @@ -import * as Types from './types'; +import * as types from './types'; type SectionDataProps = { - sectionData: Types.SectionData + sectionData: types.SectionData } export const SectionTitle: React.FC = ({ sectionData }) => { From 5842ae0be4faecf7a994805c35d4af1d1e961f13 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 2 May 2024 13:06:59 -0400 Subject: [PATCH 38/48] Change '.buttons' to '.revisions' --- src/SectionTitle.tsx | 2 +- src/section_view.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SectionTitle.tsx b/src/SectionTitle.tsx index a0c14c3..c8dfede 100644 --- a/src/SectionTitle.tsx +++ b/src/SectionTitle.tsx @@ -11,7 +11,7 @@ export const SectionTitle: React.FC = ({ sectionData }) => {

        {sectionData.name}

        {sectionData.description}

        -
        +
        diff --git a/src/section_view.css b/src/section_view.css index f89c0ff..7b8a5c8 100644 --- a/src/section_view.css +++ b/src/section_view.css @@ -45,7 +45,7 @@ div { font-size: 2rem; } -.section-title .buttons { +.section-title .revisions { flex-grow: 1; display: flex; justify-content: center; From b949d42aac1944c1b960482cb617f6c9bcc78718 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 2 May 2024 21:34:14 -0400 Subject: [PATCH 39/48] User can now rename section title --- src/SectionTitle.tsx | 51 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/src/SectionTitle.tsx b/src/SectionTitle.tsx index c8dfede..588fe6a 100644 --- a/src/SectionTitle.tsx +++ b/src/SectionTitle.tsx @@ -1,20 +1,51 @@ import * as types from './types'; +import React, { useState, FormEvent } from 'react' + + + type SectionDataProps = { - sectionData: types.SectionData + sectionData: types.SectionData, } export const SectionTitle: React.FC = ({ sectionData }) => { + const [showForm, setShowForm] = useState(false); //shows the form for when you're entering a new title + const [currentTitle, setCurrentTitle] = useState(sectionData.name); + + let handleToggleForm = () => { + console.log('button clicked'); + setShowForm(!showForm); + }; + + // Handle form submission with FormData for TypeScript + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); // Using event.currentTarget to reference the form + const newName = formData.get('newName') as string; + setCurrentTitle(newName); + setShowForm(false); + }; + return ( -
        -
        -

        {sectionData.name}

        -

        {sectionData.description}

        -
        -
        - - +
        +
        +

        {currentTitle}

        +

        {sectionData.description}

        + +
        + {showForm && ( +
        + + + +
        + )} +
        + + +
        -
        ); }; From 7676ef01814d61a5005deb9e953f63263f69a777 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 2 May 2024 21:43:41 -0400 Subject: [PATCH 40/48] Add parenthese to returned JSX --- src/Files.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Files.tsx b/src/Files.tsx index 6ad7008..d9673d5 100644 --- a/src/Files.tsx +++ b/src/Files.tsx @@ -8,12 +8,13 @@ export const Files: React.FC = ({ files }) => { return (
        + Files - {files.map((file) =>
        + {files.map((file) => ( +
        {file.title}



        {file.numComments + ' '} Comments -
        )} +
        ))}
        ); }; From 70206b1b4d3b2e5656e2c5a162269e42c086a9c0 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 2 May 2024 21:46:15 -0400 Subject: [PATCH 41/48] Make amount of comments show on page --- src/Comments.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Comments.tsx b/src/Comments.tsx index 85cbfbf..20154cc 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -7,7 +7,7 @@ import {comments as initialComments} from './testData' export const Comments: React.FC = ({ comments = initialComments }) => { return (
        - 3 Comments + {comments.length} Comments
        {comments.map((comment, index) => { return <> From dff866e19074da703936926670da77912cb29b45 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Tue, 7 May 2024 11:27:21 -0400 Subject: [PATCH 42/48] Prep to move to localStorage --- src/App.tsx | 2 ++ src/client.ts | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 src/client.ts diff --git a/src/App.tsx b/src/App.tsx index 8d1bec3..9dd058b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,7 @@ import { Comments } from './Comments'; import { CreateComment } from './CreateComment'; import { SectionTitle } from './SectionTitle'; import { useState } from 'react'; +import { foo } from './client'; @@ -22,6 +23,7 @@ type AppProps = { const App:React.FC = ({sectionData, chordProgression, comments, files}) => { const [commentsAsState, setCommentsAsState] = useState(comments) + return (
        diff --git a/src/client.ts b/src/client.ts new file mode 100644 index 0000000..fe11508 --- /dev/null +++ b/src/client.ts @@ -0,0 +1,8 @@ + +//To Do for this file: + +//1. make all the data exist in localStorage + +//1.1 that would be comments, number of comments, chord progression, files, title, and description + +//2. type it as asynch even though it's not yet, so it'll be easy to refactor to a backend that isn't localStorage From 371de77381f2f733e53e51cebe518d3c77e33405 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 8 May 2024 10:42:22 -0400 Subject: [PATCH 43/48] Make comments persistant using localStorage --- src/App.tsx | 3 +-- src/Comments.tsx | 14 +++++++++++++- src/CreateComment.tsx | 16 ++++++++++++++-- src/client.ts | 2 ++ src/types.ts | 1 + 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 9dd058b..e33fe37 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,7 +8,6 @@ import { Comments } from './Comments'; import { CreateComment } from './CreateComment'; import { SectionTitle } from './SectionTitle'; import { useState } from 'react'; -import { foo } from './client'; @@ -30,7 +29,7 @@ const App:React.FC = ({sectionData, chordProgression, comments, files} - +
        ); diff --git a/src/Comments.tsx b/src/Comments.tsx index 20154cc..a306557 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -2,9 +2,21 @@ import * as types from './types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; import {comments as initialComments} from './testData' +import { useEffect} from 'react'; -export const Comments: React.FC = ({ comments = initialComments }) => { +export const Comments: React.FC = ({ comments = initialComments, setComments }) => { + + useEffect(() => { + // Attempt to load comments from localStorage + const storedCommentsJSON = localStorage.getItem('comments'); + const storedComments = storedCommentsJSON ? JSON.parse(storedCommentsJSON) : null; + + // Check if there are stored comments, otherwise use initial comments + setComments(storedComments || initialComments); + }, []); // Empty dependency array ensures this runs once on mount + + return (
        {comments.length} Comments diff --git a/src/CreateComment.tsx b/src/CreateComment.tsx index 468cd20..49947f9 100644 --- a/src/CreateComment.tsx +++ b/src/CreateComment.tsx @@ -17,9 +17,21 @@ export const CreateComment: React.FC = ({ comments, setComme const handleAddComment = () => { const newComment = { name, commentText }; - const result = [...comments, newComment]; - setComments(result); + + // Fetch existing comments from localStorage + const storedComments = localStorage.getItem('comments'); + const existingComments = storedComments ? JSON.parse(storedComments) : []; + + // Add the new comment to the array + const updatedComments = [...existingComments, newComment]; + + // Save the updated array back to localStorage + localStorage.setItem('comments', JSON.stringify(updatedComments)); + + // Update the local state to reflect the new list of comments + setComments(updatedComments); } + return (
        diff --git a/src/client.ts b/src/client.ts index fe11508..18ba1b0 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6,3 +6,5 @@ //1.1 that would be comments, number of comments, chord progression, files, title, and description //2. type it as asynch even though it's not yet, so it'll be easy to refactor to a backend that isn't localStorage + +export default {} diff --git a/src/types.ts b/src/types.ts index 0386c73..9be5636 100644 --- a/src/types.ts +++ b/src/types.ts @@ -25,4 +25,5 @@ export type Comment = { export type commentsProps = { comments: Comment[] + setComments: (comments: Comment[]) => void; } From 2b25ef69b21ecd3cf6b6fb3873ce1d78f55bb4c3 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Wed, 8 May 2024 10:47:08 -0400 Subject: [PATCH 44/48] Rename testData.tsx to sampleData.tsx --- src/App.test.tsx | 2 +- src/Comments.tsx | 2 +- src/index.tsx | 2 +- src/{testData.ts => sampleData.ts} | 13 +++++-------- 4 files changed, 8 insertions(+), 11 deletions(-) rename src/{testData.ts => sampleData.ts} (70%) diff --git a/src/App.test.tsx b/src/App.test.tsx index aa9b389..af186ec 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,5 +1,5 @@ import { render, screen } from '@testing-library/react'; -import * as testData from './testData' +import * as testData from './sampleData' import App from './App'; test('renders learn react link', () => { diff --git a/src/Comments.tsx b/src/Comments.tsx index a306557..218f51a 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -1,7 +1,7 @@ import * as types from './types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; -import {comments as initialComments} from './testData' +import {comments as initialComments} from './sampleData' import { useEffect} from 'react'; diff --git a/src/index.tsx b/src/index.tsx index 466f9aa..14bf9ac 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; -import * as testData from './testData' +import * as testData from './sampleData' import App from './App'; import reportWebVitals from './reportWebVitals'; diff --git a/src/testData.ts b/src/sampleData.ts similarity index 70% rename from src/testData.ts rename to src/sampleData.ts index 0673458..e3b1db8 100644 --- a/src/testData.ts +++ b/src/sampleData.ts @@ -35,15 +35,12 @@ export const files: Types.File[] = [ export const comments: Types.Comment[] = [ { - name: 'Jerry', - commentText: 'My name is Schmoopie and I love this song. It reminds me of my grandpa' + name: 'Sample User', + commentText: 'Hey! This is a comment' }, { - name: 'Lerry', - commentText: 'jokes on you! Im deaf.' - }, - { - name: 'Jerry', - commentText: 'Notice the tinnitus ringing in your ears, let the hiss from your damaged hearing remind you of peaceful ocean waves...' + name: 'Sample User', + commentText: 'Hey! This is a comment' }, + ] From 8efdec6cc765586ded82b3daec2dbee2793f4b77 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Thu, 9 May 2024 16:24:16 -0400 Subject: [PATCH 45/48] Move comments data to localStorage --- src/sampleData.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sampleData.ts b/src/sampleData.ts index e3b1db8..1a438b8 100644 --- a/src/sampleData.ts +++ b/src/sampleData.ts @@ -42,5 +42,4 @@ export const comments: Types.Comment[] = [ name: 'Sample User', commentText: 'Hey! This is a comment' }, - ] From 524408ffbc3231bcf3736f80f9205a6b498b0409 Mon Sep 17 00:00:00 2001 From: Michael Kochell <6913320+mickmister@users.noreply.github.com> Date: Sat, 11 May 2024 22:39:50 -0400 Subject: [PATCH 46/48] Create ci workflows for build and type checking (#7) * create ci workflows for build and type checking * ignore empty dep array in useEffect * add linting --- .github/workflows/ci.yml | 52 ++++++++++++++++++++++++++++++++++++++++ .gitignore | 2 ++ .gitpod.yml | 3 +++ package.json | 5 +++- src/Comments.tsx | 5 ++-- src/client.ts | 10 -------- 6 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitpod.yml delete mode 100644 src/client.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..8b8f453 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,52 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - '**' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 21 + cache: 'npm' + - name: Install modules + run: npm i + - name: Build app + run: npm run build + types: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 21 + cache: 'npm' + - name: Install modules + run: npm i + - name: Check Types + run: npm run check-types + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 21 + cache: 'npm' + - name: Install modules + run: npm i + - name: Run eslint + run: npm run lint diff --git a/.gitignore b/.gitignore index 4d29575..84d9f63 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* + +_ignore diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..c4b48c3 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,3 @@ +tasks: + - init: npm install && npm run build + command: npm run start diff --git a/package.json b/package.json index b6d5992..6b7bebc 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,10 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "lint": "eslint src/**/*.ts*", + "fix": "npm run lint -- --fix", + "check-types": "tsc --noEmit" }, "eslintConfig": { "extends": [ diff --git a/src/Comments.tsx b/src/Comments.tsx index 218f51a..1823f5a 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -14,8 +14,9 @@ export const Comments: React.FC = ({ comments = initialComm // Check if there are stored comments, otherwise use initial comments setComments(storedComments || initialComments); - }, []); // Empty dependency array ensures this runs once on mount - + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + return (
        diff --git a/src/client.ts b/src/client.ts deleted file mode 100644 index 18ba1b0..0000000 --- a/src/client.ts +++ /dev/null @@ -1,10 +0,0 @@ - -//To Do for this file: - -//1. make all the data exist in localStorage - -//1.1 that would be comments, number of comments, chord progression, files, title, and description - -//2. type it as asynch even though it's not yet, so it'll be easy to refactor to a backend that isn't localStorage - -export default {} From 571c1b0296025c75b1c88100049699773a07f209 Mon Sep 17 00:00:00 2001 From: Alec Rollison <88508028+aelishRollo@users.noreply.github.com> Date: Fri, 24 May 2024 16:18:48 -0400 Subject: [PATCH 47/48] Update README.md --- README.md | 41 +++++++---------------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index b87cb00..9cddb47 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,19 @@ -# Getting Started with Create React App +## Section-View: a new tool for musical composition -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). -## Available Scripts -In the project directory, you can run: +### Section view is a collaborative pre-DAW music application -### `npm start` +## Tech Used: ![JAVASCRIPT BADGE](https://img.shields.io/static/v1?label=|&message=JAVASCRIPT&color=3c7f5d&style=plastic&logo=javascript) ![React Badge](https://img.shields.io/static/v1?label=|&message=REACT&color=61DAFB&style=plastic&logo=react)![TypeScript Badge](https://img.shields.io/static/v1?label=|&message=TypeScript&color=3178C6&style=plastic&logo=typescript) -Runs the app in the development mode.\ -Open [http://localhost:3000](http://localhost:3000) to view it in the browser. -The page will reload if you make edits.\ -You will also see any lint errors in the console. -### `npm test` -Launches the test runner in the interactive watch mode.\ -See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. -### `npm run build` +## Optimizations -Builds the app for production to the `build` folder.\ -It correctly bundles React in production mode and optimizes the build for the best performance. +This project is constantly improving and growing. We're working on extending the scope of the project as you read this -The build is minified and the filenames include the hashes.\ -Your app is ready to be deployed! +## Lessons Learned: -See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. - -### `npm run eject` - -**Note: this is a one-way operation. Once you `eject`, you can’t go back!** - -If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. - -Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. - -You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. - -## Learn More - -You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). - -To learn React, check out the [React documentation](https://reactjs.org/). +Learned quite a bit about managing complexity and writing scalable and maintainable code From bc5af78a6c40f74dd2e0fea114686de637c8afd4 Mon Sep 17 00:00:00 2001 From: Michael Kochell <6913320+mickmister@users.noreply.github.com> Date: Sat, 1 Jun 2024 15:14:27 -0400 Subject: [PATCH 48/48] Refactor to use local storage (#8) * initial take on refactoring to store and client * connect section title to store * make the app use localStorage * remote IStore interface to simplify. fix workflow test command * use typed in username for comments * add import for index.css --- .eslintrc.json | 10 ++ .github/workflows/ci.yml | 14 ++ package.json | 10 +- src/App.test.tsx | 211 ++++++++++++++++++++++-- src/App.tsx | 79 ++++++--- src/ChordProgression.tsx | 2 +- src/Comments.tsx | 55 +++--- src/CreateComment.tsx | 84 ++++------ src/Files.tsx | 41 +++-- src/SectionPage.tsx | 35 ++++ src/SectionTitle.tsx | 109 +++++++----- src/actions/useActions.ts | 44 +++++ src/client/IClient.ts | 8 + src/client/LocalStorageClient.ts | 59 +++++++ src/hooks/useClient.tsx | 21 +++ src/hooks/useGlobalStore.tsx | 87 ++++++++++ src/hooks/useMount.ts | 9 + src/index.tsx | 37 +++-- src/logo.svg | 1 - src/sampleData.ts | 45 ----- src/store/LocalStorageStore.ts | 207 +++++++++++++++++++++++ src/store/MockLocalStorageDependency.ts | 24 +++ src/types.ts | 58 ++++--- src/utils.ts | 13 ++ {src => tests}/setupTests.ts | 0 25 files changed, 1002 insertions(+), 261 deletions(-) create mode 100644 .eslintrc.json create mode 100644 src/SectionPage.tsx create mode 100644 src/actions/useActions.ts create mode 100644 src/client/IClient.ts create mode 100644 src/client/LocalStorageClient.ts create mode 100644 src/hooks/useClient.tsx create mode 100644 src/hooks/useGlobalStore.tsx create mode 100644 src/hooks/useMount.ts delete mode 100644 src/logo.svg delete mode 100644 src/sampleData.ts create mode 100644 src/store/LocalStorageStore.ts create mode 100644 src/store/MockLocalStorageDependency.ts create mode 100644 src/utils.ts rename {src => tests}/setupTests.ts (100%) diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..21ae569 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "extends": [ + "react-app", + "react-app/jest" + ], + "rules": { + "testing-library/no-container": "off", + "testing-library/no-node-access": "off" + } + } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b8f453..db1b606 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,3 +50,17 @@ jobs: run: npm i - name: Run eslint run: npm run lint + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 21 + cache: 'npm' + - name: Install modules + run: npm i + - name: Run tests + run: npm run test:ci diff --git a/package.json b/package.json index 6b7bebc..c2058f8 100644 --- a/package.json +++ b/package.json @@ -25,16 +25,12 @@ "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", + "test:ci": "react-scripts test --watchAll=false", "eject": "react-scripts eject", "lint": "eslint src/**/*.ts*", "fix": "npm run lint -- --fix", - "check-types": "tsc --noEmit" - }, - "eslintConfig": { - "extends": [ - "react-app", - "react-app/jest" - ] + "check-types": "tsc --noEmit", + "ci": "npm run lint && npm run check-types && npm run test:ci && npm run build" }, "browserslist": { "production": [ diff --git a/src/App.test.tsx b/src/App.test.tsx index af186ec..8e27742 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,16 +1,201 @@ -import { render, screen } from '@testing-library/react'; -import * as testData from './sampleData' +import {render, screen, waitFor} from '@testing-library/react'; import App from './App'; +import {IClient} from './client/IClient'; +import {ProjectData, CommentData, SectionData, EntityType, FileData} from './types'; +import {LocalStorageStore, StoreData} from './store/LocalStorageStore'; +import {MockLocalStorageDependency} from './store/MockLocalStorageDependency'; +import {LocalStorageClient} from './client/LocalStorageClient'; -test('renders learn react link', () => { - render( - - ); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); +// import * as testData from './sampleData' + +window.alert = () => {}; + +const makeTestStore = (): StoreData => { + const initialProjects: ProjectData[] = [ + { + id: 'project-1', + }, + { + id: 'project-2', + }, + ]; + + const initialSections: SectionData[] = [ + { + id: 'section-1', + projectId: 'project-1', + chordProgression: ['C', 'Dm', 'F', 'G'], + description: 'This is the intro', + title: 'Intro', + numRevisions: 3, + } + ]; + + const initialFiles: FileData[] = [ + { + id: 'file-1', + projectId: 'project-1', + entityId: 'section-1', + entityType: EntityType.SECTION, + title: 'Bass.mp3', + }, + { + id: 'file-2', + projectId: 'project-1', + entityId: 'section-1', + entityType: EntityType.SECTION, + title: 'Chunky Monkey.mp3', + }, + ]; + + const initialComments: CommentData[] = [ + { + id: 'comment-1', + projectId: 'project-1', + message: 'Hey what\'s up', + entityType: EntityType.SECTION, + entityId: 'section-1', + username: 'username-1', + }, + { + id: 'comment-2', + projectId: 'project-1', + message: 'Yeah', + entityType: EntityType.FILE, + entityId: 'file-1', + username: 'username-1', + }, + { + id: 'comment-3', + projectId: 'project-1', + message: 'Yeah 3', + entityType: EntityType.FILE, + entityId: 'file-1', + username: 'username-1', + }, + ]; + + return { + projects: initialProjects, + sections: initialSections, + files: initialFiles, + comments: initialComments, + }; +}; + +describe('App', () => { + let client: IClient; + + beforeEach(() => { + const initialStore = makeTestStore(); + + const localStorageDependency = new MockLocalStorageDependency(initialStore); + const store = new LocalStorageStore(localStorageDependency); + client = new LocalStorageClient(store); + }); + + describe('initializing', () => { + it('should show "Loading"', async () => { + // this method is made blocking for this specific test + client.fetchFullDataForProject = (() => new Promise(r => setTimeout(r))); + + render( + + ); + + expect(screen.getByText(/Loading/)).toBeDefined(); + }); + + it('should show client error', async () => { + client.fetchFullDataForProject = jest.fn().mockResolvedValue(new Error('Some error')); + + render( + + ); + + await waitFor(() => { + expect(screen.queryByText(/Loading/)).toBeNull(); + }); + + expect(screen.getByText(/Some error/)).toBeDefined(); + }); + }); + + describe('initialized', () => { + it('should show the section title and description', async () => { + render( + + ); + + await waitFor(() => { + expect(screen.queryByText(/Loading/)).toBeNull(); + }); + + expect(screen.getByText(/Intro/)).toBeDefined(); + expect(screen.getByText(/This is the intro/)).toBeDefined(); + }); + + it('should show the chord progression', async () => { + const {container} = render( + + ); + + await waitFor(() => { + expect(screen.queryByText(/Loading/)).toBeNull(); + }); + + expect(container.querySelector('.chords')?.textContent).toEqual('CDmFG'); + }); + + it('should show files attached to the section', async () => { + const {container} = render( + + ); + + await waitFor(() => { + expect(screen.queryByText(/Loading/)).toBeNull(); + }); + + expect(container.querySelector('.files #file-1')?.textContent).toContain('Bass.mp3'); + expect(container.querySelector('.files #file-1')?.textContent).toContain('2 Comments'); + }); + + it('should show the comments on the section', async () => { + const {container} = render( + + ); + + await waitFor(() => { + expect(screen.queryByText(/Loading/)).toBeNull(); + }); + + expect(container.querySelector('.comments')?.textContent).toContain('1 Comment'); + expect(container.querySelector('.comments #comment-1')?.textContent).toContain('username-1'); + expect(container.querySelector('.comments #comment-1')?.textContent).toContain('Hey what\'s up'); + }); + }); }); diff --git a/src/App.tsx b/src/App.tsx index e33fe37..df11b80 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,38 +1,69 @@ +import {useState} from 'react'; + import './App.css'; import './css_reset.css' +import './index.css' import './section_view.css'; import * as types from './types'; -import { Files } from './Files'; -import { ChordProgression } from './ChordProgression'; -import { Comments } from './Comments'; -import { CreateComment } from './CreateComment'; -import { SectionTitle } from './SectionTitle'; -import { useState } from 'react'; +import {GlobalStoreProvider} from './hooks/useGlobalStore'; +import SectionPage from './SectionPage'; +import {IClient} from './client/IClient'; +import {ClientProvider} from './hooks/useClient'; +import {useMount} from './hooks/useMount'; +type AppProps = { + projectId: string; + sectionId: string; + client: IClient; +} +const App: React.FC = ({projectId, sectionId, client}) => { + const [initialProjectData, setInitialProjectData] = useState(null); + const [error, setError] = useState(''); -type AppProps = { - sectionData: types.SectionData, - chordProgression: types.ChordProgression, - files: types.File[], - comments: types.Comment[] -} + useMount(async () => { + const projectDataOrError = await client.fetchFullDataForProject(projectId); + + if (projectDataOrError instanceof Error) { + alert(projectDataOrError.message); + setError(projectDataOrError.message); + return; + } + + setInitialProjectData(projectDataOrError); + }); + + if (error) { + return ( +

        + {error} +

        + ); + } -const App:React.FC = ({sectionData, chordProgression, comments, files}) => { + if (!initialProjectData) { + return ( +

        + Loading +

        + ); + } - const [commentsAsState, setCommentsAsState] = useState(comments) - + const pageContent = ( + + ); - return ( -
        - - - - - -
        - ); + return ( + + + {pageContent} + + + ); } export default App; diff --git a/src/ChordProgression.tsx b/src/ChordProgression.tsx index e197661..c619531 100644 --- a/src/ChordProgression.tsx +++ b/src/ChordProgression.tsx @@ -9,7 +9,7 @@ export const ChordProgression: React.FC = ({ chordProgres return (
          - {chordProgression.map((chord, index) =>
        1. {chord}
        2. )} + {chordProgression.map((chord, index) =>
        3. {chord}
        4. )}
        ); diff --git a/src/Comments.tsx b/src/Comments.tsx index 1823f5a..3a3a91a 100644 --- a/src/Comments.tsx +++ b/src/Comments.tsx @@ -1,33 +1,32 @@ -import * as types from './types'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faFaceSmile } from '@fortawesome/free-solid-svg-icons'; -import {comments as initialComments} from './sampleData' -import { useEffect} from 'react'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faFaceSmile} from '@fortawesome/free-solid-svg-icons'; +import {EntityPointer} from './types'; +import {useGlobalStore} from './hooks/useGlobalStore'; +import {plural} from './utils'; -export const Comments: React.FC = ({ comments = initialComments, setComments }) => { +type CommentsProps = { + entityPointer: EntityPointer; +} - useEffect(() => { - // Attempt to load comments from localStorage - const storedCommentsJSON = localStorage.getItem('comments'); - const storedComments = storedCommentsJSON ? JSON.parse(storedCommentsJSON) : null; +export const Comments: React.FC = ({entityPointer}) => { + const globalStore = useGlobalStore(); + const comments = globalStore.getCommentsForEntity(entityPointer); - // Check if there are stored comments, otherwise use initial comments - setComments(storedComments || initialComments); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - - return ( -
        - {comments.length} Comments -
        - {comments.map((comment, index) => { - return <> -

        {comments[index].name}: {comments[index].commentText}

        - ; - })} -
        -
        - ); + return ( +
        + {comments.length} {plural('Comment', comments.length)} +
        + {comments.map(comment => ( +

        + + {comment.username}: {comment.message} +

        + ))} +
        +
        + ); }; diff --git a/src/CreateComment.tsx b/src/CreateComment.tsx index 49947f9..8a0fb9a 100644 --- a/src/CreateComment.tsx +++ b/src/CreateComment.tsx @@ -1,59 +1,47 @@ -import {Comment} from './types'; +import {useActions} from './actions/useActions'; +import {EntityPointer} from './types'; import {useState} from 'react'; - type CreateCommentProps = { - comments: Comment[], - setComments: (comments: Comment[]) => void; + entityPointer: EntityPointer; } +export const CreateComment: React.FC = ({entityPointer}) => { + const actions = useActions(); + const [name, setName] = useState(''); + const [commentText, setCommentText] = useState(''); -export const CreateComment: React.FC = ({ comments, setComments }) => { - - const [name, setName] = useState(''); - const [commentText, setCommentText] = useState(''); - - const handleAddComment = () => { - const newComment = { name, commentText }; - - // Fetch existing comments from localStorage - const storedComments = localStorage.getItem('comments'); - const existingComments = storedComments ? JSON.parse(storedComments) : []; - - // Add the new comment to the array - const updatedComments = [...existingComments, newComment]; - - // Save the updated array back to localStorage - localStorage.setItem('comments', JSON.stringify(updatedComments)); - - // Update the local state to reflect the new list of comments - setComments(updatedComments); - } - - - return ( -
        -
        { + const handleAddComment = async (e: React.FormEvent) => { e.preventDefault(); - handleAddComment(); + + await actions.addCommentToEntity(commentText, name, entityPointer); setCommentText(''); - }}> - setName(e.target.value)} - placeholder='Enter your name' - /> - setCommentText(e.target.value)} - placeholder='Type your thoughts here' - /> - -
        -
        - ); + } + + return ( +
        +
        + setName(e.target.value)} + placeholder='Enter your name' + /> + setCommentText(e.target.value)} + placeholder='Type your thoughts here' + /> + +
        +
        + ); }; diff --git a/src/Files.tsx b/src/Files.tsx index d9673d5..c87b9f7 100644 --- a/src/Files.tsx +++ b/src/Files.tsx @@ -1,20 +1,33 @@ +import {useGlobalStore} from './hooks/useGlobalStore'; import * as types from './types'; +import {plural} from './utils'; type FilesProps = { - files: types.File[] + files: types.FileData[] } -export const Files: React.FC = ({ files }) => { - return ( -
        - + Files - {files.map((file) => ( -
        - {file.title} -



        - {file.numComments + ' '} - Comments -
        ))} -
        - ); +export const Files: React.FC = ({files}) => { + const globalStore = useGlobalStore(); + + return ( +
        + + Files + {files.map((file) => { + const numComments = globalStore.getCommentsForFile(file.id).length; + + return ( +
        + {file.title} +



        + {numComments} + {' '} + {plural('Comment', numComments)} +
        + ); + })} +
        + ); }; diff --git a/src/SectionPage.tsx b/src/SectionPage.tsx new file mode 100644 index 0000000..b3a5b5e --- /dev/null +++ b/src/SectionPage.tsx @@ -0,0 +1,35 @@ +import * as types from './types'; +import {Files} from './Files'; +import {ChordProgression} from './ChordProgression'; +import {Comments} from './Comments'; +import {CreateComment} from './CreateComment'; +import {SectionTitle} from './SectionTitle'; +import {useGlobalStore} from './hooks/useGlobalStore'; + +type SectionPageProps = { + projectId: string; + sectionId: string; +} + +const SectionPage: React.FC = ({projectId, sectionId}) => { + const globalStore = useGlobalStore(); + const section = globalStore.getSection(sectionId); + const files = globalStore.getFilesForSection(sectionId); + + const sectionPointer: types.EntityPointer = { + entityId: sectionId, + entityType: types.EntityType.SECTION, + }; + + return ( +
        + + + + + +
        + ); +} + +export default SectionPage; diff --git a/src/SectionTitle.tsx b/src/SectionTitle.tsx index 588fe6a..b810bff 100644 --- a/src/SectionTitle.tsx +++ b/src/SectionTitle.tsx @@ -1,51 +1,70 @@ -import * as types from './types'; -import React, { useState, FormEvent } from 'react' +import {useActions} from './actions/useActions'; +import {useGlobalStore} from './hooks/useGlobalStore'; +import React, {useState, FormEvent} from 'react'; +import {SectionData} from './types'; +type SectionDataProps = { + sectionId: string; +} +export const SectionTitle: React.FC = ({sectionId}) => { + const actions = useActions(); + const globalStore = useGlobalStore(); + const section = globalStore.getSection(sectionId); -type SectionDataProps = { - sectionData: types.SectionData, -} + const [isEditingTitle, setIsEditingTitle] = useState(false); + const [draftTitle, setDraftTitle] = useState(section.title); + + const handleDraftTitleChange = (e: React.ChangeEvent) => { + setDraftTitle(e.target.value); + }; + + const handleToggleForm = () => { + console.log('button clicked'); + setIsEditingTitle(!isEditingTitle); + }; + + const handleSubmit = (event: FormEvent) => { + event.preventDefault(); + const newTitle = draftTitle; + const newSection: SectionData = { + ...section, + title: newTitle, + } + + actions.updateSection(sectionId, newSection); + // setDraftTitle(newTitle); + setIsEditingTitle(false); + }; -export const SectionTitle: React.FC = ({ sectionData }) => { - const [showForm, setShowForm] = useState(false); //shows the form for when you're entering a new title - const [currentTitle, setCurrentTitle] = useState(sectionData.name); - - let handleToggleForm = () => { - console.log('button clicked'); - setShowForm(!showForm); - }; - - // Handle form submission with FormData for TypeScript - const handleSubmit = (event: FormEvent) => { - event.preventDefault(); - const formData = new FormData(event.currentTarget); // Using event.currentTarget to reference the form - const newName = formData.get('newName') as string; - setCurrentTitle(newName); - setShowForm(false); - }; - - return ( -
        -
        -

        {currentTitle}

        -

        {sectionData.description}

        - -
        - {showForm && ( -
        - - - -
        - )} -
        - - -
        -
        - ); + return ( +
        +
        +

        {section.title}

        +

        {section.description}

        + +
        + {isEditingTitle && ( +
        + + + +
        + )} +
        + + +
        +
        + ); }; diff --git a/src/actions/useActions.ts b/src/actions/useActions.ts new file mode 100644 index 0000000..21f3ccb --- /dev/null +++ b/src/actions/useActions.ts @@ -0,0 +1,44 @@ +import {useClient} from '../hooks/useClient'; +import {useGlobalStore} from '../hooks/useGlobalStore'; +import {CommentData, EntityPointer, SectionData} from '../types'; + +type UseActionsHookValue = { + addCommentToEntity(text: string, username: string, entityPointer: EntityPointer): Promise; + updateSection(sectionId: string, section: SectionData): Promise; +} + +export const useActions = (): UseActionsHookValue => { + const globalStore = useGlobalStore(); + const client = useClient(); + + // TODO: this should be retrieved from globalState + // const projectId = globalStore.getCurrentProjectId() + const projectId = 'project-1'; + + const addCommentToEntity = async (message: string, username: string, entityPointer: EntityPointer) => { + const commentPayload: Omit = { + entityType: entityPointer.entityType, + entityId: entityPointer.entityId, + message, + projectId, + username, + }; + + const comment = await client.addComment(commentPayload); + globalStore.addComment(comment); + + return comment; + }; + + const updateSection = async (sectionId: string, section: SectionData) => { + const newSection = await client.updateSection(sectionId, section); + globalStore.updateSection(sectionId, newSection); + + return section; + }; + + return { + addCommentToEntity, + updateSection, + }; +} diff --git a/src/client/IClient.ts b/src/client/IClient.ts new file mode 100644 index 0000000..1b7e669 --- /dev/null +++ b/src/client/IClient.ts @@ -0,0 +1,8 @@ +import {CommentData, FullProjectData, SectionData} from '../types'; + +export interface IClient { + fetchFullDataForProject: (projectId: string) => Promise; + + addComment(comment: Omit): Promise; + updateSection(sectionId: string, section: SectionData): Promise; +} diff --git a/src/client/LocalStorageClient.ts b/src/client/LocalStorageClient.ts new file mode 100644 index 0000000..a1eca7e --- /dev/null +++ b/src/client/LocalStorageClient.ts @@ -0,0 +1,59 @@ +import {LocalStorageStore} from '../store/LocalStorageStore'; +import {CommentData, FullProjectData, SectionData} from '../types'; +import {IClient} from './IClient'; + +export class LocalStorageClient implements IClient { + private persistentStore: LocalStorageStore; + + constructor(persistentStore: LocalStorageStore) { + this.persistentStore = persistentStore; + } + + addComment = async (comment: Omit): Promise => { + const newComment: CommentData = { + ...comment, + id: Math.random().toString().slice(2), + }; + + const comments = await this.persistentStore.getAllComments(); + const newState = [...comments, newComment]; + this.persistentStore.setAllComments(newState); + + return newComment; + } + + // fetchFullDataForProject uses the local storage store to get all data for a given project + // it fetches the project data, sections, files, and comments for the given project + fetchFullDataForProject = async (projectId: string): Promise => { + const projects = (await this.persistentStore.getAllProjects()).filter(p => p.id === projectId); + const sections = (await this.persistentStore.getAllSections()).filter(s => s.projectId === projectId); + const files = (await this.persistentStore.getAllFiles()).filter(f => f.projectId === projectId); + const comments = (await this.persistentStore.getAllComments()).filter(c => c.projectId === projectId); + + if (!projects[0]) { + return new Error(`Error: No project found for projectId ${projectId}`); + } + + return { + project: projects[0], + comments, + files, + sections, + }; + } + + updateSection = async (sectionId: string, section: SectionData): Promise => { + const sections = await this.persistentStore.getAllSections(); + const newState = sections.map(s => { + if (s.id === sectionId) { + return section; + } + + return s; + }); + + this.persistentStore.setAllSections(newState); + + return section; + } +} diff --git a/src/hooks/useClient.tsx b/src/hooks/useClient.tsx new file mode 100644 index 0000000..5dc6b4e --- /dev/null +++ b/src/hooks/useClient.tsx @@ -0,0 +1,21 @@ +import {createContext, useContext} from 'react'; +import {IClient} from '../client/IClient'; + +const clientContext = createContext(null); + +type ClientProviderProps = React.PropsWithChildren<{ + client: IClient; +}>; + +export const useClient = (): IClient => { + const client = useContext(clientContext)!; + return client; +}; + +export const ClientProvider = (props: ClientProviderProps) => { + return ( + + {props.children} + + ); +}; diff --git a/src/hooks/useGlobalStore.tsx b/src/hooks/useGlobalStore.tsx new file mode 100644 index 0000000..4a2e9a7 --- /dev/null +++ b/src/hooks/useGlobalStore.tsx @@ -0,0 +1,87 @@ +import {createContext, useContext, useMemo, useState} from 'react'; +import {CommentData, EntityPointer, EntityType, FileData, FullProjectData, SectionData} from '../types'; +import {matchesEntityPointer} from '../utils'; + +type GlobalStoreContextValue = { + getFullProjectData(): FullProjectData; + setFullProjectData(project: FullProjectData): void; +} + +const globalStoreContext = createContext(null); + +type GlobalStoreProviderProps = React.PropsWithChildren<{ + initialProjectData: FullProjectData; +}>; + +type UseGlobalStoreHookValue = { + getCommentsForSection(sectionId: string): CommentData[]; + getCommentsForFile(fileId: string): CommentData[]; + getFilesForSection(sectionId: string): FileData[]; + getCommentsForEntity(entityPointer: EntityPointer): CommentData[]; + getSection(sectionId: string): SectionData; + + addComment(comment: CommentData): void; + updateSection(sectionId: string, section: SectionData): void; +} + +export const useGlobalStore = (): UseGlobalStoreHookValue => { + const globalStore = useContext(globalStoreContext)!; + const projectData = globalStore.getFullProjectData(); + + return useMemo(() => ({ + getCommentsForFile: (fileId) => projectData.comments.filter(c => matchesEntityPointer(c, EntityType.FILE, fileId)), + getCommentsForSection: (sectionId) => projectData.comments.filter(c => matchesEntityPointer(c, EntityType.SECTION, sectionId)), + getFilesForSection: (sectionId) => projectData.files.filter(f => matchesEntityPointer(f, EntityType.SECTION, sectionId)), + getCommentsForEntity: (entityPointer: EntityPointer) => projectData.comments.filter(c => matchesEntityPointer(c, entityPointer.entityType, entityPointer.entityId)), + + // error-prone how we assume the section exists + getSection: (sectionId) => projectData.sections.find(s => s.id === sectionId)!, + + addComment: (comment) => { + const state = globalStore.getFullProjectData(); + const newState: FullProjectData = { + ...state, + comments: [ + ...state.comments, + comment, + ], + }; + + globalStore.setFullProjectData(newState); + }, + + updateSection: (sectionId, updatedSection) => { + const state = globalStore.getFullProjectData(); + + const sections = state.sections.map(existingSection => { + if (existingSection.id === sectionId) { + return updatedSection; + } + + return existingSection; + }); + + const newState: FullProjectData = { + ...state, + sections, + }; + + globalStore.setFullProjectData(newState); + } + }), [projectData, globalStore]); +}; + +export const GlobalStoreProvider = (props: GlobalStoreProviderProps) => { + const [fullProjectData, setFullProjectData] = useState(props.initialProjectData); + + const value = useMemo(() => ({ + getFullProjectData: () => fullProjectData, + setFullProjectData, + }), [fullProjectData, setFullProjectData]); + + return ( + + {props.children} + + ); +}; diff --git a/src/hooks/useMount.ts b/src/hooks/useMount.ts new file mode 100644 index 0000000..7ae5596 --- /dev/null +++ b/src/hooks/useMount.ts @@ -0,0 +1,9 @@ +import {useEffect} from 'react' + +export const useMount = (callback: () => void) => { + useEffect(() => { + callback(); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); +} diff --git a/src/index.tsx b/src/index.tsx index 14bf9ac..7b20240 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,23 +1,32 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; -import * as testData from './sampleData' import App from './App'; import reportWebVitals from './reportWebVitals'; +import {LocalStorageStore} from './store/LocalStorageStore'; +import {LocalStorageClient} from './client/LocalStorageClient'; -const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement -); -root.render( - - - -); +window.addEventListener('load', async () => { + const root = ReactDOM.createRoot( + document.getElementById('root') as HTMLElement + ); + + const localStore = new LocalStorageStore(localStorage); + const localClient = new LocalStorageClient(localStore); + + const projectId = 'project-1'; + const sectionId = 'section-1'; + + root.render( + + + + ); +}); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/sampleData.ts b/src/sampleData.ts deleted file mode 100644 index 1a438b8..0000000 --- a/src/sampleData.ts +++ /dev/null @@ -1,45 +0,0 @@ - -import * as Types from './types' - -export const sectionData: Types.SectionData = { - name: 'Intro', - description: 'This intro section consists of a tuba quartet in the style of DJ Templeton & The Windsurfers', - numRevisions: 42, -}; - -export const currentChordProgression: Types.ChordProgression = ['C', 'Dm', 'F', 'G'] - -export const files: Types.File[] = [ - { - title: 'Bass.mp3', - numComments: 2, - id: 'change me to something better 0 ' - }, - { - title: 'Drums.mp3', - numComments: 2, - id: 'change me to something better 1' - }, - { - title: 'Yodeling.mp3', - numComments: 2, - id: 'change me to something better 2' - }, - { - title: 'Tuba.mp3', - numComments: 2, - id: 'change me to something better 3' - }, -] - - -export const comments: Types.Comment[] = [ - { - name: 'Sample User', - commentText: 'Hey! This is a comment' - }, - { - name: 'Sample User', - commentText: 'Hey! This is a comment' - }, -] diff --git a/src/store/LocalStorageStore.ts b/src/store/LocalStorageStore.ts new file mode 100644 index 0000000..5908afc --- /dev/null +++ b/src/store/LocalStorageStore.ts @@ -0,0 +1,207 @@ +import {CommentData, EntityType, FileData, ProjectData, SectionData} from '../types'; + +export interface LocalStorageDependency { + getItem(key: string): string | null; + setItem(key: string, value: string): void; + clear(): void; +} + +// TODO: versioning of the store allows for migrations +// const LOCAL_STORAGE_KEY_VERSION = 'version'; + +const LOCAL_STORAGE_KEY_PROJECTS = 'projects'; +const LOCAL_STORAGE_KEY_SECTIONS = 'sections'; +const LOCAL_STORAGE_KEY_FILES = 'files'; +const LOCAL_STORAGE_KEY_COMMENTS = 'comments'; + +export type StoreData = { + projects: ProjectData[]; + sections: SectionData[]; + files: FileData[]; + comments: CommentData[]; +} + +export class LocalStorageStore { + private ls: LocalStorageDependency; + + private currentData: StoreData; + + constructor(ls: LocalStorageDependency) { + this.ls = ls; + this.currentData = this.migrateLocalStorageStore(); + + if (!this.currentData.projects.length) { + this.initializeWithSampleData(); + } + + // this.clear(); + } + + clear = () => { + this.ls.clear(); + this.currentData = this.migrateLocalStorageStore(); + } + + initializeWithSampleData = () => { + this.clear(); + this.setAllProjects(initialProjects); + this.setAllSections(initialSections); + this.setAllFiles(initialFiles); + this.setAllComments(initialComments); + } + + getAllProjects = async (): Promise => { + return this.currentData.projects; + }; + + setAllProjects = async (allProjects: ProjectData[]): Promise => { + this.currentData = { + ...this.currentData, + projects: allProjects, + }; + + this.ls.setItem(LOCAL_STORAGE_KEY_PROJECTS, JSON.stringify(allProjects)); + }; + + getAllSections = async (): Promise => { + return this.currentData.sections; + }; + + setAllSections = async (allSections: SectionData[]): Promise => { + this.currentData = { + ...this.currentData, + sections: allSections, + }; + + this.ls.setItem(LOCAL_STORAGE_KEY_SECTIONS, JSON.stringify(allSections)); + }; + + getAllFiles = async (): Promise => { + return this.currentData.files; + }; + + setAllFiles = async (allFiles: FileData[]): Promise => { + this.currentData = { + ...this.currentData, + files: allFiles, + }; + + this.ls.setItem(LOCAL_STORAGE_KEY_FILES, JSON.stringify(allFiles)); + }; + + getAllComments = async (): Promise => { + return this.currentData.comments; + }; + + setAllComments = async (allComments: CommentData[]): Promise => { + this.currentData = { + ...this.currentData, + comments: allComments, + }; + + this.ls.setItem(LOCAL_STORAGE_KEY_COMMENTS, JSON.stringify(allComments)); + }; + + private migrateLocalStorageStore = (): StoreData => { + const store: StoreData = { + projects: [], + sections: [], + files: [], + comments: [], + }; + + const projectsStr = this.ls.getItem(LOCAL_STORAGE_KEY_PROJECTS); + if (projectsStr) { + store.projects = JSON.parse(projectsStr); + } else { + this.ls.setItem(LOCAL_STORAGE_KEY_PROJECTS, JSON.stringify(store.projects)); + } + + const sectionsStr = this.ls.getItem(LOCAL_STORAGE_KEY_SECTIONS); + if (sectionsStr) { + store.sections = JSON.parse(sectionsStr); + } else { + this.ls.setItem(LOCAL_STORAGE_KEY_SECTIONS, JSON.stringify(store.sections)); + } + + const filesStr = this.ls.getItem(LOCAL_STORAGE_KEY_FILES); + if (filesStr) { + store.files = JSON.parse(filesStr); + } else { + this.ls.setItem(LOCAL_STORAGE_KEY_FILES, JSON.stringify(store.files)); + } + + const commentsStr = this.ls.getItem(LOCAL_STORAGE_KEY_COMMENTS); + if (commentsStr) { + store.comments = JSON.parse(commentsStr); + } else { + this.ls.setItem(LOCAL_STORAGE_KEY_COMMENTS, JSON.stringify(store.comments)); + } + + return store; + } +} + +const initialProjects: ProjectData[] = [ + { + id: 'project-1', + }, + { + id: 'project-2', + }, +]; + +const initialSections: SectionData[] = [ + { + id: 'section-1', + projectId: 'project-1', + chordProgression: ['C', 'Dm', 'F', 'G'], + description: 'This is the intro', + title: 'Intro', + numRevisions: 3, + } +]; + +const initialFiles: FileData[] = [ + { + id: 'file-1', + projectId: 'project-1', + entityId: 'section-1', + entityType: EntityType.SECTION, + title: 'Bass.mp3', + }, + { + id: 'file-2', + projectId: 'project-1', + entityId: 'section-1', + entityType: EntityType.SECTION, + title: 'Chunky Monkey.mp3', + }, +]; + +const initialComments: CommentData[] = [ + { + id: 'comment-1', + projectId: 'project-1', + message: 'Hey what\'s up', + entityType: EntityType.SECTION, + entityId: 'section-1', + username: 'username-1', + }, + { + id: 'comment-2', + projectId: 'project-1', + message: 'Yeah', + entityType: EntityType.FILE, + entityId: 'file-1', + username: 'username-1', + }, + { + id: 'comment-3', + projectId: 'project-1', + message: 'Yeah 3', + entityType: EntityType.FILE, + entityId: 'file-1', + username: 'username-1', + }, +]; diff --git a/src/store/MockLocalStorageDependency.ts b/src/store/MockLocalStorageDependency.ts new file mode 100644 index 0000000..cfc9890 --- /dev/null +++ b/src/store/MockLocalStorageDependency.ts @@ -0,0 +1,24 @@ +import {LocalStorageDependency} from './LocalStorageStore'; + +export class MockLocalStorageDependency> implements LocalStorageDependency { + public currentData: T; + + constructor(data: T) { + this.currentData = data; + } + + getItem(key: string): string | null { + if (this.currentData[key]) { + return JSON.stringify(this.currentData[key]); + } + + return null; + } + + setItem(key: string, value: string): void { + this.currentData[key as keyof T] = JSON.parse(value); + } + clear(): void { + this.currentData = {} as T; + } +} diff --git a/src/types.ts b/src/types.ts index 9be5636..d70c88f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,29 +1,45 @@ - - -export type SectionData = { - name: string, - description: string, - numRevisions: number +export type ProjectData = { + id: string; } - - -export type ChordProgression = string[] - - -export type File = { - title: string, - numComments: number, - id: string, +export enum EntityType { + PROJECT = 'project', + SECTION = 'section', + FILE = 'file', } +export type EntityPointer = { + entityType: EntityType; + entityId: string; +} -export type Comment = { - name: string, - commentText: string +export type SectionData = { + id: string; + projectId: string; + title: string; + description: string; + numRevisions: number; + chordProgression: ChordProgression; } -export type commentsProps = { - comments: Comment[] - setComments: (comments: Comment[]) => void; +export type ChordProgression = string[] + +export type FileData = { + projectId: string; + id: string; + title: string; +} & EntityPointer; + +export type CommentData = { + projectId: string; + id: string; + username: string; + message: string; +} & EntityPointer; + +export type FullProjectData = { + project: ProjectData; + sections: SectionData[]; + comments: CommentData[]; + files: FileData[]; } diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..a2b81aa --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,13 @@ +import {EntityPointer, EntityType} from './types'; + +export const matchesEntityPointer = (entityPointer: EntityPointer, entityType: EntityType, entityId: string): boolean => { + return entityPointer.entityType === entityType && entityPointer.entityId === entityId; +} + +export const plural = (name: string, numItems: number) => { + if (numItems === 1) { + return name; + } + + return name + 's'; +}; diff --git a/src/setupTests.ts b/tests/setupTests.ts similarity index 100% rename from src/setupTests.ts rename to tests/setupTests.ts