mirror of
https://github.com/kremalicious/blog.git
synced 2025-02-14 21:10:25 +01:00
more typings
This commit is contained in:
parent
74af0c2dc9
commit
9197962a77
@ -6,7 +6,9 @@
|
|||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"env": { "browser": true, "node": true, "es6": true, "jest": true },
|
"env": { "browser": true, "node": true, "es6": true, "jest": true },
|
||||||
"settings": { "react": { "version": "detect" } },
|
"settings": {
|
||||||
|
"react": { "version": "detect" }
|
||||||
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["**/*.ts", "**/*.tsx"],
|
"files": ["**/*.ts", "**/*.tsx"],
|
||||||
|
25
src/@types/GitHub.d.ts
vendored
Normal file
25
src/@types/GitHub.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
export interface GitHubRepo {
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
owner: {
|
||||||
|
login: string
|
||||||
|
}
|
||||||
|
object: {
|
||||||
|
id: string
|
||||||
|
text: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GitHub {
|
||||||
|
github: {
|
||||||
|
viewer: {
|
||||||
|
repositories: {
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: GitHubRepo
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
src/@types/PostMetadata.d.ts
vendored
Normal file
53
src/@types/PostMetadata.d.ts
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { FluidObject } from 'gatsby-image'
|
||||||
|
|
||||||
|
export interface PostMetadataFields {
|
||||||
|
slug: string
|
||||||
|
date: string
|
||||||
|
githubLink: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PostMetadataImageExif {
|
||||||
|
iso: string
|
||||||
|
model: string
|
||||||
|
fstop: string
|
||||||
|
shutterspeed: string
|
||||||
|
focalLength: string
|
||||||
|
lensModel: string
|
||||||
|
exposure: string
|
||||||
|
gps: {
|
||||||
|
latitude: string
|
||||||
|
longitude: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PostMetadataImage {
|
||||||
|
childImageSharp: { fluid: FluidObject }
|
||||||
|
fields: {
|
||||||
|
exif: PostMetadataImageExif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PostMetadataFrontmatter {
|
||||||
|
type?: string
|
||||||
|
title: string
|
||||||
|
description?: string
|
||||||
|
image?: PostMetadataImage
|
||||||
|
author?: string
|
||||||
|
updated?: string
|
||||||
|
tags?: string[]
|
||||||
|
linkurl?: string
|
||||||
|
style?: {
|
||||||
|
publicURL?: string
|
||||||
|
}
|
||||||
|
changelog?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PostMetadata {
|
||||||
|
id?: string
|
||||||
|
html?: string
|
||||||
|
excerpt?: string
|
||||||
|
frontmatter: PostMetadataFrontmatter
|
||||||
|
fields?: PostMetadataFields
|
||||||
|
rawMarkdownBody?: string
|
||||||
|
fileAbsolutePath?: string
|
||||||
|
}
|
29
src/@types/SiteMetadata.d.ts
vendored
Normal file
29
src/@types/SiteMetadata.d.ts
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
export interface MenuItem {
|
||||||
|
title: string
|
||||||
|
link: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Author {
|
||||||
|
name: string
|
||||||
|
email: string
|
||||||
|
uri: string
|
||||||
|
twitter: string
|
||||||
|
github: string
|
||||||
|
facebook: string
|
||||||
|
bitcoin: string
|
||||||
|
ether: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SiteMetadata {
|
||||||
|
siteTitle: string
|
||||||
|
siteTitleShort: string
|
||||||
|
siteDescription: string
|
||||||
|
siteUrl: string
|
||||||
|
author: Author
|
||||||
|
typekitID: string
|
||||||
|
menu: MenuItem[]
|
||||||
|
rss: string
|
||||||
|
jsonfeed: string
|
||||||
|
itemsPerPage: number
|
||||||
|
repoContentPath: string
|
||||||
|
}
|
11
src/@types/global.d.ts
vendored
11
src/@types/global.d.ts
vendored
@ -16,3 +16,14 @@ declare module '*.svg' {
|
|||||||
const src: string
|
const src: string
|
||||||
export default src
|
export default src
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Window {
|
||||||
|
__LUNR__: {
|
||||||
|
readonly [language: string]: {
|
||||||
|
readonly index: lunr.Index
|
||||||
|
readonly store: {
|
||||||
|
readonly [key: string]: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Changelog from '../atoms/Changelog'
|
import Changelog from '../atoms/Changelog'
|
||||||
|
import { PostMetadata } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
// Remove lead paragraph from content
|
// Remove lead paragraph from content
|
||||||
const PostContent = ({ post }: { post: any }) => {
|
const PostContent = ({ post }: { post: PostMetadata }) => {
|
||||||
const separator = '<!-- more -->'
|
const separator = '<!-- more -->'
|
||||||
const changelog = post.frontmatter.changelog
|
const changelog = post.frontmatter.changelog
|
||||||
|
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styles from './PostLead.module.scss'
|
import styles from './PostLead.module.scss'
|
||||||
|
import { PostMetadata } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
// Extract lead paragraph from content
|
// Extract lead paragraph from content
|
||||||
// Grab everything before more tag, or just first paragraph
|
// Grab everything before more tag, or just first paragraph
|
||||||
const PostLead = ({
|
const PostLead = ({ post, index }: { post: PostMetadata; index?: boolean }) => {
|
||||||
post,
|
|
||||||
index
|
|
||||||
}: {
|
|
||||||
post: { html: string }
|
|
||||||
index?: boolean
|
|
||||||
}) => {
|
|
||||||
let lead
|
let lead
|
||||||
const content = post.html
|
const content = post.html
|
||||||
const separator = '<!-- more -->'
|
const separator = '<!-- more -->'
|
||||||
|
@ -4,8 +4,9 @@ import slugify from 'slugify'
|
|||||||
import Time from '../atoms/Time'
|
import Time from '../atoms/Time'
|
||||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||||
import styles from './PostMeta.module.scss'
|
import styles from './PostMeta.module.scss'
|
||||||
|
import { PostMetadata } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
export default function PostMeta({ post }: { post: any }) {
|
export default function PostMeta({ post }: { post: PostMetadata }) {
|
||||||
const siteMeta = useSiteMetadata()
|
const siteMeta = useSiteMetadata()
|
||||||
const { author, updated, tags, type } = post.frontmatter
|
const { author, updated, tags, type } = post.frontmatter
|
||||||
const { date } = post.fields
|
const { date } = post.fields
|
||||||
|
@ -2,12 +2,13 @@ import React from 'react'
|
|||||||
import { Link } from 'gatsby'
|
import { Link } from 'gatsby'
|
||||||
import Image from '../atoms/Image'
|
import Image from '../atoms/Image'
|
||||||
import styles from './PostTeaser.module.scss'
|
import styles from './PostTeaser.module.scss'
|
||||||
|
import { PostMetadata } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
export default function PostTeaser({
|
export default function PostTeaser({
|
||||||
post,
|
post,
|
||||||
toggleSearch
|
toggleSearch
|
||||||
}: {
|
}: {
|
||||||
post: { fields: { slug: string }; frontmatter: { image: any; title: string } }
|
post: PostMetadata
|
||||||
toggleSearch?: () => void
|
toggleSearch?: () => void
|
||||||
}) {
|
}) {
|
||||||
const { image, title } = post.frontmatter
|
const { image, title } = post.frontmatter
|
||||||
|
@ -5,7 +5,11 @@ import Container from '../atoms/Container'
|
|||||||
import PostTeaser from '../Post/PostTeaser'
|
import PostTeaser from '../Post/PostTeaser'
|
||||||
import SearchResultsEmpty from './SearchResultsEmpty'
|
import SearchResultsEmpty from './SearchResultsEmpty'
|
||||||
import styles from './SearchResults.module.scss'
|
import styles from './SearchResults.module.scss'
|
||||||
import { GatsbyImageProps } from 'gatsby-image'
|
import { PostMetadata } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
|
export interface Results {
|
||||||
|
slug: string
|
||||||
|
}
|
||||||
|
|
||||||
const query = graphql`
|
const query = graphql`
|
||||||
query {
|
query {
|
||||||
@ -30,48 +34,32 @@ const query = graphql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
interface Page {
|
function SearchResultsPure({
|
||||||
slug: string
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PostNode {
|
|
||||||
node: {
|
|
||||||
id: string
|
|
||||||
fields: { slug: string }
|
|
||||||
frontmatter: {
|
|
||||||
title: string
|
|
||||||
type: string
|
|
||||||
image: { childImageSharp: GatsbyImageProps }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function SearchResults({
|
|
||||||
searchQuery,
|
searchQuery,
|
||||||
results,
|
results,
|
||||||
toggleSearch
|
toggleSearch,
|
||||||
|
posts
|
||||||
}: {
|
}: {
|
||||||
|
posts: [{ node: PostMetadata }]
|
||||||
searchQuery: string
|
searchQuery: string
|
||||||
results: any
|
results: Results[]
|
||||||
toggleSearch(): void
|
toggleSearch(): void
|
||||||
}) {
|
}) {
|
||||||
const data = useStaticQuery(query)
|
return (
|
||||||
const posts = data.allMarkdownRemark.edges
|
|
||||||
|
|
||||||
// creating portal to break out of DOM node we're in
|
|
||||||
// and render the results in content container
|
|
||||||
return ReactDOM.createPortal(
|
|
||||||
<div className={styles.searchResults}>
|
<div className={styles.searchResults}>
|
||||||
<Container>
|
<Container>
|
||||||
{results.length > 0 ? (
|
{results.length > 0 ? (
|
||||||
<ul>
|
<ul>
|
||||||
{results.map((page: Page) =>
|
{results.map((page: { slug: string }) =>
|
||||||
posts
|
posts
|
||||||
.filter((post: PostNode) => post.node.fields.slug === page.slug)
|
.filter(
|
||||||
.map((post: PostNode) => (
|
({ node }: { node: PostMetadata }) =>
|
||||||
|
node.fields.slug === page.slug
|
||||||
|
)
|
||||||
|
.map(({ node }: { node: PostMetadata }) => (
|
||||||
<PostTeaser
|
<PostTeaser
|
||||||
key={page.slug}
|
key={page.slug}
|
||||||
post={post.node}
|
post={node}
|
||||||
toggleSearch={toggleSearch}
|
toggleSearch={toggleSearch}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
@ -81,7 +69,31 @@ export default function SearchResults({
|
|||||||
<SearchResultsEmpty searchQuery={searchQuery} results={results} />
|
<SearchResultsEmpty searchQuery={searchQuery} results={results} />
|
||||||
)}
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
</div>,
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SearchResults({
|
||||||
|
searchQuery,
|
||||||
|
results,
|
||||||
|
toggleSearch
|
||||||
|
}: {
|
||||||
|
searchQuery: string
|
||||||
|
results: Results[]
|
||||||
|
toggleSearch(): void
|
||||||
|
}) {
|
||||||
|
const data = useStaticQuery(query)
|
||||||
|
const posts = data.allMarkdownRemark.edges
|
||||||
|
|
||||||
|
// creating portal to break out of DOM node we're in
|
||||||
|
// and render the results in content container
|
||||||
|
return ReactDOM.createPortal(
|
||||||
|
<SearchResultsPure
|
||||||
|
posts={posts}
|
||||||
|
results={results}
|
||||||
|
searchQuery={searchQuery}
|
||||||
|
toggleSearch={toggleSearch}
|
||||||
|
/>,
|
||||||
document.getElementById('document')
|
document.getElementById('document')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import styles from './SearchResultsEmpty.module.scss'
|
import styles from './SearchResultsEmpty.module.scss'
|
||||||
|
import { Results } from './SearchResults'
|
||||||
|
|
||||||
const SearchResultsEmpty = ({
|
const SearchResultsEmpty = ({
|
||||||
searchQuery,
|
searchQuery,
|
||||||
results
|
results
|
||||||
}: {
|
}: {
|
||||||
searchQuery: string
|
searchQuery: string
|
||||||
results: []
|
results: Results[]
|
||||||
}) => (
|
}) => (
|
||||||
<div className={styles.empty}>
|
<div className={styles.empty}>
|
||||||
<header className={styles.emptyMessage}>
|
<header className={styles.emptyMessage}>
|
||||||
|
@ -1,26 +1,12 @@
|
|||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { CSSTransition } from 'react-transition-group'
|
import { CSSTransition } from 'react-transition-group'
|
||||||
import lunr from 'lunr'
|
|
||||||
import SearchInput from './SearchInput'
|
import SearchInput from './SearchInput'
|
||||||
import SearchButton from './SearchButton'
|
import SearchButton from './SearchButton'
|
||||||
import SearchResults from './SearchResults'
|
import SearchResults from './SearchResults'
|
||||||
|
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
__LUNR__: {
|
|
||||||
readonly [language: string]: {
|
|
||||||
readonly index: lunr.Index
|
|
||||||
readonly store: {
|
|
||||||
readonly [key: string]: any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSearchResults(query: string, lng: string) {
|
function getSearchResults(query: string, lng: string) {
|
||||||
if (!query || !window.__LUNR__) return []
|
if (!query || !window.__LUNR__) return []
|
||||||
const lunrIndex = window.__LUNR__[lng]
|
const lunrIndex = window.__LUNR__[lng]
|
||||||
|
@ -21,7 +21,7 @@ export default function Alerts({
|
|||||||
message
|
message
|
||||||
}: {
|
}: {
|
||||||
transactionHash: string | null
|
transactionHash: string | null
|
||||||
message: { text?: MessageChannel; status?: string } | null
|
message: { text?: string; status?: string } | null
|
||||||
}) {
|
}) {
|
||||||
const constructMessage = () => {
|
const constructMessage = () => {
|
||||||
let messageOutput
|
let messageOutput
|
||||||
|
@ -2,28 +2,22 @@ import React from 'react'
|
|||||||
import testRender from '../../../jest/testRender'
|
import testRender from '../../../jest/testRender'
|
||||||
|
|
||||||
import { PureChangelog as Changelog } from './Changelog'
|
import { PureChangelog as Changelog } from './Changelog'
|
||||||
|
import { GitHubRepo } from '../../@types/GitHub'
|
||||||
|
|
||||||
const data = {
|
const repos: [{ node: GitHubRepo }] = [
|
||||||
github: {
|
{
|
||||||
viewer: {
|
node: {
|
||||||
repositories: {
|
name: 'gatsby-plugin-matomo',
|
||||||
edges: [
|
url: 'https://hello.com',
|
||||||
{
|
owner: { login: 'kremalicious' },
|
||||||
node: {
|
object: {
|
||||||
name: 'gatsby-plugin-matomo',
|
id: 'hello',
|
||||||
url: 'https://hello.com',
|
text: 'hello'
|
||||||
owner: { login: 'kremalicious' },
|
|
||||||
object: {
|
|
||||||
text: 'hello'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
|
|
||||||
describe('Changelog', () => {
|
describe('Changelog', () => {
|
||||||
testRender(<Changelog repo="gatsby-plugin-matomo" data={data} />)
|
testRender(<Changelog repo="gatsby-plugin-matomo" repos={repos} />)
|
||||||
})
|
})
|
||||||
|
@ -3,12 +3,17 @@ import { graphql, useStaticQuery } from 'gatsby'
|
|||||||
import remark from 'remark'
|
import remark from 'remark'
|
||||||
import remarkReact from 'remark-react'
|
import remarkReact from 'remark-react'
|
||||||
import styles from './Changelog.module.scss'
|
import styles from './Changelog.module.scss'
|
||||||
|
import { GitHub, GitHubRepo } from '../../@types/GitHub'
|
||||||
|
|
||||||
export function PureChangelog({ repo, data }: { repo: string; data: any }) {
|
export function PureChangelog({
|
||||||
const repositoriesGitHub = data.github.viewer.repositories.edges
|
repo,
|
||||||
|
repos
|
||||||
const repoFilteredArray = repositoriesGitHub
|
}: {
|
||||||
.map(({ node }: { node: any }) => {
|
repo: string
|
||||||
|
repos: [{ node: GitHubRepo }]
|
||||||
|
}) {
|
||||||
|
const repoFilteredArray = repos
|
||||||
|
.map(({ node }: { node: GitHubRepo }) => {
|
||||||
if (node.name === repo) return node
|
if (node.name === repo) return node
|
||||||
})
|
})
|
||||||
.filter((n: any) => n)
|
.filter((n: any) => n)
|
||||||
@ -73,6 +78,7 @@ export default function Changelog({ repo }: { repo: string }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
const data = useStaticQuery(queryGithub)
|
const data: GitHub = useStaticQuery(queryGithub)
|
||||||
return <PureChangelog repo={repo} data={data} />
|
const repos: [{ node: GitHubRepo }] = data.github.viewer.repositories.edges
|
||||||
|
return <PureChangelog repo={repo} repos={repos} />
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,9 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ExifMap from './ExifMap'
|
import ExifMap from './ExifMap'
|
||||||
import styles from './Exif.module.scss'
|
import styles from './Exif.module.scss'
|
||||||
|
import { PostMetadataImageExif } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
interface ExifProps {
|
export default function Exif({ exif }: { exif: PostMetadataImageExif }) {
|
||||||
iso: string
|
|
||||||
model: string
|
|
||||||
fstop: string
|
|
||||||
shutterspeed: string
|
|
||||||
focalLength: string
|
|
||||||
lensModel: string
|
|
||||||
exposure: string
|
|
||||||
gps: {
|
|
||||||
latitude: string
|
|
||||||
longitude: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Exif({ exif }: { exif: ExifProps }) {
|
|
||||||
const { iso, model, fstop, shutterspeed, focalLength, exposure, gps } = exif
|
const { iso, model, fstop, shutterspeed, focalLength, exposure, gps } = exif
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react'
|
|||||||
import { graphql, useStaticQuery } from 'gatsby'
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
import { Helmet } from 'react-helmet'
|
import { Helmet } from 'react-helmet'
|
||||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||||
|
import { PostMetadata } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
const query = graphql`
|
const query = graphql`
|
||||||
query {
|
query {
|
||||||
@ -116,7 +117,7 @@ export default function SEO({
|
|||||||
slug,
|
slug,
|
||||||
postSEO
|
postSEO
|
||||||
}: {
|
}: {
|
||||||
post?: any
|
post?: PostMetadata
|
||||||
slug?: string
|
slug?: string
|
||||||
postSEO?: boolean
|
postSEO?: boolean
|
||||||
}) {
|
}) {
|
||||||
|
@ -2,39 +2,16 @@ import React from 'react'
|
|||||||
import { Link, graphql, useStaticQuery } from 'gatsby'
|
import { Link, graphql, useStaticQuery } from 'gatsby'
|
||||||
import Image from '../atoms/Image'
|
import Image from '../atoms/Image'
|
||||||
import styles from './Featured.module.scss'
|
import styles from './Featured.module.scss'
|
||||||
|
import { PostMetadata } from '../../@types/PostMetadata'
|
||||||
|
|
||||||
const query = graphql`
|
function FeaturedPure({
|
||||||
query {
|
data
|
||||||
allMarkdownRemark(
|
}: {
|
||||||
filter: { frontmatter: { featured: { eq: true } } }
|
data: { allMarkdownRemark: { edges: [{ node: PostMetadata }] } }
|
||||||
sort: { fields: [fields___date], order: DESC }
|
}) {
|
||||||
) {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
id
|
|
||||||
frontmatter {
|
|
||||||
title
|
|
||||||
image {
|
|
||||||
childImageSharp {
|
|
||||||
...ImageFluidThumb
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fields {
|
|
||||||
slug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
export default function Featured() {
|
|
||||||
const data = useStaticQuery(query)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.featured}>
|
<div className={styles.featured}>
|
||||||
{data.allMarkdownRemark.edges.map(({ node }: { node: any }) => {
|
{data.allMarkdownRemark.edges.map(({ node }: { node: PostMetadata }) => {
|
||||||
const { title, image } = node.frontmatter
|
const { title, image } = node.frontmatter
|
||||||
const { slug } = node.fields
|
const { slug } = node.fields
|
||||||
|
|
||||||
@ -50,3 +27,34 @@ export default function Featured() {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function Featured() {
|
||||||
|
const query = graphql`
|
||||||
|
query {
|
||||||
|
allMarkdownRemark(
|
||||||
|
filter: { frontmatter: { featured: { eq: true } } }
|
||||||
|
sort: { fields: [fields___date], order: DESC }
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
frontmatter {
|
||||||
|
title
|
||||||
|
image {
|
||||||
|
childImageSharp {
|
||||||
|
...ImageFluidThumb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fields {
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const data = useStaticQuery(query)
|
||||||
|
return <FeaturedPure data={data} />
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { Link } from 'gatsby'
|
|||||||
import Hamburger from '../atoms/Hamburger'
|
import Hamburger from '../atoms/Hamburger'
|
||||||
import styles from './Menu.module.scss'
|
import styles from './Menu.module.scss'
|
||||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||||
|
import { MenuItem } from '../../@types/SiteMetadata'
|
||||||
|
|
||||||
export default function Menu() {
|
export default function Menu() {
|
||||||
const [menuOpen, setMenuOpen] = useState(false)
|
const [menuOpen, setMenuOpen] = useState(false)
|
||||||
@ -13,7 +14,7 @@ export default function Menu() {
|
|||||||
setMenuOpen(!menuOpen)
|
setMenuOpen(!menuOpen)
|
||||||
}
|
}
|
||||||
|
|
||||||
const MenuItems = menu.map((item: any) => (
|
const MenuItems = menu.map((item: MenuItem) => (
|
||||||
<li key={item.title}>
|
<li key={item.title}>
|
||||||
<Link onClick={toggleMenu} to={item.link}>
|
<Link onClick={toggleMenu} to={item.link}>
|
||||||
{item.title}
|
{item.title}
|
||||||
|
@ -2,6 +2,10 @@ import React, { useState } from 'react'
|
|||||||
import { graphql, useStaticQuery } from 'gatsby'
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
import PostTeaser from '../Post/PostTeaser'
|
import PostTeaser from '../Post/PostTeaser'
|
||||||
import styles from './RelatedPosts.module.scss'
|
import styles from './RelatedPosts.module.scss'
|
||||||
|
import {
|
||||||
|
PostMetadata,
|
||||||
|
PostMetadataFrontmatter
|
||||||
|
} from '../../@types/PostMetadata'
|
||||||
|
|
||||||
const query = graphql`
|
const query = graphql`
|
||||||
query {
|
query {
|
||||||
@ -31,22 +35,26 @@ const query = graphql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
function postsWithDataFilter(posts: [], key: string, valuesToFind: string[]) {
|
function postsWithDataFilter(
|
||||||
const newArray = posts.filter((post: any) => {
|
posts: [{ node: PostMetadata }],
|
||||||
const frontmatterKey = post.node.frontmatter[key]
|
key: keyof PostMetadataFrontmatter,
|
||||||
|
valuesToFind: string[]
|
||||||
|
) {
|
||||||
|
const newArray = posts.filter(({ node }: { node: PostMetadata }) => {
|
||||||
|
const frontmatterKey = node.frontmatter[key] as []
|
||||||
|
|
||||||
if (
|
if (
|
||||||
frontmatterKey !== null &&
|
frontmatterKey !== null &&
|
||||||
frontmatterKey.some((r: string) => valuesToFind.includes(r))
|
frontmatterKey.some((r: string) => valuesToFind.includes(r))
|
||||||
) {
|
) {
|
||||||
return post
|
return node
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return newArray
|
return newArray
|
||||||
}
|
}
|
||||||
|
|
||||||
function photosWithDataFilter(posts: []) {
|
function photosWithDataFilter(posts: []) {
|
||||||
const newArray = posts.filter((post: any) => {
|
const newArray = posts.filter((post: { node: PostMetadata }) => {
|
||||||
const { fileAbsolutePath } = post.node
|
const { fileAbsolutePath } = post.node
|
||||||
|
|
||||||
if (fileAbsolutePath.includes('content/photos')) {
|
if (fileAbsolutePath.includes('content/photos')) {
|
||||||
@ -85,7 +93,7 @@ export default function RelatedPosts({
|
|||||||
{filteredPosts
|
{filteredPosts
|
||||||
.sort(() => 0.5 - Math.random())
|
.sort(() => 0.5 - Math.random())
|
||||||
.slice(0, 6)
|
.slice(0, 6)
|
||||||
.map(({ node }: { node: any }) => (
|
.map(({ node }: { node: PostMetadata }) => (
|
||||||
<PostTeaser key={node.id} post={node} />
|
<PostTeaser key={node.id} post={node} />
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { useStaticQuery, graphql } from 'gatsby'
|
import { useStaticQuery, graphql } from 'gatsby'
|
||||||
|
import { SiteMetadata } from '../@types/SiteMetadata'
|
||||||
|
|
||||||
export const useSiteMetadata = () => {
|
export function useSiteMetadata(): SiteMetadata {
|
||||||
const query = graphql`
|
const query = graphql`
|
||||||
query {
|
query {
|
||||||
site {
|
site {
|
||||||
|
@ -3,6 +3,7 @@ import { graphql, Link } from 'gatsby'
|
|||||||
import PostImage from '../components/Post/PostImage'
|
import PostImage from '../components/Post/PostImage'
|
||||||
import Page from '../templates/Page'
|
import Page from '../templates/Page'
|
||||||
import styles from './goodies.module.scss'
|
import styles from './goodies.module.scss'
|
||||||
|
import { PostMetadata } from '../@types/PostMetadata'
|
||||||
|
|
||||||
const page = {
|
const page = {
|
||||||
frontmatter: {
|
frontmatter: {
|
||||||
@ -12,16 +13,7 @@ const page = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Post {
|
const GoodiesThumb = ({ post }: { post: PostMetadata }) => {
|
||||||
id: string
|
|
||||||
fields: { slug: string }
|
|
||||||
frontmatter: {
|
|
||||||
title: string
|
|
||||||
image: { childImageSharp: any }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const GoodiesThumb = ({ post }: { post: Post }) => {
|
|
||||||
const { title, image } = post.frontmatter
|
const { title, image } = post.frontmatter
|
||||||
const { slug } = post.fields
|
const { slug } = post.fields
|
||||||
|
|
||||||
@ -41,7 +33,7 @@ export default function Goodies({
|
|||||||
data,
|
data,
|
||||||
location
|
location
|
||||||
}: {
|
}: {
|
||||||
data: { goodies: { edges: [{ node: Post }] } }
|
data: { goodies: { edges: [{ node: PostMetadata }] } }
|
||||||
location: Location
|
location: Location
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
|
@ -3,6 +3,7 @@ import { graphql, Link } from 'gatsby'
|
|||||||
import Page from '../templates/Page'
|
import Page from '../templates/Page'
|
||||||
import PostImage from '../components/Post/PostImage'
|
import PostImage from '../components/Post/PostImage'
|
||||||
import styles from './photos.module.scss'
|
import styles from './photos.module.scss'
|
||||||
|
import { PostMetadata } from '../@types/PostMetadata'
|
||||||
|
|
||||||
const page = {
|
const page = {
|
||||||
frontmatter: {
|
frontmatter: {
|
||||||
@ -11,17 +12,7 @@ const page = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Photo {
|
const PhotoThumb = ({ photo }: { photo: PostMetadata }) => {
|
||||||
id: string
|
|
||||||
fields: { slug: string }
|
|
||||||
frontmatter: {
|
|
||||||
title: string
|
|
||||||
type: string
|
|
||||||
image: { childImageSharp: any }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const PhotoThumb = ({ photo }: { photo: Photo }) => {
|
|
||||||
const { title, image } = photo.frontmatter
|
const { title, image } = photo.frontmatter
|
||||||
const { slug } = photo.fields
|
const { slug } = photo.fields
|
||||||
const { fluid } = image.childImageSharp
|
const { fluid } = image.childImageSharp
|
||||||
@ -37,21 +28,11 @@ const PhotoThumb = ({ photo }: { photo: Photo }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PhotosData {
|
|
||||||
photos: {
|
|
||||||
edges: [
|
|
||||||
{
|
|
||||||
node: Photo
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Photos({
|
export default function Photos({
|
||||||
data,
|
data,
|
||||||
location
|
location
|
||||||
}: {
|
}: {
|
||||||
data: PhotosData
|
data: { photos: { edges: [{ node: PostMetadata }] } }
|
||||||
location: Location
|
location: Location
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
|
@ -3,6 +3,7 @@ import { Helmet } from 'react-helmet'
|
|||||||
import SEO from '../components/atoms/SEO'
|
import SEO from '../components/atoms/SEO'
|
||||||
import Layout from '../components/Layout'
|
import Layout from '../components/Layout'
|
||||||
import styles from './Page.module.scss'
|
import styles from './Page.module.scss'
|
||||||
|
import { PostMetadata } from '../@types/PostMetadata'
|
||||||
|
|
||||||
export default function Page({
|
export default function Page({
|
||||||
title,
|
title,
|
||||||
@ -14,8 +15,8 @@ export default function Page({
|
|||||||
title: string
|
title: string
|
||||||
children: any
|
children: any
|
||||||
section?: string
|
section?: string
|
||||||
location?: any
|
location?: Location
|
||||||
post?: any
|
post?: PostMetadata
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -13,15 +13,16 @@ import PostMeta from '../components/Post/PostMeta'
|
|||||||
import Exif from '../components/atoms/Exif'
|
import Exif from '../components/atoms/Exif'
|
||||||
import RelatedPosts from '../components/molecules/RelatedPosts'
|
import RelatedPosts from '../components/molecules/RelatedPosts'
|
||||||
import styles from './Post.module.scss'
|
import styles from './Post.module.scss'
|
||||||
|
import { PostMetadata } from '../@types/PostMetadata'
|
||||||
|
|
||||||
export default function Post({
|
export default function Post({
|
||||||
data,
|
data,
|
||||||
location
|
location
|
||||||
}: {
|
}: {
|
||||||
data: any
|
data: { post: PostMetadata }
|
||||||
location: Location
|
location: Location
|
||||||
}) {
|
}) {
|
||||||
const { markdownRemark: post } = data
|
const { post } = data
|
||||||
const { title, image, type, linkurl, style, tags } = post.frontmatter
|
const { title, image, type, linkurl, style, tags } = post.frontmatter
|
||||||
const { slug, githubLink } = post.fields
|
const { slug, githubLink } = post.fields
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ export default function Post({
|
|||||||
|
|
||||||
export const pageQuery = graphql`
|
export const pageQuery = graphql`
|
||||||
query BlogPostBySlug($slug: String!) {
|
query BlogPostBySlug($slug: String!) {
|
||||||
markdownRemark(fields: { slug: { eq: $slug } }) {
|
post: markdownRemark(fields: { slug: { eq: $slug } }) {
|
||||||
html
|
html
|
||||||
excerpt
|
excerpt
|
||||||
frontmatter {
|
frontmatter {
|
||||||
|
@ -12,13 +12,14 @@ import Pagination from '../components/molecules/Pagination'
|
|||||||
import Featured from '../components/molecules/Featured'
|
import Featured from '../components/molecules/Featured'
|
||||||
import styles from './Posts.module.scss'
|
import styles from './Posts.module.scss'
|
||||||
import stylesPost from './Post.module.scss'
|
import stylesPost from './Post.module.scss'
|
||||||
|
import { PostMetadata } from '../@types/PostMetadata'
|
||||||
|
|
||||||
export default function Posts({
|
export default function Posts({
|
||||||
data,
|
data,
|
||||||
location,
|
location,
|
||||||
pageContext
|
pageContext
|
||||||
}: {
|
}: {
|
||||||
data: any
|
data: { allMarkdownRemark: { edges: [{ node: PostMetadata }] } }
|
||||||
location: Location
|
location: Location
|
||||||
pageContext: {
|
pageContext: {
|
||||||
tag: string
|
tag: string
|
||||||
@ -30,7 +31,7 @@ export default function Posts({
|
|||||||
const edges = data.allMarkdownRemark.edges
|
const edges = data.allMarkdownRemark.edges
|
||||||
const { tag, currentPageNumber, numPages, nextPage } = pageContext
|
const { tag, currentPageNumber, numPages, nextPage } = pageContext
|
||||||
|
|
||||||
const PostsList = edges.map(({ node }: { node: any }) => {
|
const PostsList = edges.map(({ node }: { node: PostMetadata }) => {
|
||||||
const { type, linkurl, title, image } = node.frontmatter
|
const { type, linkurl, title, image } = node.frontmatter
|
||||||
const { slug } = node.fields
|
const { slug } = node.fields
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user