From 9b0a2834b9cc76bc3d1c1d16a2940f4451ad3692 Mon Sep 17 00:00:00 2001 From: Guillaume Jolibois <97659288+Joliwood@users.noreply.github.com> Date: Wed, 29 May 2024 12:16:56 +0200 Subject: [PATCH 1/2] :tada: Title suppression (#37) * :tada: :construction: profile page OK but still WIP for update profile section * :tada: new design between edit and view mode for infos user * :tada: button edit / save etc added * :tada: responsive OK * :tada: confirmation modal + logic suppression OK * :tada: redirection + logout added when account deleted * :sparkles: responsive added * :construction: update pencil button indicator added to song cards * :construction: nested modal added for confirmations * :tada: user can delete own songs * :zap: mutation var error fixed + responsive improve * :zap: likable fixed on listen page --- public/locales/en/translation.json | 2 + public/locales/fr/translation.json | 2 + src/components/favoritesPage/Favorites.tsx | 1 - src/components/listenPage/SongDisplay.tsx | 83 ++++++++--- .../profilePage/ProfileDeleteAccount.tsx | 7 +- .../profilePage/ProfileDeleteSong.tsx | 129 ++++++++++++++++++ .../profilePage/ProfileSongOrAlbum.tsx | 8 +- .../profilePage/ProfileUpdateSong.tsx | 76 +++++++++++ .../mutations/DeleteArtistMutation.ts | 2 +- src/requests/mutations/DeleteSongsMutation.ts | 9 ++ src/requests/mutations/index.ts | 1 + src/requests/queries/FavoriteSongsQuery.ts | 30 ++-- src/svg/PencilIcon.tsx | 31 +++++ src/types/__generated_schemas__/gql.ts | 13 +- src/types/__generated_schemas__/graphql.ts | 13 +- 15 files changed, 359 insertions(+), 48 deletions(-) create mode 100644 src/components/profilePage/ProfileDeleteSong.tsx create mode 100644 src/components/profilePage/ProfileUpdateSong.tsx create mode 100644 src/requests/mutations/DeleteSongsMutation.ts create mode 100644 src/svg/PencilIcon.tsx diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 5545acd..9c7166f 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -37,6 +37,8 @@ "DELETE_ACCOUNT_CONFIRM": "Are you sure you want to delete your account ? This action is irreversible.", "DELETE_ACCOUNT_ERROR": "An error occured, please try again later", "DELETE_ACCOUNT_SUCCESS": "Your account has been deleted successfully", + "DELETE_SONG_ERROR": "An error occured, please try again later", + "DELETE_SONG_SUCCESS": "The song has been deleted successfully", "FAVORITES_PAGE_EMPTY": "You haven't added songs to your favorites yet, click on the button bellow and start exploring our catalog.", "FAVORITES_PAGE_TITLE": "My Favorite Songs", "HERO_TXT_1": "Welcome on", diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index 8e22bdf..156fb9a 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -37,6 +37,8 @@ "DELETE_ACCOUNT_CONFIRM": "Êtes-vous sûr de vouloir supprimer votre compte ? Cette action est irréversible.", "DELETE_ACCOUNT_ERROR": "Une erreur est survenue lors de la suppression de votre compte. Veuillez réessayer plus tard.", "DELETE_ACCOUNT_SUCCESS": "Votre compte a bien été supprimé", + "DELETE_SONG_ERROR": "Une erreur est survenue lors de la suppression du son. Veuillez réessayer plus tard.", + "DELETE_SONG_SUCCESS": "Le son a bien été supprimé", "FAVORITES_PAGE_EMPTY": "Vous n'avez pas encore ajouté de titres à vos favoris. Cliquez sur le bouton ci-dessous pour commencer à explorer notre catalogue.", "FAVORITES_PAGE_TITLE": "Mes favoris", "HERO_TXT_1": "Bienvenu sur", diff --git a/src/components/favoritesPage/Favorites.tsx b/src/components/favoritesPage/Favorites.tsx index b66fbcf..e99503c 100644 --- a/src/components/favoritesPage/Favorites.tsx +++ b/src/components/favoritesPage/Favorites.tsx @@ -21,7 +21,6 @@ interface Props { function Favorites({ isLogin }: { isLogin: boolean }) { const { t } = useTranslation('translation'); const { data, loading, error } = useQuery(FavoriteSongsQuery, { - variables: { liked: true }, fetchPolicy: 'no-cache', }); const [songs, setSongs] = useState([]); diff --git a/src/components/listenPage/SongDisplay.tsx b/src/components/listenPage/SongDisplay.tsx index 640554a..3152e0d 100644 --- a/src/components/listenPage/SongDisplay.tsx +++ b/src/components/listenPage/SongDisplay.tsx @@ -1,18 +1,22 @@ -import React, { useEffect, useState } from 'react'; +/* eslint-disable jsx-a11y/control-has-associated-label */ +import React, { useEffect, useMemo, useState } from 'react'; import { SongCard } from '../customElements'; import { ListenPageSongsQueryQuery } from '../../types/__generated_schemas__/graphql'; +import ProfileUpdateSong from '../profilePage/ProfileUpdateSong'; interface Props { - songs: ListenPageSongsQueryQuery['songs']; + fromProfilePage?: boolean; isLogin: boolean; - sortBy: string | null; likable?: boolean; + songs: ListenPageSongsQueryQuery['songs']; + sortBy: string | null; } function SongDisplay({ + fromProfilePage = false, isLogin, - likable = false, + likable = true, songs, sortBy, }: Props) { @@ -55,25 +59,60 @@ function SongDisplay({ setSortedSongs(sorted); }, [songs, sortBy]); + const songCardsJSX = useMemo(() => { + if (!sortedSongs) { + return null; + } + + if (fromProfilePage) { + return sortedSongs.map( + (song) => { + if (!song) { + return null; + } + + return ( +
+ + +
+ ); + }, + ); + } + + return sortedSongs.map( + (song) => ( + + ), + ); + }, [fromProfilePage, isLogin, likable, sortedSongs]); + return ( -
- {sortedSongs && sortedSongs.map( - (song) => ( - // TODO - Fix the types - - ), - )} +
+ {songCardsJSX}
); } diff --git a/src/components/profilePage/ProfileDeleteAccount.tsx b/src/components/profilePage/ProfileDeleteAccount.tsx index 87d0294..eba6194 100644 --- a/src/components/profilePage/ProfileDeleteAccount.tsx +++ b/src/components/profilePage/ProfileDeleteAccount.tsx @@ -97,7 +97,12 @@ const ProfileDeleteAccount = () => { {/* Modal backdrop */}
- +
)} diff --git a/src/components/profilePage/ProfileDeleteSong.tsx b/src/components/profilePage/ProfileDeleteSong.tsx new file mode 100644 index 0000000..b905d9b --- /dev/null +++ b/src/components/profilePage/ProfileDeleteSong.tsx @@ -0,0 +1,129 @@ +/* eslint-disable jsx-a11y/control-has-associated-label */ +import React, { useCallback, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { ApolloError, useMutation } from '@apollo/client'; +import { DeleteSongsMutation } from '../../requests/mutations'; + +import { useNewToast } from '../toastContext'; +import { Spinner } from '../customElements'; + +type Props = { + closeParentModal: () => void; + songId: number; +}; + +const ProfileDeleteSong = (props: Props) => { + const [isOpen, setIsOpen] = useState(false); + const { t } = useTranslation(['common', 'translation']); + const newToast = useNewToast(); + const { closeParentModal, songId } = props; + const openModal = () => setIsOpen(true); + const modalId = 'delete_song_modal'; + + const closeModal = useCallback(() => { + setIsOpen(false); + closeParentModal(); + }, [closeParentModal]); + + const [DeleteSongsAction, { + loading: deleteSongsLoading, + error: deleteSongsError, + }] = useMutation(DeleteSongsMutation, { + variables: { + songIds: [songId], + }, + }); + + const handleDelete = useCallback(async () => { + try { + const response = await DeleteSongsAction(); + + if (response) { + newToast('success', t('DELETE_SONG_SUCCESS', { ns: 'translation' })); + closeModal(); + } + } catch (error) { + if (error instanceof ApolloError) { + if (error.graphQLErrors[0]?.extensions?.code === 'ARTIST_NAME_ALREADY_EXISTS') { + newToast('error', error.message); + return; + } + + if (error.graphQLErrors[0]?.extensions?.code === 'ARTIST_EMAIL_ALREADY_EXISTS') { + newToast('error', error.message); + return; + } + } + + if (deleteSongsError) { + newToast('error', deleteSongsError.message); + return; + } + + newToast('error', t('DELETE_SONG_ERROR', { ns: 'translation' })); + } + }, [DeleteSongsAction, closeModal, deleteSongsError, newToast, t]); + + const deleteButtonJSX = useMemo(() => { + if (deleteSongsLoading) { + return ( + + ); + } + + return ( + + ); + }, [deleteSongsLoading, handleDelete, t]); + + return ( + <> + {/* Delete Account Button */} +
+ +
+ + {isOpen && ( + +
+

{t('DELETE_ACCOUNT_CONFIRM', { ns: 'translation' })}

+
+ + {deleteButtonJSX} +
+
+ + {/* Modal backdrop */} +
+ +
+
+ )} + + ); +}; + +export default ProfileDeleteSong; diff --git a/src/components/profilePage/ProfileSongOrAlbum.tsx b/src/components/profilePage/ProfileSongOrAlbum.tsx index b2dee0c..c80eda6 100644 --- a/src/components/profilePage/ProfileSongOrAlbum.tsx +++ b/src/components/profilePage/ProfileSongOrAlbum.tsx @@ -33,7 +33,13 @@ const ProfileSongOrAlbum = (props: Props): JSX.Element => { } return ( - + ); }, [albums, chosenDisplay, loading, songs]); diff --git a/src/components/profilePage/ProfileUpdateSong.tsx b/src/components/profilePage/ProfileUpdateSong.tsx new file mode 100644 index 0000000..ac63386 --- /dev/null +++ b/src/components/profilePage/ProfileUpdateSong.tsx @@ -0,0 +1,76 @@ +/* eslint-disable jsx-a11y/control-has-associated-label */ +import React, { useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import PencilIcon from '../../svg/PencilIcon'; +import ProfileDeleteSong from './ProfileDeleteSong'; + +type Props = { + songId: number; +}; + +const ProfileUpdateSong = (props: Props) => { + const [isOpen, setIsOpen] = useState(false); + const { t } = useTranslation(['common', 'translation']); + const closeModal = () => setIsOpen(false); + const openModal = () => setIsOpen(true); + const modalId = 'update_song_modal'; + const { songId } = props; + + return ( + <> + {/* Delete Account Button */} +
+ +
+ + {isOpen && ( + +
+

En cours de modif song

+

Champ 1

+

Champ 2

+

Champ 3

+

Champ 4

+ +
+ + +
+ + + + + {/* Modal backdrop */} +
+ +
+
+ )} + + ); +}; +export default ProfileUpdateSong; diff --git a/src/requests/mutations/DeleteArtistMutation.ts b/src/requests/mutations/DeleteArtistMutation.ts index 5404a78..58143d2 100644 --- a/src/requests/mutations/DeleteArtistMutation.ts +++ b/src/requests/mutations/DeleteArtistMutation.ts @@ -1,7 +1,7 @@ import { gql } from '../../types/__generated_schemas__/gql'; const DeleteArtistMutation = gql(` - mutation Mutation { + mutation DeleteArtist { deleteArtist } `); diff --git a/src/requests/mutations/DeleteSongsMutation.ts b/src/requests/mutations/DeleteSongsMutation.ts new file mode 100644 index 0000000..7124e64 --- /dev/null +++ b/src/requests/mutations/DeleteSongsMutation.ts @@ -0,0 +1,9 @@ +import { gql } from '../../types/__generated_schemas__/gql'; + +const DeleteSongsMutation = gql(` + mutation DeleteSongs($songIds: [Int!]!) { + deleteSongs(ids: $songIds) + } +`); + +export default DeleteSongsMutation; diff --git a/src/requests/mutations/index.ts b/src/requests/mutations/index.ts index 1c292e0..bda2789 100644 --- a/src/requests/mutations/index.ts +++ b/src/requests/mutations/index.ts @@ -1,5 +1,6 @@ export { default as CreateArtistMutation } from './CreateArtistMutation'; export { default as DeleteArtistMutation } from './DeleteArtistMutation'; +export { default as DeleteSongsMutation } from './DeleteSongsMutation'; export { default as LikeSongMutation } from './LikeSongMutation'; export { default as UnlikeSongMutation } from './UnlikeSongMutation'; export { default as CreateSongMutation } from './CreateSongMutation'; diff --git a/src/requests/queries/FavoriteSongsQuery.ts b/src/requests/queries/FavoriteSongsQuery.ts index 7215a8f..90ad023 100644 --- a/src/requests/queries/FavoriteSongsQuery.ts +++ b/src/requests/queries/FavoriteSongsQuery.ts @@ -1,20 +1,20 @@ -import { gql } from '@apollo/client/core'; +import { gql } from '../../types/__generated_schemas__/gql'; -const FavotiteSongsQuery = gql` -query FavoriteSongsQuery { - songs(filter: { liked: true }) { - cover - duration - id - lyrics - title - isLiked - release_year - artist { - name +const FavotiteSongsQuery = gql(` + query FavoriteSongsQuery { + songs(filter: { liked: true }) { + cover + duration + id + lyrics + title + isLiked + release_year + artist { + name + } } } -} -`; +`); export default FavotiteSongsQuery; diff --git a/src/svg/PencilIcon.tsx b/src/svg/PencilIcon.tsx new file mode 100644 index 0000000..dda1b17 --- /dev/null +++ b/src/svg/PencilIcon.tsx @@ -0,0 +1,31 @@ +import React from 'react'; + +const PencilIcon = (): JSX.Element => ( + + + + +); + +export default PencilIcon; diff --git a/src/types/__generated_schemas__/gql.ts b/src/types/__generated_schemas__/gql.ts index a0b926b..47b886e 100644 --- a/src/types/__generated_schemas__/gql.ts +++ b/src/types/__generated_schemas__/gql.ts @@ -15,11 +15,12 @@ import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/ const documents = { "\n mutation CreateAlbum($input: AlbumCreateInput!) {\n addAlbum(input: $input) {\n id\n title\n cover\n release_year\n songs {\n id\n }\n }\n }\n": types.CreateAlbumDocument, "\n mutation CreateArtist($input: ArtistCreateInput!) {\n addArtist(input: $input) {\n country\n id\n name\n picture\n }\n }\n": types.CreateArtistDocument, + "\n mutation DeleteArtist {\n deleteArtist\n }\n": types.DeleteArtistDocument, + "\n mutation DeleteSongs($songIds: [Int!]!) {\n deleteSongs(ids: $songIds)\n }\n": types.DeleteSongsDocument, "\n mutation CreateSong($input: SongCreateInput!) {\n addSong(input: $input) {\n id\n title\n cover\n duration\n release_year\n lyrics\n }\n }\n": types.CreateSongDocument, - "\n mutation Mutation {\n deleteArtist\n }\n": types.MutationDocument, "\n mutation LikeSong($songId: Int!) {\n likeSong(id: $songId)\n }\n": types.LikeSongDocument, "\n mutation UnlikeSong($songId: Int!) {\n unlikeSong(id: $songId)\n }\n": types.UnlikeSongDocument, - "\nquery FavoriteSongsQuery {\n songs(filter: { liked: true }) {\n cover\n duration\n id\n lyrics\n title\n isLiked\n release_year\n artist {\n name\n }\n }\n}\n": types.FavoriteSongsQueryDocument, + "\n query FavoriteSongsQuery {\n songs(filter: { liked: true }) {\n cover\n duration\n id\n lyrics\n title\n isLiked\n release_year\n artist {\n name\n }\n }\n }\n": types.FavoriteSongsQueryDocument, "\n query ListenPageAlbumsQuery($limit: Int) {\n albums(limit: $limit){\n id\n title\n artist {\n name\n }\n cover\n release_year\n songs {\n id\n title\n duration\n }\n }\n }\n": types.ListenPageAlbumsQueryDocument, "\n query ListenPageSongsQuery($limit: Int) {\n songs(limit: $limit) {\n id\n title\n artist {\n name\n }\n cover\n duration\n release_year\n isLiked\n }\n }\n": types.ListenPageSongsQueryDocument, "\n query Login($input: LoginInput!) {\n login(input: $input) {\n expire_at\n token\n }\n }\n": types.LoginDocument, @@ -55,11 +56,15 @@ export function gql(source: "\n mutation CreateArtist($input: ArtistCreateInput /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ +export function gql(source: "\n mutation DeleteArtist {\n deleteArtist\n }\n"): (typeof documents)["\n mutation DeleteArtist {\n deleteArtist\n }\n"]; +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql(source: "\n mutation DeleteSongs($songIds: [Int!]!) {\n deleteSongs(ids: $songIds)\n }\n"): (typeof documents)["\n mutation DeleteSongs($songIds: [Int!]!) {\n deleteSongs(ids: $songIds)\n }\n"]; export function gql(source: "\n mutation CreateSong($input: SongCreateInput!) {\n addSong(input: $input) {\n id\n title\n cover\n duration\n release_year\n lyrics\n }\n }\n"): (typeof documents)["\n mutation CreateSong($input: SongCreateInput!) {\n addSong(input: $input) {\n id\n title\n cover\n duration\n release_year\n lyrics\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "\n mutation Mutation {\n deleteArtist\n }\n"): (typeof documents)["\n mutation Mutation {\n deleteArtist\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ @@ -71,7 +76,7 @@ export function gql(source: "\n mutation UnlikeSong($songId: Int!) {\n unlik /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ -export function gql(source: "\nquery FavoriteSongsQuery {\n songs(filter: { liked: true }) {\n cover\n duration\n id\n lyrics\n title\n isLiked\n release_year\n artist {\n name\n }\n }\n}\n"): (typeof documents)["\nquery FavoriteSongsQuery {\n songs(filter: { liked: true }) {\n cover\n duration\n id\n lyrics\n title\n isLiked\n release_year\n artist {\n name\n }\n }\n}\n"]; +export function gql(source: "\n query FavoriteSongsQuery {\n songs(filter: { liked: true }) {\n cover\n duration\n id\n lyrics\n title\n isLiked\n release_year\n artist {\n name\n }\n }\n }\n"): (typeof documents)["\n query FavoriteSongsQuery {\n songs(filter: { liked: true }) {\n cover\n duration\n id\n lyrics\n title\n isLiked\n release_year\n artist {\n name\n }\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/src/types/__generated_schemas__/graphql.ts b/src/types/__generated_schemas__/graphql.ts index 1af3c9d..9815997 100644 --- a/src/types/__generated_schemas__/graphql.ts +++ b/src/types/__generated_schemas__/graphql.ts @@ -301,6 +301,7 @@ export type CreateArtistMutationVariables = Exact<{ export type CreateArtistMutation = { __typename?: 'Mutation', addArtist?: { __typename?: 'Artist', country?: string | null, id: number, name: string, picture?: string | null } | null }; +export type DeleteArtistMutationVariables = Exact<{ [key: string]: never; }>; export type CreateSongMutationVariables = Exact<{ input: SongCreateInput; }>; @@ -308,10 +309,15 @@ export type CreateSongMutationVariables = Exact<{ export type CreateSongMutation = { __typename?: 'Mutation', addSong?: { __typename?: 'Song', id: number, title: string, cover?: string | null, duration: number, release_year?: number | null, lyrics?: string | null } | null }; -export type MutationMutationVariables = Exact<{ [key: string]: never; }>; +export type DeleteArtistMutation = { __typename?: 'Mutation', deleteArtist?: boolean | null }; -export type MutationMutation = { __typename?: 'Mutation', deleteArtist?: boolean | null }; +export type DeleteSongsMutationVariables = Exact<{ + songIds: Array | Scalars['Int']['input']; +}>; + + +export type DeleteSongsMutation = { __typename?: 'Mutation', deleteSongs?: boolean | null }; export type LikeSongMutationVariables = Exact<{ songId: Scalars['Int']['input']; @@ -387,8 +393,9 @@ export type UserSongsQueryQuery = { __typename?: 'Query', songs?: Array<{ __type export const CreateAlbumDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateAlbum"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"AlbumCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addAlbum"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"release_year"}},{"kind":"Field","name":{"kind":"Name","value":"songs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateArtistDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateArtist"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ArtistCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addArtist"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"picture"}}]}}]}}]} as unknown as DocumentNode; +export const DeleteArtistDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteArtist"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteArtist"}}]}}]} as unknown as DocumentNode; +export const DeleteSongsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteSongs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"songIds"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteSongs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"songIds"}}}]}]}}]} as unknown as DocumentNode; export const CreateSongDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSong"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"SongCreateInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"addSong"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"release_year"}},{"kind":"Field","name":{"kind":"Name","value":"lyrics"}}]}}]}}]} as unknown as DocumentNode; -export const MutationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"Mutation"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteArtist"}}]}}]} as unknown as DocumentNode; export const LikeSongDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"LikeSong"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"songId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"likeSong"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"songId"}}}]}]}}]} as unknown as DocumentNode; export const UnlikeSongDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UnlikeSong"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"songId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"unlikeSong"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"songId"}}}]}]}}]} as unknown as DocumentNode; export const FavoriteSongsQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FavoriteSongsQuery"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"songs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"liked"},"value":{"kind":"BooleanValue","value":true}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"lyrics"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"isLiked"}},{"kind":"Field","name":{"kind":"Name","value":"release_year"}},{"kind":"Field","name":{"kind":"Name","value":"artist"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; From 345ad589ce216afdae3671220e6220d9ea093988 Mon Sep 17 00:00:00 2001 From: Anthony Bourret <127198152+AnthonyBourret@users.noreply.github.com> Date: Wed, 29 May 2024 22:14:48 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=8E=89=20Search=20listen=20page=20(#3?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :construction: Songs & Albums Filtered Queries * :tada: Filtered Search + Responsive fixed * :hammer: Generated types ok * :hammer: Review correction * :hammer: Import types correction * :hammer: syntaxe fixed --- public/locales/en/common.json | 5 +- public/locales/fr/common.json | 7 +- src/components/customElements/FilterRadio.tsx | 16 +- src/components/listenPage/AlbumDisplay.tsx | 49 ++++-- src/components/listenPage/Listen.tsx | 14 +- src/components/listenPage/SearchBar.tsx | 145 ++++++++++++++---- src/components/listenPage/SongDisplay.tsx | 2 +- src/requests/queries/SearchAlbumsQuery.ts | 22 +++ src/requests/queries/SearchSongsQuery.ts | 19 +++ src/requests/queries/index.ts | 2 + src/types/__generated_schemas__/gql.ts | 10 ++ src/types/__generated_schemas__/graphql.ts | 18 +++ 12 files changed, 256 insertions(+), 53 deletions(-) create mode 100644 src/requests/queries/SearchAlbumsQuery.ts create mode 100644 src/requests/queries/SearchSongsQuery.ts diff --git a/public/locales/en/common.json b/public/locales/en/common.json index e988273..9003dc4 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -33,7 +33,10 @@ "SEARCH_BAR_BTN": "Search", "SEARCH_BAR_FILTER_ALBUM": "Albums", "SEARCH_BAR_FILTER_DURATION_TEXT": "Duration :", + "SEARCH_BAR_FILTER_RELEASE_TEXT": "Years :", "SEARCH_BAR_FILTER_SONG": "Songs", "SEARCH_BAR_PLACEHOLDER": "Search by...", - "SEARCH_BAR_TEXT": "What would you like to listen to ?" + "SEARCH_BAR_TEXT": "What would you like to listen to ?", + "SEARCH_RADIO_INPUT_TEXT": "Show all", + "SEARCH_RESULT_NULL": "No result found" } diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index bcbe2a1..a2375cc 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -31,8 +31,11 @@ "ORDER_SELECT_TEXT": "Trier par :", "SEARCH_BAR_BTN": "Chercher", "SEARCH_BAR_FILTER_ALBUM": "Albums", - "SEARCH_BAR_FILTER_DURATION_TEXT": "Durée", + "SEARCH_BAR_FILTER_DURATION_TEXT": "Durée :", + "SEARCH_BAR_FILTER_RELEASE_TEXT": "Années :", "SEARCH_BAR_FILTER_SONG": "Chansons", "SEARCH_BAR_PLACEHOLDER": "Chercher par...", - "SEARCH_BAR_TEXT": "Quelle voulez-vous écouter ?" + "SEARCH_BAR_TEXT": "Quelle voulez-vous écouter ?", + "SEARCH_RADIO_INPUT_TEXT": "Voir tout", + "SEARCH_RESULT_NULL": "Aucun résultat trouvé" } diff --git a/src/components/customElements/FilterRadio.tsx b/src/components/customElements/FilterRadio.tsx index f24a64d..470d258 100644 --- a/src/components/customElements/FilterRadio.tsx +++ b/src/components/customElements/FilterRadio.tsx @@ -1,16 +1,28 @@ import React from 'react'; +import { ReleaseYear, DurationRange } from '../../types/__generated_schemas__/graphql'; interface Props { inputId: string; labelText: string; + value?: ReleaseYear | DurationRange; + setFilter: React.Dispatch>; } -function FilterRadio({ inputId, labelText }: Props): JSX.Element { +function FilterRadio({ + inputId, labelText, value, setFilter, +}: Props): JSX.Element { return (
); diff --git a/src/components/listenPage/AlbumDisplay.tsx b/src/components/listenPage/AlbumDisplay.tsx index 056d93e..788c3db 100644 --- a/src/components/listenPage/AlbumDisplay.tsx +++ b/src/components/listenPage/AlbumDisplay.tsx @@ -1,6 +1,7 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; import { AlbumCard } from '../customElements'; -import { ListenPageAlbumsQueryQuery } from '../../types/__generated_schemas__/graphql'; +import type { ListenPageAlbumsQueryQuery } from '../../types/__generated_schemas__/graphql'; interface Props { albums: ListenPageAlbumsQueryQuery['albums']; @@ -9,6 +10,7 @@ interface Props { function AlbumDisplay({ albums, sortBy }: Props) { const [sortedAlbums, setSortedAlbums] = useState([]); + const { t } = useTranslation('common'); // The useEffect is used to make a new array of songs based on the sortBy value. // This array is sorted based on the value of sortBy. @@ -39,21 +41,36 @@ function AlbumDisplay({ albums, sortBy }: Props) { setSortedAlbums(sorted); }, [albums, sortBy]); + + const albumDisplayed = useMemo( + () => { + if (sortedAlbums && sortedAlbums.length > 0) { + return ( +
+ {sortedAlbums.map((album) => ( + album && ( + + ) + ))} +
+ ); + } + return ( +

{t('SEARCH_RESULT_NULL')}

+ ); + }, + [sortedAlbums, t], + ); return ( -
- {sortedAlbums && sortedAlbums.map((album) => ( - album && ( - - ) - ))} +
+ {albumDisplayed}
); } diff --git a/src/components/listenPage/Listen.tsx b/src/components/listenPage/Listen.tsx index 6e84d9c..0128453 100644 --- a/src/components/listenPage/Listen.tsx +++ b/src/components/listenPage/Listen.tsx @@ -7,7 +7,12 @@ import { ScrollToTopButton, SongAndAlbumOrder, Spinner } from '../customElements import { ChosenDisplay } from '../../types'; import SearchBar from './SearchBar'; import { ListenPageSongsQuery } from '../../requests/queries'; -import { ListenPageSongsQueryQuery, ListenPageAlbumsQueryQuery } from '../../types/__generated_schemas__/graphql'; +import type { + ListenPageSongsQueryQuery, + ListenPageAlbumsQueryQuery, + DurationRange, + ReleaseYear, +} from '../../types/__generated_schemas__/graphql'; function Listen({ isLogin }: { isLogin: boolean }) { const { data, loading, error } = useQuery(ListenPageSongsQuery, { variables: { limit: 30 } }); @@ -15,6 +20,8 @@ function Listen({ isLogin }: { isLogin: boolean }) { const [albums, setAlbums] = useState([]); const [chosenDisplay, setChosenDisplay] = useState('songs'); const [sortBy, setSortBy] = useState(null); + const [durationFilter, setDurationFilter] = useState(); + const [yearFilter, setYearFilter] = useState(); useEffect(() => { if (data?.songs !== undefined) { @@ -39,7 +46,12 @@ function Listen({ isLogin }: { isLogin: boolean }) { diff --git a/src/components/listenPage/SearchBar.tsx b/src/components/listenPage/SearchBar.tsx index 6a1cbd9..c21fb9d 100644 --- a/src/components/listenPage/SearchBar.tsx +++ b/src/components/listenPage/SearchBar.tsx @@ -1,21 +1,40 @@ -import React, { useMemo } from 'react'; +import React, { useState, useMemo } from 'react'; import { useLazyQuery } from '@apollo/client'; import { useTranslation } from 'react-i18next'; - +import { Logo } from '../../svg'; import { FilterRadio } from '../customElements'; import { ChosenDisplay } from '../../types'; -import { ListenPageAlbumsQuery } from '../../requests/queries'; -import { ListenPageAlbumsQueryQuery } from '../../types/__generated_schemas__/graphql'; -import PageTitle from '../customElements/PageTitle'; +import { ListenPageAlbumsQuery, SearchAlbumsQuery, SearchSongsQuery } from '../../requests/queries'; +import { + type ListenPageAlbumsQueryQuery, + type ListenPageSongsQueryQuery, + ReleaseYear, + DurationRange, +} from '../../types/__generated_schemas__/graphql'; interface Props { - chosenDisplay: string; + chosenDisplay: 'songs' | 'albums'; setChosenDisplay: React.Dispatch>; setAlbums: React.Dispatch>; + setSongs: React.Dispatch>; + setYearFilter: React.Dispatch>; + setDurationFilter: React.Dispatch>; + yearFilter?: ReleaseYear; + durationFilter?: DurationRange; } -function SearchBar({ chosenDisplay, setChosenDisplay, setAlbums }: Props): JSX.Element { +function SearchBar({ + chosenDisplay, + setChosenDisplay, + setAlbums, + setSongs, + setDurationFilter, + setYearFilter, + yearFilter, + durationFilter, +}: Props): JSX.Element { const { t } = useTranslation('common'); + const [nameFilter, setNameFilter] = useState(''); const [getAlbums] = useLazyQuery(ListenPageAlbumsQuery, { variables: { limit: 15 }, @@ -27,41 +46,111 @@ function SearchBar({ chosenDisplay, setChosenDisplay, setAlbums }: Props): JSX.E }, }); + const [getFilteredAlbums] = useLazyQuery(SearchAlbumsQuery, { + onCompleted: (data) => { + if (data.albums) { + setAlbums(data.albums); + setChosenDisplay('albums'); + } + }, + }); + + const [getFilteredSongs] = useLazyQuery(SearchSongsQuery, { + onCompleted: (data) => { + if (data.songs) { + setSongs(data.songs); + setChosenDisplay('songs'); + } + }, + }); + + const handleSearch = () => { + if (chosenDisplay === 'albums') { + getFilteredAlbums({ + variables: { + limit: 15, + filter: { name: nameFilter, release_year: yearFilter }, + }, + }); + } + if (chosenDisplay === 'songs') { + getFilteredSongs({ + variables: { + limit: 30, + filter: { name: nameFilter, duration_filter: durationFilter }, + }, + }); + } + }; + + // Function to change the display between songs and albums and reload the data without filters + const handleDisplayChanges = (display: ChosenDisplay) => { + setChosenDisplay(display); + setNameFilter(''); + if (display === 'albums') getAlbums({ variables: { limit: 15 } }); + if (display === 'songs') getFilteredSongs({ variables: { limit: 30 } }); + }; + const songDuration = useMemo(() => { if (chosenDisplay === 'albums') { return ( -
- - - - +
+
{t('SEARCH_BAR_FILTER_RELEASE_TEXT')}
+
+ + + + + + +
); } return ( -
- - - - +
+
{t('SEARCH_BAR_FILTER_DURATION_TEXT')}
+
+ + + + + +
); - }, [chosenDisplay]); + }, [chosenDisplay, t, setDurationFilter, setYearFilter]); - const bottomElement = useMemo(() => ( -
+ return ( +
+
+
+ +
+

{t('MENU_APP_NAME')}

+

{t('SEARCH_BAR_TEXT')}

+
{/* Search input => Filter on the request */}
- - + setNameFilter(e.target.value)} + /> +
{/* Duration input => Filter on the request */}
-
{t('SEARCH_BAR_FILTER_DURATION_TEXT')}
- {/* Radio Input Components changing on isAlbum value change */} {songDuration}
@@ -70,14 +159,14 @@ function SearchBar({ chosenDisplay, setChosenDisplay, setAlbums }: Props): JSX.E
- ), [chosenDisplay, getAlbums, setChosenDisplay, songDuration, t]); - - return ( - ); } diff --git a/src/components/listenPage/SongDisplay.tsx b/src/components/listenPage/SongDisplay.tsx index 3152e0d..c3b67f5 100644 --- a/src/components/listenPage/SongDisplay.tsx +++ b/src/components/listenPage/SongDisplay.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useState } from 'react'; import { SongCard } from '../customElements'; -import { ListenPageSongsQueryQuery } from '../../types/__generated_schemas__/graphql'; +import type { ListenPageSongsQueryQuery } from '../../types/__generated_schemas__/graphql'; import ProfileUpdateSong from '../profilePage/ProfileUpdateSong'; interface Props { diff --git a/src/requests/queries/SearchAlbumsQuery.ts b/src/requests/queries/SearchAlbumsQuery.ts new file mode 100644 index 0000000..04fdd1b --- /dev/null +++ b/src/requests/queries/SearchAlbumsQuery.ts @@ -0,0 +1,22 @@ +import { gql } from '../../types/__generated_schemas__/gql'; + +const SearchAlbumsQuery = gql(` + query SearchAlbumsQuery($limit: Int, $filter: AlbumFilterInput) { + albums(limit: $limit, filter: $filter) { + id + title + artist { + name + } + cover + release_year + songs { + id + title + duration + } + } + } +`); + +export default SearchAlbumsQuery; diff --git a/src/requests/queries/SearchSongsQuery.ts b/src/requests/queries/SearchSongsQuery.ts new file mode 100644 index 0000000..c1fc809 --- /dev/null +++ b/src/requests/queries/SearchSongsQuery.ts @@ -0,0 +1,19 @@ +import { gql } from '../../types/__generated_schemas__/gql'; + +const SearchSongsQuery = gql(` + query SearchSongsQuery($limit: Int, $filter: SongFilterInput) { + songs(limit: $limit, filter: $filter) { + id + title + artist { + name + } + cover + duration + release_year + isLiked + } + } +`); + +export default SearchSongsQuery; diff --git a/src/requests/queries/index.ts b/src/requests/queries/index.ts index c7fca87..5ea8bca 100644 --- a/src/requests/queries/index.ts +++ b/src/requests/queries/index.ts @@ -4,6 +4,8 @@ export { default as ListenPageSongsQuery } from './ListenPageSongsQuery'; export { default as LoginQuery } from './LoginQuery'; export { default as ProfileAlbums } from './ProfileAlbums'; export { default as ProfileQuery } from './ProfileQuery'; +export { default as SearchSongsQuery } from './SearchSongsQuery'; +export { default as SearchAlbumsQuery } from './SearchAlbumsQuery'; export { default as ProfileSongs } from './ProfileSongs'; export { default as SongOverviewQuery } from './SongOverviewQuery'; export { default as UserSongsQuery } from './UserSongsQuery'; diff --git a/src/types/__generated_schemas__/gql.ts b/src/types/__generated_schemas__/gql.ts index 47b886e..b5ed9f6 100644 --- a/src/types/__generated_schemas__/gql.ts +++ b/src/types/__generated_schemas__/gql.ts @@ -26,6 +26,8 @@ const documents = { "\n query Login($input: LoginInput!) {\n login(input: $input) {\n expire_at\n token\n }\n }\n": types.LoginDocument, "\n query ProfileAlbums($filter: AlbumFilterInput) {\n albums(filter: $filter){\n id\n title\n artist {\n name\n }\n cover\n release_year\n songs {\n id\n title\n duration\n }\n }\n }\n": types.ProfileAlbumsDocument, "\n query Profile {\n profile {\n country\n email\n name\n picture\n }\n }\n": types.ProfileDocument, + "\n query SearchAlbumsQuery($limit: Int, $filter: AlbumFilterInput) {\n albums(limit: $limit, filter: $filter) {\n id\n title\n artist {\n name\n }\n cover\n release_year\n songs {\n id\n title\n duration\n }\n }\n }\n": types.SearchAlbumsQueryDocument, + "\n query SearchSongsQuery($limit: Int, $filter: SongFilterInput) {\n songs(limit: $limit, filter: $filter) {\n id\n title\n artist {\n name\n }\n cover\n duration\n release_year\n isLiked\n }\n }\n": types.SearchSongsQueryDocument, "\n query ProfileSongs($filter: SongFilterInput) {\n songs(filter: $filter) {\n id\n title\n artist {\n name\n }\n cover\n duration\n release_year\n isLiked\n }\n }\n": types.ProfileSongsDocument, "\n query SongOverview {\n songs(limit: 5) {\n id\n cover\n title\n duration\n artist {\n name\n }\n }\n }\n": types.SongOverviewDocument, "\n query UserSongsQuery($createdByUser: Boolean!) {\n songs(filter: { createdByUser: $createdByUser}) {\n id\n title\n cover\n duration\n }\n }\n": types.UserSongsQueryDocument, @@ -97,6 +99,14 @@ export function gql(source: "\n query ProfileAlbums($filter: AlbumFilterInput) * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ export function gql(source: "\n query Profile {\n profile {\n country\n email\n name\n picture\n }\n }\n"): (typeof documents)["\n query Profile {\n profile {\n country\n email\n name\n picture\n }\n }\n"]; +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql(source: "\n query SearchAlbumsQuery($limit: Int, $filter: AlbumFilterInput) {\n albums(limit: $limit, filter: $filter) {\n id\n title\n artist {\n name\n }\n cover\n release_year\n songs {\n id\n title\n duration\n }\n }\n }\n"): (typeof documents)["\n query SearchAlbumsQuery($limit: Int, $filter: AlbumFilterInput) {\n albums(limit: $limit, filter: $filter) {\n id\n title\n artist {\n name\n }\n cover\n release_year\n songs {\n id\n title\n duration\n }\n }\n }\n"]; +/** + * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. + */ +export function gql(source: "\n query SearchSongsQuery($limit: Int, $filter: SongFilterInput) {\n songs(limit: $limit, filter: $filter) {\n id\n title\n artist {\n name\n }\n cover\n duration\n release_year\n isLiked\n }\n }\n"): (typeof documents)["\n query SearchSongsQuery($limit: Int, $filter: SongFilterInput) {\n songs(limit: $limit, filter: $filter) {\n id\n title\n artist {\n name\n }\n cover\n duration\n release_year\n isLiked\n }\n }\n"]; /** * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. */ diff --git a/src/types/__generated_schemas__/graphql.ts b/src/types/__generated_schemas__/graphql.ts index 9815997..741278f 100644 --- a/src/types/__generated_schemas__/graphql.ts +++ b/src/types/__generated_schemas__/graphql.ts @@ -371,6 +371,22 @@ export type ProfileQueryVariables = Exact<{ [key: string]: never; }>; export type ProfileQuery = { __typename?: 'Query', profile?: { __typename?: 'ArtistUser', country?: string | null, email: string, name: string, picture?: string | null } | null }; +export type SearchAlbumsQueryQueryVariables = Exact<{ + limit?: InputMaybe; + filter?: InputMaybe; +}>; + + +export type SearchAlbumsQueryQuery = { __typename?: 'Query', albums?: Array<{ __typename?: 'Album', id: number, title: string, cover?: string | null, release_year?: number | null, artist?: { __typename?: 'Artist', name: string } | null, songs?: Array<{ __typename?: 'Song', id: number, title: string, duration: number } | null> | null } | null> | null }; + +export type SearchSongsQueryQueryVariables = Exact<{ + limit?: InputMaybe; + filter?: InputMaybe; +}>; + + +export type SearchSongsQueryQuery = { __typename?: 'Query', songs?: Array<{ __typename?: 'Song', id: number, title: string, cover?: string | null, duration: number, release_year?: number | null, isLiked?: boolean | null, artist?: { __typename?: 'Artist', name: string } | null } | null> | null }; + export type ProfileSongsQueryVariables = Exact<{ filter?: InputMaybe; }>; @@ -404,6 +420,8 @@ export const ListenPageSongsQueryDocument = {"kind":"Document","definitions":[{" export const LoginDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Login"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"LoginInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"login"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire_at"}},{"kind":"Field","name":{"kind":"Name","value":"token"}}]}}]}}]} as unknown as DocumentNode; export const ProfileAlbumsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileAlbums"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"AlbumFilterInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"albums"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"artist"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"release_year"}},{"kind":"Field","name":{"kind":"Name","value":"songs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]}}]}}]} as unknown as DocumentNode; export const ProfileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"Profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"profile"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"picture"}}]}}]}}]} as unknown as DocumentNode; +export const SearchAlbumsQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SearchAlbumsQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"AlbumFilterInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"albums"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"artist"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"release_year"}},{"kind":"Field","name":{"kind":"Name","value":"songs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]}}]}}]} as unknown as DocumentNode; +export const SearchSongsQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SearchSongsQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"limit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SongFilterInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"songs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"limit"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"artist"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"release_year"}},{"kind":"Field","name":{"kind":"Name","value":"isLiked"}}]}}]}}]} as unknown as DocumentNode; export const ProfileSongsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ProfileSongs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SongFilterInput"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"songs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"artist"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"release_year"}},{"kind":"Field","name":{"kind":"Name","value":"isLiked"}}]}}]}}]} as unknown as DocumentNode; export const SongOverviewDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"SongOverview"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"songs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"limit"},"value":{"kind":"IntValue","value":"5"}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"artist"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; export const UserSongsQueryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"UserSongsQuery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"createdByUser"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"songs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"ObjectValue","fields":[{"kind":"ObjectField","name":{"kind":"Name","value":"createdByUser"},"value":{"kind":"Variable","name":{"kind":"Name","value":"createdByUser"}}}]}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"cover"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file