diff --git a/api/src/graphql/parts.sdl.js b/api/src/graphql/parts.sdl.js index dd46d83..1acf7eb 100644 --- a/api/src/graphql/parts.sdl.js +++ b/api/src/graphql/parts.sdl.js @@ -14,7 +14,7 @@ export const schema = gql` } type Query { - parts: [Part!]! + parts(userName: String): [Part!]! part(id: String!): Part partByUserAndTitle(userName: String!, partTitle: String!): Part } diff --git a/api/src/services/parts/parts.js b/api/src/services/parts/parts.js index e682f3c..d7b0df1 100644 --- a/api/src/services/parts/parts.js +++ b/api/src/services/parts/parts.js @@ -7,8 +7,18 @@ import { import { requireAuth } from 'src/lib/auth' import { requireOwnership } from 'src/lib/owner' -export const parts = () => { - return db.part.findMany({ where: { deleted: false } }) +export const parts = ({ userName }) => { + if (!userName) { + return db.part.findMany({ where: { deleted: false } }) + } + return db.part.findMany({ + where: { + deleted: false, + user: { + userName, + }, + }, + }) } export const part = ({ id }) => { diff --git a/web/src/components/Parts/Parts.js b/web/src/components/Parts/Parts.js index b2b1439..e20c865 100644 --- a/web/src/components/Parts/Parts.js +++ b/web/src/components/Parts/Parts.js @@ -10,11 +10,12 @@ const PartsList = ({ parts, shouldFilterPartsWithoutImage = false }) => { // related issue-104 const filteredParts = useMemo( () => - shouldFilterPartsWithoutImage + (shouldFilterPartsWithoutImage ? parts.filter(({ mainImage }) => mainImage) : [...parts] - // sort should probably be done on the service, but the filtering is temp too - .sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)), + ) + // sort should probably be done on the service, but the filtering is temp too + .sort((a, b) => new Date(b.updatedAt) - new Date(a.updatedAt)), [parts, shouldFilterPartsWithoutImage] ) return ( diff --git a/web/src/components/PartsOfUserCell/PartsOfUserCell.js b/web/src/components/PartsOfUserCell/PartsOfUserCell.js new file mode 100644 index 0000000..a0a55eb --- /dev/null +++ b/web/src/components/PartsOfUserCell/PartsOfUserCell.js @@ -0,0 +1,47 @@ +import { Link, routes } from '@redwoodjs/router' + +import Parts from 'src/components/Parts' + +export const QUERY = gql` + query PARTS_OF_USER($userName: String!) { + parts(userName: $userName) { + id + title + mainImage + createdAt + updatedAt + user { + image + userName + } + Reaction { + emote + } + } + } +` + +export const Loading = () =>
Loading...
+ +export const Empty = () => { + return ( +
+ {'No parts yet. '} + + {'Create one?'} + +
+ ) +} + +export const Success = ({ + parts, + variables: { shouldFilterPartsWithoutImage }, +}) => { + return ( + + ) +} diff --git a/web/src/components/PartsOfUserCell/PartsOfUserCell.mock.js b/web/src/components/PartsOfUserCell/PartsOfUserCell.mock.js new file mode 100644 index 0000000..a3cf5f8 --- /dev/null +++ b/web/src/components/PartsOfUserCell/PartsOfUserCell.mock.js @@ -0,0 +1,6 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + partsOfUser: { + id: 42, + }, +}) diff --git a/web/src/components/PartsOfUserCell/PartsOfUserCell.stories.js b/web/src/components/PartsOfUserCell/PartsOfUserCell.stories.js new file mode 100644 index 0000000..10289fe --- /dev/null +++ b/web/src/components/PartsOfUserCell/PartsOfUserCell.stories.js @@ -0,0 +1,20 @@ +import { Loading, Empty, Failure, Success } from './PartsOfUserCell' +import { standard } from './PartsOfUserCell.mock' + +export const loading = () => { + return Loading ? : null +} + +export const empty = () => { + return Empty ? : null +} + +export const failure = () => { + return Failure ? : null +} + +export const success = () => { + return Success ? : null +} + +export default { title: 'Cells/PartsOfUserCell' } diff --git a/web/src/components/PartsOfUserCell/PartsOfUserCell.test.js b/web/src/components/PartsOfUserCell/PartsOfUserCell.test.js new file mode 100644 index 0000000..c14e34e --- /dev/null +++ b/web/src/components/PartsOfUserCell/PartsOfUserCell.test.js @@ -0,0 +1,26 @@ +import { render, screen } from '@redwoodjs/testing' +import { Loading, Empty, Failure, Success } from './PartsOfUserCell' +import { standard } from './PartsOfUserCell.mock' + +describe('PartsOfUserCell', () => { + test('Loading renders successfully', () => { + render() + // Use screen.debug() to see output + expect(screen.getByText('Loading...')).toBeInTheDocument() + }) + + test('Empty renders successfully', async () => { + render() + expect(screen.getByText('Empty')).toBeInTheDocument() + }) + + test('Failure renders successfully', async () => { + render() + expect(screen.getByText(/Oh no/i)).toBeInTheDocument() + }) + + test('Success renders successfully', async () => { + render() + expect(screen.getByText(/42/i)).toBeInTheDocument() + }) +}) diff --git a/web/src/components/UserProfile/UserProfile.js b/web/src/components/UserProfile/UserProfile.js index 944203a..ae2b0bc 100644 --- a/web/src/components/UserProfile/UserProfile.js +++ b/web/src/components/UserProfile/UserProfile.js @@ -5,7 +5,7 @@ import Editor from 'rich-markdown-editor' import ImageUploader from 'src/components/ImageUploader' import Button from 'src/components/Button' import ProfileTextInput from 'src/components/ProfileTextInput' -import PartsCell from 'src/components/PartsCell' +import PartsOfUser from 'src/components/PartsOfUserCell' const UserProfile = ({ user, isEditable, loading, onSave, error, parts }) => { const { currentUser } = useAuth() @@ -93,7 +93,7 @@ const UserProfile = ({ user, isEditable, loading, onSave, error, parts }) => {

Parts:

- +