Skip to content

Instantly share code, notes, and snippets.

@KATT
Last active May 17, 2020 12:12
Show Gist options
  • Save KATT/2b324898b6e379ac2eec4aaf2a0fd71e to your computer and use it in GitHub Desktop.
Save KATT/2b324898b6e379ac2eec4aaf2a0fd71e to your computer and use it in GitHub Desktop.
VSCode for codegen
// gitignore this file
module.exports = {
HASURA_URL: 'https://myapp.herokuapp.com/v1/graphql',
HASURA_ADMIN_SECRET: 'xxx',
};
{
"recommendations": [
"dbaeumer.vscode-eslint",
"yzhang.markdown-all-in-one",
"apollographql.vscode-apollo"
]
}
{
"editor.formatOnSave": false,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact"
],
"typescript.tsdk": "node_modules/typescript/lib",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
const env = require('./.env.local');
module.exports = {
client: {
includes: ['./src/pages/**/*.{tsx,ts,js,graphql}'],
service: {
name: 'your-service-name',
url: env.HASURA_URL,
headers: {
'x-hasura-admin-secret': env.HASURA_ADMIN_SECRET,
},
},
},
};
const env = require('./.env.local');
module.exports = {
schema: [
{
[env.HASURA_URL]: {
headers: {
'x-hasura-admin-secret': env.HASURA_ADMIN_SECRET,
},
},
},
],
documents: ['./src/**/*.{tsx,ts,graphql,gql}'],
overwrite: true,
generates: {
'./src/__generated__/graphql.tsx': {
plugins: [
'typescript',
'typescript-operations',
'typescript-react-apollo',
{
add: '/* eslint-disable */',
},
],
config: {
skipTypename: false,
withHooks: true,
withHOC: false,
withComponent: false,
},
},
'./src/__generated__/graphql.schema.json': {
plugins: ['introspection'],
},
},
};
{
"private": true,
"scripts": {
"hasura": "cd hasura && hasura console",
"start": "TSC_COMPILE_ON_ERROR=true react-app-rewired start",
"build": "react-app-rewired build",
"test": "react-app-rewired test --env=jsdom",
"eject": "react-app-rewired eject",
"codegen": "graphql-codegen --config codegen.js" // run `yarn codegen --watch`
},
"dependencies": {
// ..
},
"devDependencies": {
"@graphql-codegen/add": "^1.13.2",
"@graphql-codegen/cli": "^1.13.2",
"@graphql-codegen/introspection": "^1.13.2",
"@graphql-codegen/typescript": "^1.13.2",
"@graphql-codegen/typescript-operations": "^1.13.2",
"@graphql-codegen/typescript-react-apollo": "^1.13.2",
// [...]
}
}
import {
Box,
Card,
CardActionArea,
CardContent,
Chip,
Container,
fade,
Grid,
Icon,
makeStyles,
Typography,
} from '@material-ui/core';
import Skeleton from '@material-ui/lab/Skeleton';
import { IconText } from 'components/IconText';
import { Nav } from 'components/Nav';
import { ResponsiveImage } from 'components/ResponsiveImage';
import gql from 'graphql-tag';
import React from 'react';
import { Link } from 'react-router-dom';
import { useAppContext } from 'App';
import {
usePublicPostsQuery,
usePrivatePostsQuery,
} from '__generated__/graphql';
import { ContextualErrorHandler } from 'components/ContextualErrorHandler';
export const publicPostsQuery = gql`
query publicPosts {
Post(where: { isPublic: { _eq: true } }, order_by: [{ updatedAt: desc }]) {
id
type
variety
userId
image
quantity
originCountry
organic
isPublic
}
}
`;
export const privatePostsQuery = gql`
query privatePosts {
Post(where: { isPublic: { _eq: false } }, order_by: [{ updatedAt: desc }]) {
id
type
variety
userId
image
quantity
originCountry
organic
isPublic
}
}
`;
const useStyles = makeStyles((theme) => ({
icon: {
marginRight: theme.spacing(2),
},
input: {
marginLeft: theme.spacing(1),
flex: 1,
},
iconButton: {
padding: 10,
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(1),
width: 'auto',
},
},
searchIcon: {
padding: theme.spacing(0, 2),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 0),
// vertical padding + font size from searchIcon
paddingLeft: `calc(1em + ${theme.spacing(4)}px)`,
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: '12ch',
'&:focus': {
width: '20ch',
},
},
},
cardGrid: {
paddingTop: theme.spacing(8),
paddingBottom: theme.spacing(8),
},
card: {
height: '100%',
display: 'flex',
flexDirection: 'column',
},
cardMedia: {
paddingTop: '56.25%', // 16:9
},
cardContent: {
flexGrow: 1,
},
chipWrapper: {
position: 'absolute',
width: '100%',
bottom: '0',
left: '0',
background: 'rgba(0,0,0, 0)',
padding: theme.spacing(2),
pointerEvents: 'none',
textAlign: 'right',
transform: 'translateY(50%)',
},
}));
export function IndexPage() {
let { error, data, loading } = usePublicPostsQuery();
const classes = useStyles();
let publicPosts = data?.Post;
const { isAdmin } = useAppContext();
let { data: privateData } = usePrivatePostsQuery({
skip: !isAdmin,
});
let privatePosts: any[] | undefined =
privateData?.Post ?? Array.from(new Array(3));
return (
<>
<Nav />
<Container>
<Box mt={4}>
<Typography variant="h2" component="h1" gutterBottom>
Welcome to TradeBay
</Typography>
</Box>
<Typography variant="body1" component="p" gutterBottom>
Use TradeBay to find the best prices for fresh fruit
</Typography>
</Container>
<Container className={classes.cardGrid} maxWidth="md">
{/* End hero unit */}
<Grid container spacing={4}>
<ContextualErrorHandler error={error} />
{!error &&
publicPosts?.map((post, index) => (
<Grid item key={post.id ?? index} xs={12} sm={6} md={4}>
<Card className={classes.card}>
<CardActionArea
component={Link}
to={`/posts/${post.id}`}
style={{ display: 'block' }}
>
<ResponsiveImage src={post.image}>
{post.organic && (
<div className={classes.chipWrapper}>
{post.organic && (
<Chip
// variant="filled"
color="primary"
size="small"
label="Organic"
icon={<Icon style={{ fontSize: 14 }}>eco</Icon>}
/>
)}
</div>
)}
</ResponsiveImage>
<CardContent className={classes.cardContent}>
<Typography
gutterBottom
variant="h5"
component="h2"
color="textPrimary"
>
{post.type}: {post.variety}
</Typography>
<IconText
icon={
<Icon fontSize="small" color="primary">
location_on
</Icon>
}
text={post.originCountry}
/>
<IconText
icon={
<Icon fontSize="small" color="primary">
local_shipping
</Icon>
}
text={post.quantity}
/>
</CardContent>
</CardActionArea>
</Card>
</Grid>
))}
{loading &&
!publicPosts &&
[1, 2, 3].map((post, index) => (
<Grid item key={index} xs={12} sm={6} md={4}>
<Card className={classes.card}>
<Skeleton variant="rect" className={classes.cardMedia} />
<CardContent className={classes.cardContent}>
<Skeleton
animation="wave"
height={16}
style={{ marginBottom: 6 }}
/>
<Skeleton animation="wave" height={10} width="80%" />
</CardContent>
</Card>
</Grid>
))}
</Grid>
</Container>
{isAdmin && (
<Container className={classes.cardGrid} maxWidth="md">
<Typography variant="h3" component="h2" gutterBottom>
Pending posts
</Typography>
<Grid container spacing={4}>
{!error &&
privatePosts?.map((post: any, index) => (
<Grid item key={post?.id ?? index} xs={12} sm={6} md={4}>
<Card className={classes.card}>
{post ? (
<>
<CardActionArea
component={Link}
to={`/posts/${post.id}`}
style={{ display: 'block' }}
>
<ResponsiveImage src={post.image}>
{post.organic && (
<div className={classes.chipWrapper}>
{post.organic && (
<Chip
// variant="filled"
color="primary"
size="small"
label="Organic"
icon={
<Icon style={{ fontSize: 14 }}>eco</Icon>
}
/>
)}
</div>
)}
</ResponsiveImage>
<CardContent className={classes.cardContent}>
<Typography
gutterBottom
variant="h5"
component="h2"
color="textPrimary"
>
{post.type}: {post.variety}
</Typography>
<IconText
icon={
<Icon fontSize="small" color="primary">
location_on
</Icon>
}
text={post.originCountry}
/>
<IconText
icon={
<Icon fontSize="small" color="primary">
local_shipping
</Icon>
}
text={post.quantity}
/>
</CardContent>
</CardActionArea>
</>
) : (
<>
<Skeleton
variant="rect"
className={classes.cardMedia}
/>
<CardContent className={classes.cardContent}>
<Skeleton
animation="wave"
height={16}
style={{ marginBottom: 6 }}
/>
<Skeleton animation="wave" height={10} width="80%" />
</CardContent>
</>
)}
</Card>
</Grid>
))}
</Grid>
</Container>
)}
</>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment