diff --git a/package-lock.json b/package-lock.json index e76a047..6bf8b7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2340,6 +2340,11 @@ } } }, + "@juggle/resize-observer": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.3.1.tgz", + "integrity": "sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw==" + }, "@mdx-js/util": { "version": "2.0.0-next.8", "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-2.0.0-next.8.tgz", @@ -2398,6 +2403,28 @@ } } }, + "@react-hook/latest": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@react-hook/latest/-/latest-1.0.3.tgz", + "integrity": "sha512-dy6duzl+JnAZcDbNTfmaP3xHiKtbXYOaz3G51MGVljh548Y8MWzTr+PHLOfvpypEVW9zwvl+VyKjbWKEVbV1Rg==" + }, + "@react-hook/passive-layout-effect": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@react-hook/passive-layout-effect/-/passive-layout-effect-1.2.1.tgz", + "integrity": "sha512-IwEphTD75liO8g+6taS+4oqz+nnroocNfWVHWz7j+N+ZO2vYrc6PV1q7GQhuahL0IOR7JccFTsFKQ/mb6iZWAg==" + }, + "@react-hook/resize-observer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@react-hook/resize-observer/-/resize-observer-1.2.2.tgz", + "integrity": "sha512-F7ciucmLrF4vZM78sUpRquvMCSVJwu3ayxapsHKKzTOvixZtcwJZocDBOasQQIbd7DtXzD/sVEJCKJUC0X1MDA==", + "requires": { + "@juggle/resize-observer": "^3.3.1", + "@react-hook/latest": "^1.0.2", + "@react-hook/passive-layout-effect": "^1.2.0", + "@types/raf-schd": "^4.0.0", + "raf-schd": "^4.0.2" + } + }, "@sideway/address": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz", @@ -2764,6 +2791,11 @@ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, + "@types/raf-schd": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/raf-schd/-/raf-schd-4.0.1.tgz", + "integrity": "sha512-Ha+EnKHFIh9EKW0/XZJPUd3EGDFisEvauaBd4VVCRPKeOqUxNEc9TodiY2Zhk33XCgzJucoFEcaoNcBAPHTQ2A==" + }, "@types/reach__router": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.8.tgz", @@ -5304,11 +5336,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" }, - "dequal": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz", - "integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==" - }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", @@ -13611,6 +13638,11 @@ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, + "raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -15794,14 +15826,6 @@ } } }, - "swr": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/swr/-/swr-0.5.5.tgz", - "integrity": "sha512-u4mUorK9Ipt+6LEITvWRWiRWAQjAysI6cHxbMmMV1dIdDzxMnswWo1CyGoyBHXX91CchxcuoqgFZ/ycx+YfhCA==", - "requires": { - "dequal": "2.0.2" - } - }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", diff --git a/package.json b/package.json index 9998b5a..835fa30 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "@fortawesome/free-brands-svg-icons": "^5.15.2", "@fortawesome/free-solid-svg-icons": "^5.15.2", "@fortawesome/react-fontawesome": "^0.1.14", + "@react-hook/resize-observer": "^1.2.2", "babel-plugin-prismjs": "^2.0.1", "babel-plugin-styled-components": "^1.11.1", "babel-preset-gatsby": "^1.3.0", diff --git a/schema.graphql b/schema.graphql index 59c4a4e..acfc994 100644 --- a/schema.graphql +++ b/schema.graphql @@ -336,6 +336,20 @@ type SiteSiteMetadata { siteUrl: String } +type SiteFunction implements Node { + functionRoute: String! + pluginName: String! + originalAbsoluteFilePath: String! + originalRelativeFilePath: String! + relativeCompiledFilePath: String! + absoluteCompiledFilePath: String! + matchPath: String + id: ID! + parent: Node + children: [Node!]! + internal: Internal! +} + type SitePage implements Node { path: String! component: String! @@ -350,7 +364,6 @@ type SitePage implements Node { context: SitePageContext pluginCreator: SitePlugin pluginCreatorId: String - componentPath: String } type SitePageContext { @@ -620,26 +633,6 @@ type BracketCharacter implements Node { internal: Internal! } -type SiteBuildMetadata implements Node { - id: ID! - parent: Node - children: [Node!]! - internal: Internal! - buildTime( - # Format the date using Moment.js' date tokens, e.g. `date(formatString: "YYYY MMMM DD")`. See https://momentjs.com/docs/#/displaying/format/ for documentation for different tokens. - formatString: String - - # Returns a string generated with Moment.js' `fromNow` function - fromNow: Boolean - - # Returns the difference between this date and the current time. Defaults to "milliseconds" but you can also pass in as the measurement "years", "months", "weeks", "days", "hours", "minutes", and "seconds". - difference: String - - # Configures the locale Moment.js will use to format the date. - locale: String - ): Date -} - type SitePlugin implements Node { id: ID! parent: Node @@ -716,6 +709,26 @@ type SitePluginPackageJsonPeerDependencies { version: String } +type SiteBuildMetadata implements Node { + id: ID! + parent: Node + children: [Node!]! + internal: Internal! + buildTime( + # Format the date using Moment.js' date tokens, e.g. `date(formatString: "YYYY MMMM DD")`. See https://momentjs.com/docs/#/displaying/format/ for documentation for different tokens. + formatString: String + + # Returns a string generated with Moment.js' `fromNow` function + fromNow: Boolean + + # Returns the difference between this date and the current time. Defaults to "milliseconds" but you can also pass in as the measurement "years", "months", "weeks", "days", "hours", "minutes", and "seconds". + difference: String + + # Configures the locale Moment.js will use to format the date. + locale: String + ): Date +} + type Query { file(sourceInstanceName: StringQueryOperatorInput, absolutePath: StringQueryOperatorInput, relativePath: StringQueryOperatorInput, extension: StringQueryOperatorInput, size: IntQueryOperatorInput, prettySize: StringQueryOperatorInput, modifiedTime: DateQueryOperatorInput, accessTime: DateQueryOperatorInput, changeTime: DateQueryOperatorInput, birthTime: DateQueryOperatorInput, root: StringQueryOperatorInput, dir: StringQueryOperatorInput, base: StringQueryOperatorInput, ext: StringQueryOperatorInput, name: StringQueryOperatorInput, relativeDirectory: StringQueryOperatorInput, dev: IntQueryOperatorInput, mode: IntQueryOperatorInput, nlink: IntQueryOperatorInput, uid: IntQueryOperatorInput, gid: IntQueryOperatorInput, rdev: IntQueryOperatorInput, ino: FloatQueryOperatorInput, atimeMs: FloatQueryOperatorInput, mtimeMs: FloatQueryOperatorInput, ctimeMs: FloatQueryOperatorInput, atime: DateQueryOperatorInput, mtime: DateQueryOperatorInput, ctime: DateQueryOperatorInput, birthtime: DateQueryOperatorInput, birthtimeMs: FloatQueryOperatorInput, id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput): File allFile(filter: FileFilterInput, sort: FileSortInput, skip: Int, limit: Int): FileConnection! @@ -723,7 +736,9 @@ type Query { allDirectory(filter: DirectoryFilterInput, sort: DirectorySortInput, skip: Int, limit: Int): DirectoryConnection! site(buildTime: DateQueryOperatorInput, siteMetadata: SiteSiteMetadataFilterInput, port: IntQueryOperatorInput, host: StringQueryOperatorInput, pathPrefix: StringQueryOperatorInput, polyfill: BooleanQueryOperatorInput, id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput): Site allSite(filter: SiteFilterInput, sort: SiteSortInput, skip: Int, limit: Int): SiteConnection! - sitePage(path: StringQueryOperatorInput, component: StringQueryOperatorInput, internalComponentName: StringQueryOperatorInput, componentChunkName: StringQueryOperatorInput, matchPath: StringQueryOperatorInput, id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput, isCreatedByStatefulCreatePages: BooleanQueryOperatorInput, context: SitePageContextFilterInput, pluginCreator: SitePluginFilterInput, pluginCreatorId: StringQueryOperatorInput, componentPath: StringQueryOperatorInput): SitePage + siteFunction(functionRoute: StringQueryOperatorInput, pluginName: StringQueryOperatorInput, originalAbsoluteFilePath: StringQueryOperatorInput, originalRelativeFilePath: StringQueryOperatorInput, relativeCompiledFilePath: StringQueryOperatorInput, absoluteCompiledFilePath: StringQueryOperatorInput, matchPath: StringQueryOperatorInput, id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput): SiteFunction + allSiteFunction(filter: SiteFunctionFilterInput, sort: SiteFunctionSortInput, skip: Int, limit: Int): SiteFunctionConnection! + sitePage(path: StringQueryOperatorInput, component: StringQueryOperatorInput, internalComponentName: StringQueryOperatorInput, componentChunkName: StringQueryOperatorInput, matchPath: StringQueryOperatorInput, id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput, isCreatedByStatefulCreatePages: BooleanQueryOperatorInput, context: SitePageContextFilterInput, pluginCreator: SitePluginFilterInput, pluginCreatorId: StringQueryOperatorInput): SitePage allSitePage(filter: SitePageFilterInput, sort: SitePageSortInput, skip: Int, limit: Int): SitePageConnection! anime(idRaw: IntQueryOperatorInput, name: StringQueryOperatorInput, slug: StringQueryOperatorInput, year: IntQueryOperatorInput, season: StringQueryOperatorInput, synopsis: StringQueryOperatorInput, synonyms: SynonymFilterListInput, themes: ThemeFilterListInput, series: SeriesFilterListInput, resources: ResourceFilterListInput, images: ImageFilterListInput, id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput): Anime allAnime(filter: AnimeFilterInput, sort: AnimeSortInput, skip: Int, limit: Int): AnimeConnection! @@ -769,10 +784,10 @@ type Query { allBracketPairing(filter: BracketPairingFilterInput, sort: BracketPairingSortInput, skip: Int, limit: Int): BracketPairingConnection! bracketCharacter(pairing: BracketPairingFilterInput, idRaw: IntQueryOperatorInput, seed: IntQueryOperatorInput, name: StringQueryOperatorInput, source: StringQueryOperatorInput, theme: ThemeFilterInput, id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput): BracketCharacter allBracketCharacter(filter: BracketCharacterFilterInput, sort: BracketCharacterSortInput, skip: Int, limit: Int): BracketCharacterConnection! - siteBuildMetadata(id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput, buildTime: DateQueryOperatorInput): SiteBuildMetadata - allSiteBuildMetadata(filter: SiteBuildMetadataFilterInput, sort: SiteBuildMetadataSortInput, skip: Int, limit: Int): SiteBuildMetadataConnection! sitePlugin(id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput, resolve: StringQueryOperatorInput, name: StringQueryOperatorInput, version: StringQueryOperatorInput, pluginOptions: SitePluginPluginOptionsFilterInput, nodeAPIs: StringQueryOperatorInput, browserAPIs: StringQueryOperatorInput, ssrAPIs: StringQueryOperatorInput, pluginFilepath: StringQueryOperatorInput, packageJson: SitePluginPackageJsonFilterInput): SitePlugin allSitePlugin(filter: SitePluginFilterInput, sort: SitePluginSortInput, skip: Int, limit: Int): SitePluginConnection! + siteBuildMetadata(id: StringQueryOperatorInput, parent: NodeFilterInput, children: NodeFilterListInput, internal: InternalFilterInput, buildTime: DateQueryOperatorInput): SiteBuildMetadata + allSiteBuildMetadata(filter: SiteBuildMetadataFilterInput, sort: SiteBuildMetadataSortInput, skip: Int, limit: Int): SiteBuildMetadataConnection! } input StringQueryOperatorInput { @@ -852,6 +867,9 @@ type FileConnection { nodes: [File!]! pageInfo: PageInfo! distinct(field: FileFieldsEnum!): [String!]! + max(field: FileFieldsEnum!): Float + min(field: FileFieldsEnum!): Float + sum(field: FileFieldsEnum!): Float group(skip: Int, limit: Int, field: FileFieldsEnum!): [FileGroupConnection!]! } @@ -1054,6 +1072,9 @@ type DirectoryConnection { nodes: [Directory!]! pageInfo: PageInfo! distinct(field: DirectoryFieldsEnum!): [String!]! + max(field: DirectoryFieldsEnum!): Float + min(field: DirectoryFieldsEnum!): Float + sum(field: DirectoryFieldsEnum!): Float group(skip: Int, limit: Int, field: DirectoryFieldsEnum!): [DirectoryGroupConnection!]! } @@ -1250,6 +1271,9 @@ type SiteConnection { nodes: [Site!]! pageInfo: PageInfo! distinct(field: SiteFieldsEnum!): [String!]! + max(field: SiteFieldsEnum!): Float + min(field: SiteFieldsEnum!): Float + sum(field: SiteFieldsEnum!): Float group(skip: Int, limit: Int, field: SiteFieldsEnum!): [SiteGroupConnection!]! } @@ -1386,6 +1410,148 @@ input SiteSortInput { order: [SortOrderEnum] = [ASC] } +type SiteFunctionConnection { + totalCount: Int! + edges: [SiteFunctionEdge!]! + nodes: [SiteFunction!]! + pageInfo: PageInfo! + distinct(field: SiteFunctionFieldsEnum!): [String!]! + max(field: SiteFunctionFieldsEnum!): Float + min(field: SiteFunctionFieldsEnum!): Float + sum(field: SiteFunctionFieldsEnum!): Float + group(skip: Int, limit: Int, field: SiteFunctionFieldsEnum!): [SiteFunctionGroupConnection!]! +} + +type SiteFunctionEdge { + next: SiteFunction + node: SiteFunction! + previous: SiteFunction +} + +enum SiteFunctionFieldsEnum { + functionRoute + pluginName + originalAbsoluteFilePath + originalRelativeFilePath + relativeCompiledFilePath + absoluteCompiledFilePath + matchPath + id + parent___id + parent___parent___id + parent___parent___parent___id + parent___parent___parent___children + parent___parent___children + parent___parent___children___id + parent___parent___children___children + parent___parent___internal___content + parent___parent___internal___contentDigest + parent___parent___internal___description + parent___parent___internal___fieldOwners + parent___parent___internal___ignoreType + parent___parent___internal___mediaType + parent___parent___internal___owner + parent___parent___internal___type + parent___children + parent___children___id + parent___children___parent___id + parent___children___parent___children + parent___children___children + parent___children___children___id + parent___children___children___children + parent___children___internal___content + parent___children___internal___contentDigest + parent___children___internal___description + parent___children___internal___fieldOwners + parent___children___internal___ignoreType + parent___children___internal___mediaType + parent___children___internal___owner + parent___children___internal___type + parent___internal___content + parent___internal___contentDigest + parent___internal___description + parent___internal___fieldOwners + parent___internal___ignoreType + parent___internal___mediaType + parent___internal___owner + parent___internal___type + children + children___id + children___parent___id + children___parent___parent___id + children___parent___parent___children + children___parent___children + children___parent___children___id + children___parent___children___children + children___parent___internal___content + children___parent___internal___contentDigest + children___parent___internal___description + children___parent___internal___fieldOwners + children___parent___internal___ignoreType + children___parent___internal___mediaType + children___parent___internal___owner + children___parent___internal___type + children___children + children___children___id + children___children___parent___id + children___children___parent___children + children___children___children + children___children___children___id + children___children___children___children + children___children___internal___content + children___children___internal___contentDigest + children___children___internal___description + children___children___internal___fieldOwners + children___children___internal___ignoreType + children___children___internal___mediaType + children___children___internal___owner + children___children___internal___type + children___internal___content + children___internal___contentDigest + children___internal___description + children___internal___fieldOwners + children___internal___ignoreType + children___internal___mediaType + children___internal___owner + children___internal___type + internal___content + internal___contentDigest + internal___description + internal___fieldOwners + internal___ignoreType + internal___mediaType + internal___owner + internal___type +} + +type SiteFunctionGroupConnection { + totalCount: Int! + edges: [SiteFunctionEdge!]! + nodes: [SiteFunction!]! + pageInfo: PageInfo! + field: String! + fieldValue: String +} + +input SiteFunctionFilterInput { + functionRoute: StringQueryOperatorInput + pluginName: StringQueryOperatorInput + originalAbsoluteFilePath: StringQueryOperatorInput + originalRelativeFilePath: StringQueryOperatorInput + relativeCompiledFilePath: StringQueryOperatorInput + absoluteCompiledFilePath: StringQueryOperatorInput + matchPath: StringQueryOperatorInput + id: StringQueryOperatorInput + parent: NodeFilterInput + children: NodeFilterListInput + internal: InternalFilterInput +} + +input SiteFunctionSortInput { + fields: [SiteFunctionFieldsEnum] + order: [SortOrderEnum] = [ASC] +} + input SitePageContextFilterInput { slug: StringQueryOperatorInput id: StringQueryOperatorInput @@ -1490,6 +1656,9 @@ type SitePageConnection { nodes: [SitePage!]! pageInfo: PageInfo! distinct(field: SitePageFieldsEnum!): [String!]! + max(field: SitePageFieldsEnum!): Float + min(field: SitePageFieldsEnum!): Float + sum(field: SitePageFieldsEnum!): Float group(skip: Int, limit: Int, field: SitePageFieldsEnum!): [SitePageGroupConnection!]! } @@ -1690,7 +1859,6 @@ enum SitePageFieldsEnum { pluginCreator___packageJson___peerDependencies___version pluginCreator___packageJson___keywords pluginCreatorId - componentPath } type SitePageGroupConnection { @@ -1716,7 +1884,6 @@ input SitePageFilterInput { context: SitePageContextFilterInput pluginCreator: SitePluginFilterInput pluginCreatorId: StringQueryOperatorInput - componentPath: StringQueryOperatorInput } input SitePageSortInput { @@ -1906,6 +2073,9 @@ type AnimeConnection { nodes: [Anime!]! pageInfo: PageInfo! distinct(field: AnimeFieldsEnum!): [String!]! + max(field: AnimeFieldsEnum!): Float + min(field: AnimeFieldsEnum!): Float + sum(field: AnimeFieldsEnum!): Float group(skip: Int, limit: Int, field: AnimeFieldsEnum!): [AnimeGroupConnection!]! } @@ -2462,6 +2632,9 @@ type SynonymConnection { nodes: [Synonym!]! pageInfo: PageInfo! distinct(field: SynonymFieldsEnum!): [String!]! + max(field: SynonymFieldsEnum!): Float + min(field: SynonymFieldsEnum!): Float + sum(field: SynonymFieldsEnum!): Float group(skip: Int, limit: Int, field: SynonymFieldsEnum!): [SynonymGroupConnection!]! } @@ -2770,6 +2943,9 @@ type ThemeConnection { nodes: [Theme!]! pageInfo: PageInfo! distinct(field: ThemeFieldsEnum!): [String!]! + max(field: ThemeFieldsEnum!): Float + min(field: ThemeFieldsEnum!): Float + sum(field: ThemeFieldsEnum!): Float group(skip: Int, limit: Int, field: ThemeFieldsEnum!): [ThemeGroupConnection!]! } @@ -3320,6 +3496,9 @@ type EntryConnection { nodes: [Entry!]! pageInfo: PageInfo! distinct(field: EntryFieldsEnum!): [String!]! + max(field: EntryFieldsEnum!): Float + min(field: EntryFieldsEnum!): Float + sum(field: EntryFieldsEnum!): Float group(skip: Int, limit: Int, field: EntryFieldsEnum!): [EntryGroupConnection!]! } @@ -3697,6 +3876,9 @@ type VideoConnection { nodes: [Video!]! pageInfo: PageInfo! distinct(field: VideoFieldsEnum!): [String!]! + max(field: VideoFieldsEnum!): Float + min(field: VideoFieldsEnum!): Float + sum(field: VideoFieldsEnum!): Float group(skip: Int, limit: Int, field: VideoFieldsEnum!): [VideoGroupConnection!]! } @@ -3952,6 +4134,9 @@ type SongConnection { nodes: [Song!]! pageInfo: PageInfo! distinct(field: SongFieldsEnum!): [String!]! + max(field: SongFieldsEnum!): Float + min(field: SongFieldsEnum!): Float + sum(field: SongFieldsEnum!): Float group(skip: Int, limit: Int, field: SongFieldsEnum!): [SongGroupConnection!]! } @@ -4334,6 +4519,9 @@ type PerformanceConnection { nodes: [Performance!]! pageInfo: PageInfo! distinct(field: PerformanceFieldsEnum!): [String!]! + max(field: PerformanceFieldsEnum!): Float + min(field: PerformanceFieldsEnum!): Float + sum(field: PerformanceFieldsEnum!): Float group(skip: Int, limit: Int, field: PerformanceFieldsEnum!): [PerformanceGroupConnection!]! } @@ -4676,6 +4864,9 @@ type ArtistConnection { nodes: [Artist!]! pageInfo: PageInfo! distinct(field: ArtistFieldsEnum!): [String!]! + max(field: ArtistFieldsEnum!): Float + min(field: ArtistFieldsEnum!): Float + sum(field: ArtistFieldsEnum!): Float group(skip: Int, limit: Int, field: ArtistFieldsEnum!): [ArtistGroupConnection!]! } @@ -4981,6 +5172,9 @@ type SeriesConnection { nodes: [Series!]! pageInfo: PageInfo! distinct(field: SeriesFieldsEnum!): [String!]! + max(field: SeriesFieldsEnum!): Float + min(field: SeriesFieldsEnum!): Float + sum(field: SeriesFieldsEnum!): Float group(skip: Int, limit: Int, field: SeriesFieldsEnum!): [SeriesGroupConnection!]! } @@ -5291,6 +5485,9 @@ type ResourceConnection { nodes: [Resource!]! pageInfo: PageInfo! distinct(field: ResourceFieldsEnum!): [String!]! + max(field: ResourceFieldsEnum!): Float + min(field: ResourceFieldsEnum!): Float + sum(field: ResourceFieldsEnum!): Float group(skip: Int, limit: Int, field: ResourceFieldsEnum!): [ResourceGroupConnection!]! } @@ -5412,6 +5609,9 @@ type ImageConnection { nodes: [Image!]! pageInfo: PageInfo! distinct(field: ImageFieldsEnum!): [String!]! + max(field: ImageFieldsEnum!): Float + min(field: ImageFieldsEnum!): Float + sum(field: ImageFieldsEnum!): Float group(skip: Int, limit: Int, field: ImageFieldsEnum!): [ImageGroupConnection!]! } @@ -5533,6 +5733,9 @@ type AnimeSeriesConnection { nodes: [AnimeSeries!]! pageInfo: PageInfo! distinct(field: AnimeSeriesFieldsEnum!): [String!]! + max(field: AnimeSeriesFieldsEnum!): Float + min(field: AnimeSeriesFieldsEnum!): Float + sum(field: AnimeSeriesFieldsEnum!): Float group(skip: Int, limit: Int, field: AnimeSeriesFieldsEnum!): [AnimeSeriesGroupConnection!]! } @@ -5941,6 +6144,9 @@ type EntryVideoConnection { nodes: [EntryVideo!]! pageInfo: PageInfo! distinct(field: EntryVideoFieldsEnum!): [String!]! + max(field: EntryVideoFieldsEnum!): Float + min(field: EntryVideoFieldsEnum!): Float + sum(field: EntryVideoFieldsEnum!): Float group(skip: Int, limit: Int, field: EntryVideoFieldsEnum!): [EntryVideoGroupConnection!]! } @@ -6284,6 +6490,9 @@ type AnimeResourceConnection { nodes: [AnimeResource!]! pageInfo: PageInfo! distinct(field: AnimeResourceFieldsEnum!): [String!]! + max(field: AnimeResourceFieldsEnum!): Float + min(field: AnimeResourceFieldsEnum!): Float + sum(field: AnimeResourceFieldsEnum!): Float group(skip: Int, limit: Int, field: AnimeResourceFieldsEnum!): [AnimeResourceGroupConnection!]! } @@ -6640,6 +6849,9 @@ type ArtistResourceConnection { nodes: [ArtistResource!]! pageInfo: PageInfo! distinct(field: ArtistResourceFieldsEnum!): [String!]! + max(field: ArtistResourceFieldsEnum!): Float + min(field: ArtistResourceFieldsEnum!): Float + sum(field: ArtistResourceFieldsEnum!): Float group(skip: Int, limit: Int, field: ArtistResourceFieldsEnum!): [ArtistResourceGroupConnection!]! } @@ -6915,6 +7127,9 @@ type AnimeImageConnection { nodes: [AnimeImage!]! pageInfo: PageInfo! distinct(field: AnimeImageFieldsEnum!): [String!]! + max(field: AnimeImageFieldsEnum!): Float + min(field: AnimeImageFieldsEnum!): Float + sum(field: AnimeImageFieldsEnum!): Float group(skip: Int, limit: Int, field: AnimeImageFieldsEnum!): [AnimeImageGroupConnection!]! } @@ -7271,6 +7486,9 @@ type ArtistImageConnection { nodes: [ArtistImage!]! pageInfo: PageInfo! distinct(field: ArtistImageFieldsEnum!): [String!]! + max(field: ArtistImageFieldsEnum!): Float + min(field: ArtistImageFieldsEnum!): Float + sum(field: ArtistImageFieldsEnum!): Float group(skip: Int, limit: Int, field: ArtistImageFieldsEnum!): [ArtistImageGroupConnection!]! } @@ -7546,6 +7764,9 @@ type AnnouncementConnection { nodes: [Announcement!]! pageInfo: PageInfo! distinct(field: AnnouncementFieldsEnum!): [String!]! + max(field: AnnouncementFieldsEnum!): Float + min(field: AnnouncementFieldsEnum!): Float + sum(field: AnnouncementFieldsEnum!): Float group(skip: Int, limit: Int, field: AnnouncementFieldsEnum!): [AnnouncementGroupConnection!]! } @@ -7733,6 +7954,9 @@ type BracketConnection { nodes: [Bracket!]! pageInfo: PageInfo! distinct(field: BracketFieldsEnum!): [String!]! + max(field: BracketFieldsEnum!): Float + min(field: BracketFieldsEnum!): Float + sum(field: BracketFieldsEnum!): Float group(skip: Int, limit: Int, field: BracketFieldsEnum!): [BracketGroupConnection!]! } @@ -8063,6 +8287,9 @@ type BracketRoundConnection { nodes: [BracketRound!]! pageInfo: PageInfo! distinct(field: BracketRoundFieldsEnum!): [String!]! + max(field: BracketRoundFieldsEnum!): Float + min(field: BracketRoundFieldsEnum!): Float + sum(field: BracketRoundFieldsEnum!): Float group(skip: Int, limit: Int, field: BracketRoundFieldsEnum!): [BracketRoundGroupConnection!]! } @@ -8415,6 +8642,9 @@ type BracketPairingConnection { nodes: [BracketPairing!]! pageInfo: PageInfo! distinct(field: BracketPairingFieldsEnum!): [String!]! + max(field: BracketPairingFieldsEnum!): Float + min(field: BracketPairingFieldsEnum!): Float + sum(field: BracketPairingFieldsEnum!): Float group(skip: Int, limit: Int, field: BracketPairingFieldsEnum!): [BracketPairingGroupConnection!]! } @@ -8885,6 +9115,9 @@ type BracketCharacterConnection { nodes: [BracketCharacter!]! pageInfo: PageInfo! distinct(field: BracketCharacterFieldsEnum!): [String!]! + max(field: BracketCharacterFieldsEnum!): Float + min(field: BracketCharacterFieldsEnum!): Float + sum(field: BracketCharacterFieldsEnum!): Float group(skip: Int, limit: Int, field: BracketCharacterFieldsEnum!): [BracketCharacterGroupConnection!]! } @@ -9293,139 +9526,15 @@ input BracketCharacterSortInput { order: [SortOrderEnum] = [ASC] } -type SiteBuildMetadataConnection { - totalCount: Int! - edges: [SiteBuildMetadataEdge!]! - nodes: [SiteBuildMetadata!]! - pageInfo: PageInfo! - distinct(field: SiteBuildMetadataFieldsEnum!): [String!]! - group(skip: Int, limit: Int, field: SiteBuildMetadataFieldsEnum!): [SiteBuildMetadataGroupConnection!]! -} - -type SiteBuildMetadataEdge { - next: SiteBuildMetadata - node: SiteBuildMetadata! - previous: SiteBuildMetadata -} - -enum SiteBuildMetadataFieldsEnum { - id - parent___id - parent___parent___id - parent___parent___parent___id - parent___parent___parent___children - parent___parent___children - parent___parent___children___id - parent___parent___children___children - parent___parent___internal___content - parent___parent___internal___contentDigest - parent___parent___internal___description - parent___parent___internal___fieldOwners - parent___parent___internal___ignoreType - parent___parent___internal___mediaType - parent___parent___internal___owner - parent___parent___internal___type - parent___children - parent___children___id - parent___children___parent___id - parent___children___parent___children - parent___children___children - parent___children___children___id - parent___children___children___children - parent___children___internal___content - parent___children___internal___contentDigest - parent___children___internal___description - parent___children___internal___fieldOwners - parent___children___internal___ignoreType - parent___children___internal___mediaType - parent___children___internal___owner - parent___children___internal___type - parent___internal___content - parent___internal___contentDigest - parent___internal___description - parent___internal___fieldOwners - parent___internal___ignoreType - parent___internal___mediaType - parent___internal___owner - parent___internal___type - children - children___id - children___parent___id - children___parent___parent___id - children___parent___parent___children - children___parent___children - children___parent___children___id - children___parent___children___children - children___parent___internal___content - children___parent___internal___contentDigest - children___parent___internal___description - children___parent___internal___fieldOwners - children___parent___internal___ignoreType - children___parent___internal___mediaType - children___parent___internal___owner - children___parent___internal___type - children___children - children___children___id - children___children___parent___id - children___children___parent___children - children___children___children - children___children___children___id - children___children___children___children - children___children___internal___content - children___children___internal___contentDigest - children___children___internal___description - children___children___internal___fieldOwners - children___children___internal___ignoreType - children___children___internal___mediaType - children___children___internal___owner - children___children___internal___type - children___internal___content - children___internal___contentDigest - children___internal___description - children___internal___fieldOwners - children___internal___ignoreType - children___internal___mediaType - children___internal___owner - children___internal___type - internal___content - internal___contentDigest - internal___description - internal___fieldOwners - internal___ignoreType - internal___mediaType - internal___owner - internal___type - buildTime -} - -type SiteBuildMetadataGroupConnection { - totalCount: Int! - edges: [SiteBuildMetadataEdge!]! - nodes: [SiteBuildMetadata!]! - pageInfo: PageInfo! - field: String! - fieldValue: String -} - -input SiteBuildMetadataFilterInput { - id: StringQueryOperatorInput - parent: NodeFilterInput - children: NodeFilterListInput - internal: InternalFilterInput - buildTime: DateQueryOperatorInput -} - -input SiteBuildMetadataSortInput { - fields: [SiteBuildMetadataFieldsEnum] - order: [SortOrderEnum] = [ASC] -} - type SitePluginConnection { totalCount: Int! edges: [SitePluginEdge!]! nodes: [SitePlugin!]! pageInfo: PageInfo! distinct(field: SitePluginFieldsEnum!): [String!]! + max(field: SitePluginFieldsEnum!): Float + min(field: SitePluginFieldsEnum!): Float + sum(field: SitePluginFieldsEnum!): Float group(skip: Int, limit: Int, field: SitePluginFieldsEnum!): [SitePluginGroupConnection!]! } @@ -9589,3 +9698,133 @@ input SitePluginSortInput { fields: [SitePluginFieldsEnum] order: [SortOrderEnum] = [ASC] } + +type SiteBuildMetadataConnection { + totalCount: Int! + edges: [SiteBuildMetadataEdge!]! + nodes: [SiteBuildMetadata!]! + pageInfo: PageInfo! + distinct(field: SiteBuildMetadataFieldsEnum!): [String!]! + max(field: SiteBuildMetadataFieldsEnum!): Float + min(field: SiteBuildMetadataFieldsEnum!): Float + sum(field: SiteBuildMetadataFieldsEnum!): Float + group(skip: Int, limit: Int, field: SiteBuildMetadataFieldsEnum!): [SiteBuildMetadataGroupConnection!]! +} + +type SiteBuildMetadataEdge { + next: SiteBuildMetadata + node: SiteBuildMetadata! + previous: SiteBuildMetadata +} + +enum SiteBuildMetadataFieldsEnum { + id + parent___id + parent___parent___id + parent___parent___parent___id + parent___parent___parent___children + parent___parent___children + parent___parent___children___id + parent___parent___children___children + parent___parent___internal___content + parent___parent___internal___contentDigest + parent___parent___internal___description + parent___parent___internal___fieldOwners + parent___parent___internal___ignoreType + parent___parent___internal___mediaType + parent___parent___internal___owner + parent___parent___internal___type + parent___children + parent___children___id + parent___children___parent___id + parent___children___parent___children + parent___children___children + parent___children___children___id + parent___children___children___children + parent___children___internal___content + parent___children___internal___contentDigest + parent___children___internal___description + parent___children___internal___fieldOwners + parent___children___internal___ignoreType + parent___children___internal___mediaType + parent___children___internal___owner + parent___children___internal___type + parent___internal___content + parent___internal___contentDigest + parent___internal___description + parent___internal___fieldOwners + parent___internal___ignoreType + parent___internal___mediaType + parent___internal___owner + parent___internal___type + children + children___id + children___parent___id + children___parent___parent___id + children___parent___parent___children + children___parent___children + children___parent___children___id + children___parent___children___children + children___parent___internal___content + children___parent___internal___contentDigest + children___parent___internal___description + children___parent___internal___fieldOwners + children___parent___internal___ignoreType + children___parent___internal___mediaType + children___parent___internal___owner + children___parent___internal___type + children___children + children___children___id + children___children___parent___id + children___children___parent___children + children___children___children + children___children___children___id + children___children___children___children + children___children___internal___content + children___children___internal___contentDigest + children___children___internal___description + children___children___internal___fieldOwners + children___children___internal___ignoreType + children___children___internal___mediaType + children___children___internal___owner + children___children___internal___type + children___internal___content + children___internal___contentDigest + children___internal___description + children___internal___fieldOwners + children___internal___ignoreType + children___internal___mediaType + children___internal___owner + children___internal___type + internal___content + internal___contentDigest + internal___description + internal___fieldOwners + internal___ignoreType + internal___mediaType + internal___owner + internal___type + buildTime +} + +type SiteBuildMetadataGroupConnection { + totalCount: Int! + edges: [SiteBuildMetadataEdge!]! + nodes: [SiteBuildMetadata!]! + pageInfo: PageInfo! + field: String! + fieldValue: String +} + +input SiteBuildMetadataFilterInput { + id: StringQueryOperatorInput + parent: NodeFilterInput + children: NodeFilterListInput + internal: InternalFilterInput + buildTime: DateQueryOperatorInput +} + +input SiteBuildMetadataSortInput { + fields: [SiteBuildMetadataFieldsEnum] + order: [SortOrderEnum] = [ASC] +} diff --git a/src/components/button/Button.js b/src/components/button/Button.js index bdc37df..44fe661 100644 --- a/src/components/button/Button.js +++ b/src/components/button/Button.js @@ -42,6 +42,11 @@ export const Button = styled.button.attrs(({ children, circle }) => ({ box-shadow: none; } `} + + ${(props) => props.disabled && css` + cursor: not-allowed; + opacity: 0.5; + `} ${gaps} `; diff --git a/src/components/input/SearchInput.js b/src/components/input/SearchInput.js index 6faefc5..5e97bf7 100644 --- a/src/components/input/SearchInput.js +++ b/src/components/input/SearchInput.js @@ -1,9 +1,9 @@ import styled from "styled-components"; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faSearch, faSpinner } from "@fortawesome/free-solid-svg-icons"; +import { faSearch, faTimes } from "@fortawesome/free-solid-svg-icons"; import { gapsRow } from "styles/mixins"; import theme from "theme"; import { Icon } from "components/icon"; +import { Button } from "components/button"; const StyledSearchInput = styled.div` display: flex; @@ -28,8 +28,16 @@ const StyledForm = styled.form` const StyledInput = styled.input` width: 100%; `; +const StyledResetButton = styled(Button)` + padding: 0; + + &:hover { + background-color: transparent; + box-shadow: none; + } +`; -export function SearchInput({ query, setQuery, isSearching, onSubmit, inputProps = {}, ...props }) { +export function SearchInput({ query, setQuery, onSubmit, inputProps = {}, ...props }) { return ( @@ -47,8 +55,10 @@ export function SearchInput({ query, setQuery, isSearching, onSubmit, inputProps {...inputProps} /> - {isSearching && ( - + {!!query && ( + + setQuery && setQuery("")}/> + )} ); diff --git a/src/components/listbox/Listbox.js b/src/components/listbox/Listbox.js index 3c55af9..6a85420 100644 --- a/src/components/listbox/Listbox.js +++ b/src/components/listbox/Listbox.js @@ -3,11 +3,13 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCheck, faSort, faTimes } from "@fortawesome/free-solid-svg-icons"; import { Button } from "components/button"; import { Text } from "components/text"; -import { useCallback, useRef, useState } from "react"; -import { Collapse } from "components/utils"; +import { useEffect, useRef, useState } from "react"; import theme from "theme"; +import { Box } from "components/box"; +import { AnimatePresence, motion } from "framer-motion"; +import useResizeObserver from "@react-hook/resize-observer"; -const StyledListbox = styled.div` +const StyledListbox = styled(Box)` display: inline-block; `; const StyledListboxButton = styled(Button)` @@ -17,7 +19,7 @@ const StyledListboxButton = styled(Button)` width: 100%; `; -const StyledListboxPopover = styled.div` +const StyledListboxPopover = styled(motion.div)` position: absolute; margin-top: 0.5rem; @@ -26,10 +28,15 @@ const StyledListboxPopover = styled.div` border-radius: 1rem; overflow: hidden; + will-change: transform, opacity; + background-color: ${theme.colors["solid"]}; + box-shadow: ${theme.shadows.high}; + + transition: none; `; const StyledListboxList = styled.ul` - max-height: 10rem; + max-height: 33vh; margin: 0; padding: 0; list-style: none; @@ -59,58 +66,80 @@ const StyledListboxOption = styled.li` `} `; -export function Listbox({ options, defaultValue, nullLabel }) { - const [selectedValue, setSelectedValue] = useState(defaultValue); +export function Listbox({ options, nullLabel, selectedValue, onSelect, noReset, disabled, defaultValue, ...props }) { const [showPopover, setShowPopover] = useState(false); const [buttonWidth, setButtonWidth] = useState(0); - const buttonRef = useCallback((buttonNode) => { - if (buttonNode !== null) { - setButtonWidth(buttonNode.getBoundingClientRect().width); - } - }, []); + const buttonRef = useRef(null); const listRef = useRef(null); + useResizeObserver(buttonRef, (entry) => setButtonWidth(entry.target.getBoundingClientRect().width)); + + useEffect(() => { + if (showPopover) { + listRef.current.focus(); + } + }, [ showPopover ]); + function handleButtonClick() { - setShowPopover(true); - listRef.current.focus(); + if (!disabled) { + setShowPopover(true); + } } function handleOptionClick(value) { - setSelectedValue(value); - setShowPopover(false); + if (!disabled) { + onSelect(value); + setShowPopover(false); + } } function handleResetClick(event) { event.stopPropagation(); - setSelectedValue(null); - setShowPopover(false); + if (!disabled) { + onSelect(null); + setShowPopover(false); + } } return ( - - event.preventDefault()}> - {selectedValue !== null ? options[selectedValue] : nullLabel} - {selectedValue !== null ? ( + + event.preventDefault()} + disabled={disabled} + > + {selectedValue !== null ? selectedValue : nullLabel} + {(selectedValue !== null && !noReset) ? ( ) : ( )} - - - setShowPopover(false)}> - {Object.entries(options).map(([value, label]) => ( - handleOptionClick(value)}> - {label} - {value === selectedValue && ( - - )} - - ))} - - - + + {showPopover && ( + + setShowPopover(false)}> + {options.map((value) => ( + handleOptionClick(value)}> + {value} + {value === selectedValue && ( + + )} + + ))} + + + )} + ); } diff --git a/src/components/search-filter/FilterGroup.js b/src/components/search-filter/FilterGroup.js new file mode 100644 index 0000000..f916f74 --- /dev/null +++ b/src/components/search-filter/FilterGroup.js @@ -0,0 +1,9 @@ +import { Grid } from "components/box"; + +export function FilterGroup({ children }) { + return ( + + {children} + + ); +} diff --git a/src/components/search-filter/SeasonFilter.js b/src/components/search-filter/SeasonFilter.js new file mode 100644 index 0000000..8b98d41 --- /dev/null +++ b/src/components/search-filter/SeasonFilter.js @@ -0,0 +1,22 @@ +import { Text } from "components/text"; +import { Listbox } from "components/listbox"; +import { Flex } from "components/box"; + +export function SeasonFilter({ value, setValue }) { + return ( + + Season + + + ); +} diff --git a/src/components/search-filter/SortBy.js b/src/components/search-filter/SortBy.js new file mode 100644 index 0000000..ffd9b7e --- /dev/null +++ b/src/components/search-filter/SortBy.js @@ -0,0 +1,18 @@ +import { Text } from "components/text"; +import { Listbox } from "components/listbox"; +import { Flex } from "components/box"; + +export function SortBy({ options, value, setValue }) { + return ( + + Sort by + + + ); +} diff --git a/src/components/search-filter/YearFilter.js b/src/components/search-filter/YearFilter.js new file mode 100644 index 0000000..0e1b01e --- /dev/null +++ b/src/components/search-filter/YearFilter.js @@ -0,0 +1,31 @@ +import { Text } from "components/text"; +import { Listbox } from "components/listbox"; +import { Flex } from "components/box"; +import { graphql, useStaticQuery } from "gatsby"; + +export function YearFilter({ value, setValue }) { + const yearList = useStaticQuery(graphql` + query { + allAnime { + groupedByYear: group(field: year) { + year: fieldValue + } + } + } + `).allAnime.groupedByYear + .map((node) => node.year) + .sort() + .reverse(); + + return ( + + Year + + + ); +} diff --git a/src/components/search-filter/index.js b/src/components/search-filter/index.js new file mode 100644 index 0000000..c2d26bd --- /dev/null +++ b/src/components/search-filter/index.js @@ -0,0 +1,4 @@ +export { FilterGroup } from "./FilterGroup"; +export { SeasonFilter } from "./SeasonFilter"; +export { YearFilter } from "./YearFilter"; +export { SortBy } from "./SortBy"; diff --git a/src/components/search/EntitySearch.js b/src/components/search/EntitySearch.js index 066ae32..8cb3cd2 100644 --- a/src/components/search/EntitySearch.js +++ b/src/components/search/EntitySearch.js @@ -6,10 +6,35 @@ import { Icon } from "components/icon"; import { SearchResultList } from "components/search"; import { useInfiniteQuery, useQueryClient } from "react-query"; import { fetchEntitySearchResults } from "lib/search"; +import { FilterGroup, SeasonFilter, SortBy, YearFilter } from "components/search-filter"; +import { useState } from "react"; + +const sortByFields = new Map([ + [ "Relevance", null ], + [ "A ➜ Z", "name" ], + [ "Z ➜ A", "-name" ], + [ "Old ➜ New", "year,season,name" ], + [ "New ➜ Old", "-year,-season,name" ], + [ "Last Added", "-created_at" ] +]); +const sortByOptions = [ ...sortByFields.keys() ]; export function EntitySearch({ searchQuery, searchEntity }) { + const [ filterSeason, setFilterSeason ] = useState(null); + const [ filterYear, setFilterYear ] = useState(null); + const [ sortBy, setSortBy ] = useState(sortByOptions[0]); + const fetchEntityPage = ({ pageParam = 1 }) => - fetchEntitySearchResults(searchQuery, 15, pageParam, searchEntity); + fetchEntitySearchResults({ + query: searchQuery, + entity: searchEntity, + page: pageParam, + filters: { + season: filterSeason, + year: filterYear + }, + sortBy: sortByFields.get(sortBy) + }); const queryClient = useQueryClient(); @@ -21,7 +46,14 @@ export function EntitySearch({ searchQuery, searchEntity }) { isLoading, isPlaceholderData } = useInfiniteQuery( - [ "searchEntity", searchQuery, searchEntity ], + [ + "searchEntity", + searchQuery, + searchEntity, + filterSeason, + filterYear, + sortBy + ], fetchEntityPage, { getNextPageParam: (lastPage) => lastPage.hasNextPage, @@ -42,34 +74,51 @@ export function EntitySearch({ searchQuery, searchEntity }) { } ); - if (isLoading) { - return ( - Searching... - ); - } - - const results = data.pages.flatMap((page) => page.data); - - if (!results.length) { - return ( - No results found for query "{searchQuery}". Did you spell it correctly? - ); - } - - const isLoadingMore = isFetchingNextPage || isPlaceholderData; - return ( - - - - {(hasNextPage || isPlaceholderData) && ( - - - - )} + + + + + + {(() => { + if (isLoading) { + return ( + Searching... + ); + } + + const results = data.pages.flatMap((page) => page.data); + + if (!results.length) { + if (searchQuery) { + return ( + No results found for query "{searchQuery}". Did you spell it correctly? + ); + } else { + return ( + No results found for your current filter settings. + ); + } + } + + const isLoadingMore = isFetchingNextPage || isPlaceholderData; + + return ( + <> + + + + {(hasNextPage || isPlaceholderData) && ( + + + + )} + + ); + })()} ); } diff --git a/src/components/search/GlobalSearch.js b/src/components/search/GlobalSearch.js index 13ad6a5..ca32efa 100644 --- a/src/components/search/GlobalSearch.js +++ b/src/components/search/GlobalSearch.js @@ -74,7 +74,7 @@ function GlobalSearchSection({ entity, title, results }) { {hasMoreResults && ( - + diff --git a/src/lib/search.js b/src/lib/search.js index d63989c..9a15199 100644 --- a/src/lib/search.js +++ b/src/lib/search.js @@ -106,10 +106,25 @@ export async function fetchGlobalSearchResults(query, limit, entities) { return Object.fromEntries(entities.map((entity) => [ entity, json.search[entityConfigs[entity].plural || entity] ])); } -export async function fetchEntitySearchResults(query, limit, page, entity) { - const parameters = generateEntitySearchParameters(entity); +export async function fetchEntitySearchResults({ + query, + entity, + page = 1, + limit = 15, + filters = {}, + sortBy = null +}) { + const parameters = [ + ...generateEntitySearchParameters(entity), + ...generateFilterAndSortParameters(filters, sortBy) + ]; - const res = await fetch(`${baseUrl}/api/${entity}?${parameters.join("&")}&page[size]=${limit}&page[number]=${page}&q=${encodeURIComponent(query)}`); + let url = `${baseUrl}/api/${entity}?${parameters.join("&")}&page[size]=${limit}&page[number]=${page}`; + if (query) { + url += `&q=${encodeURIComponent(query)}`; + } + + const res = await fetch(url); const json = await res.json(); const results = json[entityConfigs[entity].plural || entity]; @@ -156,6 +171,22 @@ function generateEntitySearchParameters(entity) { return parameters; } +function generateFilterAndSortParameters(filters, sortBy) { + const parameters = []; + + for (const [ key, value ] of Object.entries(filters)) { + if (value) { + parameters.push(`filter[${key}]=${value}`); + } + } + + if (sortBy) { + parameters.push(`sort=${sortBy}`); + } + + return parameters; +} + // Map artists and songs to performances to comply with the application schema function applyThemeSchema(themes) { for (const theme of themes) { diff --git a/src/pages/design.js b/src/pages/design.js index d7ff3df..1fcd120 100644 --- a/src/pages/design.js +++ b/src/pages/design.js @@ -53,6 +53,7 @@ export default function DesignPage() { const colors = Object.keys(theme.colors); const [selectedItem, setSelectedItem] = useState("anime"); + const [season, setSeason] = useState(null); const [, entitySwitcher] = useSwitcher([ "anime", "themes", "artists" ], "anime"); const [maxLines, toggleMaxLines] = useToggle(1, 0); @@ -472,21 +473,37 @@ export default function DesignPage() {
                     
                         {codeBlock`
-                            
+                            // At the top of the component
+                            const [season, setSeason] = useState(null);
+                            
+                            // Inside the render output
+                            
                         `}
                     
                 
- + Utils diff --git a/src/templates/search.js b/src/templates/search.js index a97c0b6..cc30697 100644 --- a/src/templates/search.js +++ b/src/templates/search.js @@ -8,7 +8,7 @@ import { gapsColumn, gapsRow } from "styles/mixins"; import { Box, Flex } from "components/box"; import { Switcher } from "components/switcher"; import { SEO } from "components/seo"; -import { faTimes } from "@fortawesome/free-solid-svg-icons"; +import { faCompass, faSearch, faTimes } from "@fortawesome/free-solid-svg-icons"; import { Text } from "components/text"; import { Icon } from "components/icon"; @@ -24,7 +24,7 @@ const StyledSearchOptions = styled(Flex)` } `; -export default function SearchPage({ pageContext: { entity }, location: { search, hash } }) { +export default function SearchPage({ pageContext: { entity }, location: { search, hash, state } }) { const urlParams = useMemo(() => new URLSearchParams(search), [ search ]); const urlSuffix = search + hash; @@ -64,9 +64,8 @@ export default function SearchPage({ pageContext: { entity }, location: { search @@ -77,14 +76,14 @@ export default function SearchPage({ pageContext: { entity }, location: { search > {({ Button, item, selected, content }) => item.value === null ? ( !!entity ? ( - + ) : null ) : ( - + @@ -92,42 +91,28 @@ export default function SearchPage({ pageContext: { entity }, location: { search )} - {/**/} - {/* */} - {/* */} - {/* Season*/} - {/* */} - {/* */} - {/* */} - {/* Year*/} - {/* {*/} - {/* options[year] = year;*/} - {/* return options;*/} - {/* }, {})*/} - {/* }/>*/} - {/* */} - {/* */} - {/**/} - {} ); } function Search({ searchQuery, searchEntity }) { - if (searchQuery) { - if (searchEntity) { - return ; - } else { - return ; - } + if (searchEntity) { + return ; + } else if (searchQuery) { + return ; } else { - return Type in a query to begin searching.; + return ( + + + + Looking for something specific? Use the search bar on the left! + + + + Feeling adventurous? Explore the database by choosing a category on the right! + + + ); } } diff --git a/src/theme/index.js b/src/theme/index.js index b93d50d..3a9d512 100644 --- a/src/theme/index.js +++ b/src/theme/index.js @@ -5,7 +5,8 @@ const theme = { "721px" ], shadows: { - low: "0 3px 6px rgb(0 0 0 / .15), 0 2px 4px rgb(0 0 0 / .12)" + low: "0 3px 6px rgb(0 0 0 / .15), 0 2px 4px rgb(0 0 0 / .12)", + high: "0 3px 3px 5px rgb(0 0 0 / .15), 0 2px 9px 5px rgb(0 0 0 / .12)" }, colors: createThemeDefinition() };