Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compare since previous compare PR #4

Open
wants to merge 48 commits into
base: initial
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3ecc9ef
Refactor CSS reset to its own file. Standardize naming conventions
aelishRollo Apr 12, 2024
b947804
Change .parent to .root
aelishRollo Apr 12, 2024
5119278
Make sectionData, currentChordProgression, files, and comments, data …
aelishRollo Apr 12, 2024
ad77205
Refactor files to be its own component
aelishRollo Apr 13, 2024
69a671d
Refactor ChordProgression into a component
aelishRollo Apr 13, 2024
627dc8f
Refactor Chordprogression for to include the <div> with class chords
aelishRollo Apr 13, 2024
233b7e8
Refactor Files so <div> with class 'files' is all together
aelishRollo Apr 13, 2024
eb84b11
Refactor comments section into its own component
aelishRollo Apr 13, 2024
812d456
Refactor submit section into its own component
aelishRollo Apr 13, 2024
3b2d7e2
Refactor Section-Title into its own component
aelishRollo Apr 13, 2024
b0cd8b4
Give all component return statements pretty parentheses
aelishRollo Apr 20, 2024
aaeaec0
Refactor sectionData to be passed in as a prop
aelishRollo Apr 22, 2024
cf1bde7
Refactor chord progression component to use props
aelishRollo Apr 23, 2024
660977c
Refactor files component to use props
aelishRollo Apr 23, 2024
b494a52
Refactor Comments to use props
aelishRollo Apr 23, 2024
4dbcfec
Add an id for the array of files
aelishRollo Apr 24, 2024
22e7c24
Move type definitions to Types.ts
aelishRollo Apr 24, 2024
ae941bd
Add types to testData.ts
aelishRollo Apr 25, 2024
11c9a6e
Remove unnecessary import
aelishRollo Apr 25, 2024
ca323bb
Add export keywords to testData.ts
aelishRollo Apr 25, 2024
72db333
Move all data to testData.tsx
aelishRollo Apr 25, 2024
631ef8a
Refactor App.tsx to accept testData as a prop
aelishRollo Apr 26, 2024
4a263fc
Prepare to refactor components to their own files
aelishRollo Apr 26, 2024
41a8b2e
Refactor components to their own files
aelishRollo Apr 26, 2024
8855891
Add comments as state variable, hoist it
aelishRollo Apr 27, 2024
7620d10
Remove extra map from .submit
aelishRollo Apr 27, 2024
ac1ea6c
Rename Submit component to CreateComment
aelishRollo Apr 27, 2024
b06a3d4
Fix comment update bug
aelishRollo Apr 30, 2024
4fa90a9
Remove unnecessary imports
aelishRollo Apr 30, 2024
763e61f
Fix overflow issue when adding a new comment
aelishRollo Apr 30, 2024
948eaab
Make all types start with uppercase character
aelishRollo May 1, 2024
8413354
Move AppProps to App.jsx
aelishRollo May 1, 2024
b18ed6a
Move CreateCommentProps to CreateComment.tsx
aelishRollo May 1, 2024
b0b6b80
Move FilesProps definition to Files.tsx
aelishRollo May 1, 2024
9390c2d
Move ChordProgressionProps to ChordProgression.tsx
aelishRollo May 1, 2024
b9c09d0
Move SectionDataProps to SectionData.tsx
aelishRollo May 1, 2024
4b48b2c
Change 'Types' to 'types'
aelishRollo May 1, 2024
5842ae0
Change '.buttons' to '.revisions'
aelishRollo May 2, 2024
b949d42
User can now rename section title
aelishRollo May 3, 2024
7676ef0
Add parenthese to returned JSX
aelishRollo May 3, 2024
70206b1
Make amount of comments show on page
aelishRollo May 3, 2024
dff866e
Prep to move to localStorage
aelishRollo May 7, 2024
371de77
Make comments persistant using localStorage
aelishRollo May 8, 2024
2b25ef6
Rename testData.tsx to sampleData.tsx
aelishRollo May 8, 2024
8efdec6
Move comments data to localStorage
aelishRollo May 9, 2024
524408f
Create ci workflows for build and type checking (#7)
mickmister May 12, 2024
571c1b0
Update README.md
aelishRollo May 24, 2024
bc5af78
Refactor to use local storage (#8)
mickmister Jun 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down
17 changes: 13 additions & 4 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -11,16 +11,25 @@ import { useState } from 'react';



const App:React.FC<Types.appProps> = ({sectionData, chordProgression, comments, files}) => {

const [commentsAsState, setCommentsAsState] = useState<Types.comment[]>(comments)
type AppProps = {
sectionData: types.SectionData,
chordProgression: types.ChordProgression,
files: types.File[],
comments: types.Comment[]
}

const App:React.FC<AppProps> = ({sectionData, chordProgression, comments, files}) => {

const [commentsAsState, setCommentsAsState] = useState<types.Comment[]>(comments)


return (
<div className="root">
<SectionTitle sectionData={sectionData} />
<ChordProgression chordProgression={chordProgression} />
<Files files={files}/>
<Comments comments={commentsAsState}/>
<Comments comments={commentsAsState} setComments={setCommentsAsState}/>
<CreateComment comments={commentsAsState} setComments={setCommentsAsState}/>
</div>
);
Expand Down
9 changes: 7 additions & 2 deletions src/ChordProgression.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import * as Types from './types';
import * as types from './types';

export const ChordProgression: React.FC<Types.chordProgressionProps> = ({ chordProgression }) => {
type ChordProgressionProps = {
chordProgression: types.ChordProgression
}


export const ChordProgression: React.FC<ChordProgressionProps> = ({ chordProgression }) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not necessarily a problem, but having two things named the same (this component and types.ChordProgression, which is exported as a named export in the types.ts file) can cause issues when you want to use your IDE to import one of those two things. I usually name this ChordProgressionView or something like that to avoid the name collision

Suggested change
export const ChordProgression: React.FC<ChordProgressionProps> = ({ chordProgression }) => {
export const ChordProgressionView: React.FC<ChordProgressionProps> = ({ chordProgression }) => {

return (
<div className="chords">
<ol>
Expand Down
20 changes: 16 additions & 4 deletions src/Comments.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
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'
import {comments as initialComments} from './sampleData'
import { useEffect} from 'react';


export const Comments: React.FC<Types.commentsProps> = ({ comments = initialComments }) => {
export const Comments: React.FC<types.commentsProps> = ({ comments = initialComments, setComments }) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: types.commentProps should be moved into this file as Props or CommentsProps

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may make sense to create a src/components folder to put components like this


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);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eventually there will be other places where comments will be rendered, with comments on other types of things even. I think this component should receive one of these as a prop:

  • comments - Array of Comment
  • entity - {entity_type: string, entity_id: string}; mentioned in Comments data model #5

I like the second one more. Then the Comments component is responsible for fetching from the store these comments.

Fetch all project data at page load from project id pointers. But lazy load comment bodies. Make use of "See comments" buttons at times to delay loading.

}, []); // Empty dependency array ensures this runs once on mount
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice comment showing you know how this works. The comment itself is probably unnecessary for production code

Edit: This was signaling a linting error, so I disabled this line from the linting process



return (
<div className="comments">
<span>3 Comments</span>
<span>{comments.length} Comments</span>
<div className="display-comments">
{comments.map((comment, index) => {
return <>
Expand Down
58 changes: 48 additions & 10 deletions src/CreateComment.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,59 @@

import { CreateCommentProps, comment, commentsProps } from './types';
import {Comment} from './types';
import {useState} from 'react';

export const CreateComment:React.FC<CreateCommentProps> = ({comments, setComments}) => {

type CreateCommentProps = {
comments: Comment[],
setComments: (comments: Comment[]) => void;
}

const handleAddComment = (newComment:comment) => {
let result = [...comments]
result.push(newComment)
setComments(result)
console.log(result)


export const CreateComment: React.FC<CreateCommentProps> = ({ 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);
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Swag 👍 🤫



return (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should add a <textarea> or here to capture the user's comment

<div>
<button onClick={() => handleAddComment({name: "New User", commentText: "This is a new comment."})}>
Add Comment
</button>
<form onSubmit={(e) => {
e.preventDefault();
handleAddComment();
setCommentText('');
}}>
<input
type='text'
value={name}
onChange={(e) => setName(e.target.value)}
placeholder='Enter your name'
/>
<input
type='text'
value={commentText}
onChange={(e) => setCommentText(e.target.value)}
placeholder='Type your thoughts here'
/>
<button type='submit'>Add Comment</button>
</form>
</div>
);
};
13 changes: 9 additions & 4 deletions src/Files.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import * as Types from './types';
import * as types from './types';

export const Files: React.FC<Types.filesProps> = ({ files }) => {
type FilesProps = {
files: types.File[]
}

export const Files: React.FC<FilesProps> = ({ files }) => {
return (
<div className="files">
<span>+ Files</span>
{files.map((file) => <div id={file.id}>
{files.map((file) => (
<div id={file.id}>
{file.title}
<br></br> <br></br>
{file.numComments + ' '}
Comments
</div>)}
</div>))}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation looks off here. Should be more like this:

{files.map((file) => (
  <div id={file.id}>
    {file.title}
    <br></br> <br></br>
    {file.numComments + ' '}
    Comments
  </div>
))}

Also I tend to not use <br>, and instead do vertical spacing with css. Here I think I arbitrarily would create a file-title class that has margin-bottom

{files.map((file) => (
  <div id={file.id}>
    <p className='file-title'>{file.title}</p>
    <p className='file-num-comments'>
        {file.numComments + ' '}
        Comments
    </p>
  </div>
))}
.file-title {
  margin-bottom: 30px;
}

I set them to p, though span with display: inline-block would also work

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure there's a more appropriate way to make that positioned that way vertically. Also we need to make sure this looks good on mobile

</div>
);
};
57 changes: 46 additions & 11 deletions src/SectionTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,51 @@
import * as Types from './types';
import * as types from './types';
import React, { useState, FormEvent } from 'react'




type SectionDataProps = {
sectionData: types.SectionData,
}

export const SectionTitle: React.FC<SectionDataProps> = ({ 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<HTMLFormElement>) => {
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);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting to get the data from the form this way. Any particular reason you preferred this over using useState etc.?

};

export const SectionTitle: React.FC<Types.sectionDataProps> = ({ sectionData }) => {
return (
<div className="section-title">
<div className='text'>
<h1> {sectionData.name} </h1>
<p>{sectionData.description}</p>
</div>
<div className='buttons'>
<button> {sectionData.numRevisions} revisions </button>
<button> Save revision </button>
<div className="section-title">
<div className='text'>
<h1>{currentTitle}</h1>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have an idea of user experience of how we can edit the title. I think we should be able to click the current title, or an edit button next to it, and then the title becomes an input box where you can edit its content. Then the submit button changes back to an h1 element

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For an edit button, we can use the pencil icon from FontAwesome

https://fontawesome.com/icons/pencil?f=classic&s=solid
https://fontawesome.com/search

<p>{sectionData.description}</p>
<button onClick={handleToggleForm}>
{showForm ? 'Cancel Editing' : 'Rename Section'}
</button>
</div>
{showForm && (
<form onSubmit={handleSubmit}>
<label htmlFor="newName">New Name:</label>
<input id="newName" name="newName" type="text" placeholder="Enter new section name" />
<button type="submit">Update Name</button>
</form>
)}
<div className='revisions'>
<button>{sectionData.numRevisions} revisions</button>
<button>Save revision</button>
</div>
</div>
</div>
);
};
10 changes: 10 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

//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 {}
2 changes: 1 addition & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down
20 changes: 8 additions & 12 deletions src/testData.ts → src/sampleData.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -33,17 +33,13 @@ 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'
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'
},
]
2 changes: 1 addition & 1 deletion src/section_view.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ div {
font-size: 2rem;
}

.section-title .buttons {
.section-title .revisions {
flex-grow: 1;
display: flex;
justify-content: center;
Expand Down
40 changes: 6 additions & 34 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,29 @@

import React, { Dispatch } from "react"

export type sectionData = {
export type SectionData = {
name: string,
description: string,
numRevisions: number
}

export type sectionDataProps = {
sectionData: sectionData
}



export type chordProgression = string[]

export type chordProgressionProps = {
chordProgression: chordProgression
}
export type ChordProgression = string[]



export type file = {
export type File = {
title: string,
numComments: number,
id: string,
}

export type filesProps = {
files: file[]
}


export type comment = {
export type Comment = {
name: string,
commentText: string
}

export type commentsProps = {
comments: comment[]
}



export type CreateCommentProps = {
comments: comment[],
setComments: (comments: comment[]) => void;
}


export type appProps = {
sectionData: sectionData,
chordProgression: chordProgression,
files: file[],
comments: comment[]
comments: Comment[]
setComments: (comments: Comment[]) => void;
}