diff --git a/issue-tracker/README.md b/issue-tracker/README.md
index cd4d7986..4154b15a 100644
--- a/issue-tracker/README.md
+++ b/issue-tracker/README.md
@@ -50,6 +50,28 @@ You can run the app by navigating to `relay-examples/issue-tracker/` and then ru
This will start the development server (including Relay Compiler) and open a browser to [localhost:3000](http://localhost:3000).
+## Working on IssueTracker
+There are few key parts of IssueTracker:
+
+```shell
+├── public
+├── schema
+└── src
+ ├── __generated__
+ ├── components
+ ├── hooks
+ ├── pages
+ │ ├── IssueDetail
+ │ │ └── __generated__
+ │ └── Issues
+ │ └── __generated__
+ └── routing
+```
+- `schema`: Contains `graphql` schema
+- `components`: Contains foundational components used by other pages (e.g ErrorBoundary, SuspenseImage)
+- `hooks`: Contains all hooks available on this project
+- `pages`: Contains the modules for our routes and their own components
+- `routing`: Contains configurations and utility functions related to routes
## About the App
This app uses a number of technologies including (among others):
diff --git a/issue-tracker/src/ErrorBoundary.js b/issue-tracker/src/components/ErrorBoundary.js
similarity index 100%
rename from issue-tracker/src/ErrorBoundary.js
rename to issue-tracker/src/components/ErrorBoundary.js
diff --git a/issue-tracker/src/SuspenseImage.js b/issue-tracker/src/components/SuspenseImage.js
similarity index 96%
rename from issue-tracker/src/SuspenseImage.js
rename to issue-tracker/src/components/SuspenseImage.js
index dc0fc4f3..2bc3ee0f 100644
--- a/issue-tracker/src/SuspenseImage.js
+++ b/issue-tracker/src/components/SuspenseImage.js
@@ -1,5 +1,5 @@
import React from 'react';
-import JSResource from './JSResource';
+import JSResource from '../JSResource';
export default function SuspenseImage(props) {
const { src } = props;
diff --git a/issue-tracker/src/useMutation.js b/issue-tracker/src/hooks/useMutation.js
similarity index 100%
rename from issue-tracker/src/useMutation.js
rename to issue-tracker/src/hooks/useMutation.js
diff --git a/issue-tracker/src/IssueActions.js b/issue-tracker/src/pages/IssueDetail/IssueActions.js
similarity index 98%
rename from issue-tracker/src/IssueActions.js
rename to issue-tracker/src/pages/IssueDetail/IssueActions.js
index 4420d452..9ed6a3eb 100644
--- a/issue-tracker/src/IssueActions.js
+++ b/issue-tracker/src/pages/IssueDetail/IssueActions.js
@@ -2,7 +2,7 @@ import graphql from 'babel-plugin-relay/macro';
import React from 'react';
import { useFragment } from 'react-relay/hooks';
import { ConnectionHandler } from 'relay-runtime';
-import useMutation from './useMutation';
+import useMutation from '../../hooks/useMutation';
const { useCallback, useState } = React;
diff --git a/issue-tracker/src/pages/IssueDetail/IssueDetailComment.js b/issue-tracker/src/pages/IssueDetail/IssueDetailComment.js
new file mode 100644
index 00000000..6b6ebcbe
--- /dev/null
+++ b/issue-tracker/src/pages/IssueDetail/IssueDetailComment.js
@@ -0,0 +1,23 @@
+import ReactMarkdown from 'react-markdown';
+import SuspenseImage from '../../components/SuspenseImage';
+import React from 'react';
+
+export default function IssueDetailComment(props) {
+ const { comment } = props;
+ return (
+
+
+
{comment.author.login}
+
+
+
+
+ );
+}
diff --git a/issue-tracker/src/IssueDetailComments.js b/issue-tracker/src/pages/IssueDetail/IssueDetailComments.js
similarity index 77%
rename from issue-tracker/src/IssueDetailComments.js
rename to issue-tracker/src/pages/IssueDetail/IssueDetailComments.js
index 6dc35514..c03f92cf 100644
--- a/issue-tracker/src/IssueDetailComments.js
+++ b/issue-tracker/src/pages/IssueDetail/IssueDetailComments.js
@@ -1,8 +1,7 @@
import graphql from 'babel-plugin-relay/macro';
import React from 'react';
import { usePaginationFragment } from 'react-relay/hooks';
-import ReactMarkdown from 'react-markdown';
-import SuspenseImage from './SuspenseImage';
+import IssueDetailComment from './IssueDetailComment';
const { useCallback, useTransition, Suspense, SuspenseList } = React;
@@ -73,34 +72,15 @@ export default function IssueDetailComments(props) {
return (
<>
- {comments.map(edge => {
- if (edge == null || edge.node == null) {
- return null;
- }
- const comment = edge.node;
- return (
+ {comments
+ .filter(edge => edge != null || edge.node != null)
+ .map(edge => (
// Wrap each comment in a separate suspense fallback to allow them to commit
// individually; SuspenseList ensures they'll reveal in-order.
-