Skip to content

Commit

Permalink
Merge branch 'main' of github.com:iteria-app/example-material-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
magicsk committed Nov 28, 2022
2 parents 1a34f7a + f575ada commit 7db0edd
Show file tree
Hide file tree
Showing 23 changed files with 34,435 additions and 16,593 deletions.
20 changes: 19 additions & 1 deletion .env.development
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
VITE_HASURA_GRAPHQL_ENDPOINT = "https://test.hasura.magicsk.eu/v1/graphql"
VITE_HASURA_GRAPHQL_SECRET = "c2akHldMLELW7z5RFUMu8AnUxyHAXAThFzW5JZK7HejgMjG5cn7kr1m0C0Vefdbc"
VITE_INJECT_MODE = "devServer"
VITE_AUTH_MODE = "token" # token | admin_secret
VITE_INJECT_MODE = "devServer"


VITE_AUTH_PROVIDER = "firebase"

VITE_FIREBASE_API_KEY = "AIzaSyBQrfw2BoTJL7SEFwP7fnNih6FNxegw7QY"
VITE_FIREBASE_DOMAIN = "dev-iteria.firebaseapp.com"
VITE_FIREBASE_PERSISTANCE="LOCAL_DB" # NONE | LOCAL_BROWSER | LOCAL_DB | SESSION

VITE_AUTH0_DOMAIN = ""
VITE_AUTH0_CLIENT_ID = ""
VITE_AUTH0_AUDIENCE = ""

VITE_KEYCLOAK_URL = ""
VITE_KEYCLOAK_REALM = ""
VITE_KEYCLOAK_CLIENT_ID = ""
VITE_KEYCLOAK_CLIENT_SECRET = ""
VITE_KEYCLOAK_ADMIN_SECRET = ""
20 changes: 19 additions & 1 deletion .env.production
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
VITE_HASURA_GRAPHQL_ENDPOINT = "https://test.hasura.magicsk.eu/v1/graphql"
VITE_HASURA_GRAPHQL_SECRET = "c2akHldMLELW7z5RFUMu8AnUxyHAXAThFzW5JZK7HejgMjG5cn7kr1m0C0Vefdbc"
VITE_INJECT_MODE = "jamstack"
VITE_AUTH_MODE = "token" # token | admin_secret
VITE_INJECT_MODE = "jamstack"


VITE_AUTH_PROVIDER = "firebase"

VITE_FIREBASE_API_KEY = "AIzaSyBQrfw2BoTJL7SEFwP7fnNih6FNxegw7QY"
VITE_FIREBASE_DOMAIN = "dev-iteria.firebaseapp.com"
VITE_FIREBASE_PERSISTANCE="LOCAL_DB" # NONE | LOCAL_BROWSER | LOCAL_DB | SESSION

VITE_AUTH0_DOMAIN = ""
VITE_AUTH0_CLIENT_ID = ""
VITE_AUTH0_AUDIENCE = ""

VITE_KEYCLOAK_URL = ""
VITE_KEYCLOAK_REALM = ""
VITE_KEYCLOAK_CLIENT_ID = ""
VITE_KEYCLOAK_CLIENT_SECRET = ""
VITE_KEYCLOAK_ADMIN_SECRET = ""
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,4 @@
"typescript": "4.5.4",
"vite": "2.8.6"
}
}
}
36 changes: 24 additions & 12 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
I18nProvider,
useLocale,
DataContext,
GraphqlcodegenDataProvider
GraphqlcodegenDataProvider,
authExchange,
useClient
} from '@iteria-app/component-templates'
import '../src/mixins/chartjs'
import { theme } from './theme'
Expand All @@ -16,28 +18,38 @@ import * as graphqlgen from './generated/graphql'
import introspection from './generated/introspect.json'
import {
cacheExchange,
ClientOptions,
createClient,
debugExchange,
fetchExchange,
Provider as UrqlProvider,
Provider as UrqlProvider
} from 'urql'

const graphqlcodegenDataProvider = new GraphqlcodegenDataProvider(
graphqlgen,
introspection.__schema as any
)

const client = createClient({
url: import.meta.env.VITE_HASURA_GRAPHQL_ENDPOINT as string,
exchanges: [debugExchange, fetchExchange],
fetchOptions: {
headers: {
'x-hasura-admin-secret': import.meta.env.VITE_HASURA_GRAPHQL_SECRET as string
const App = () => {
const clientOptions: ClientOptions = {
url: import.meta.env.VITE_HASURA_GRAPHQL_ENDPOINT as string,
exchanges: [debugExchange, authExchange(), fetchExchange]
//requestPolicy: 'cache-and-network',
}
const superClient = createClient({
...clientOptions,
fetchOptions: {
headers: {
'x-hasura-admin-secret': import.meta.env
.VITE_HASURA_GRAPHQL_SECRET as string
}
}
},
})
})

let client = createClient(clientOptions)

if (import.meta.env.VITE_AUTH_MODE === 'admin_secret') client = superClient

const App = () => {
const routing = useRoutes(routes)
const locale = useLocale()
const messagesObject = messages(locale)
Expand All @@ -55,7 +67,7 @@ const App = () => {

App.propTypes = {
locale: PropTypes.string,
messages: PropTypes.object,
messages: PropTypes.object
}

export default App
34 changes: 34 additions & 0 deletions src/components/entities/FormCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Grid, Table, TableBody, Typography } from '@mui/material'
import {
stringPrettyCapitalize,
Translate,
} from '@iteria-app/component-templates'
import React, { ReactNode } from 'react'
interface Props {
title: string
children: ReactNode
length?: number
}
export const FormCard: React.FC<Props> = ({ title, children, length }) => {
return (
<Grid item md={length ?? 6 > 7 ? 12 : 6}>
<Typography sx={{ marginY: '12px', textTransform: 'uppercase' }}>
<Translate
entityName={title}
defaultMessage={stringPrettyCapitalize(title)}
/>
</Typography>
<Table sx={{ tableLayout: 'fixed' }}>
<TableBody
sx={{
'tr:nth-of-type(odd)': {
background: '#F2F3F4',
},
}}
>
{children}
</TableBody>
</Table>
</Grid>
)
}
83 changes: 83 additions & 0 deletions src/components/entities/LookupDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Close } from '@mui/icons-material'
import {
Dialog,
DialogTitle,
Grid,
IconButton,
DialogContent,
} from '@mui/material'
import React from 'react'
import {
stringPrettyCapitalize,
Translate,
} from '@iteria-app/component-templates'
interface Props {
children: React.ReactNode
Container: any
View: any
onClickRow?: (products: any) => void
title?: string
}
export const LookupDialog: React.FC<Props> = ({
children,
Container,
View,
onClickRow,
title,
}) => {
const [open, setOpen] = React.useState(false)
const handleClickOpen = () => {
setOpen(true)
}
const handleClose = () => {
setOpen(false)
}
return (
<>
{React.Children.map(children, (child) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, { onClick: handleClickOpen })
}
return child
})}
<Dialog fullWidth open={open} onClose={handleClose}>
<DialogTitle>
<Grid container>
<Grid item xs>
<Translate
entityName={title ?? 'default'}
fieldName="lookup.title"
defaultMessage={
stringPrettyCapitalize(title) ?? 'Lookup dialog'
}
/>
</Grid>
<Grid item>
<IconButton aria-label="close" onClick={handleClose}>
<Close />
</IconButton>
</Grid>
</Grid>
</DialogTitle>
<DialogContent>
<Container
View={(data, filterProps) => (
<View
data={data?.data}
loading={data?.loading}
error={data?.error}
onClickRow={(row) => {
if (onClickRow) {
onClickRow(row)
}
setOpen(false)
}}
filterProps={filterProps}
/>
)}
/>
</DialogContent>
</Dialog>
</>
)
}
68 changes: 68 additions & 0 deletions src/components/entities/products/ProductsCardListContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react'
import {
ErrorBoundary,
QueryBoundary,
useFilter,
InfiniteScrolling,
Toolbar,
CreateButton,
} from '@iteria-app/component-templates'
import { Box, Grid, Skeleton } from '@mui/material'
import { ProductsFragment, useProductsQuery } from '../../../generated/graphql'
import introspection from '../../../generated/introspect.json'
interface ViewProps {
data: ProductsFragment[]
}
interface ProductsListContainerProps {
View: React.FC<ViewProps>
}
const ProductsCardListContainer: React.FC<ProductsListContainerProps> = ({
View,
}) => {
const filterProps = useFilter()
const entityIntrospection = introspection?.__schema?.types?.find(
(type) => type?.name === 'products'
)?.fields
const [data] = useProductsQuery({
variables: {
where: filterProps.filter,
limit: filterProps.pageSize,
offset: filterProps.offset,
order_by: filterProps.sort,
},
})
return (
<ErrorBoundary>
<QueryBoundary queryResponse={data}>
<Toolbar filterProps={filterProps} introspection={entityIntrospection}>
<CreateButton entityName="products" />
</Toolbar>
<InfiniteScrolling
filterProps={filterProps}
data={data}
loadingSkeleton={
<Grid container>
{[...Array(6)].map((_, index) => (
<Box key={index} p="5px" m="5px" maxWidth="200px">
<Skeleton
variant="rectangular"
animation="pulse"
width={200}
height={150}
/>
<Box marginTop="5px">
<Skeleton variant="text" animation="pulse" />
<Skeleton variant="text" animation="pulse" width={100} />
</Box>
</Box>
))}
</Grid>
}
>
<View data={data?.data?.products} />
</InfiniteScrolling>
</QueryBoundary>
</ErrorBoundary>
)
}
export default ProductsCardListContainer
84 changes: 84 additions & 0 deletions src/components/entities/products/ProductsCardListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react'
import {
Box,
Card,
CardContent,
CardHeader,
CardMedia,
IconButton,
Typography,
} from '@mui/material'
import { useNavigate } from 'react-router-dom'
import { ProductsFragment } from '../../../generated/graphql'
import MoreVertIcon from '@mui/icons-material/MoreVert'
import { getCardTitle, getImagePath } from '@iteria-app/component-templates'
import { useFormikContext } from 'formik'
export interface IPropsProductsCardItem {
data: ProductsFragment
relationshipName?: string
index?: number
}
const ProductsCardListItem: React.FC<IPropsProductsCardItem> = ({
data,
relationshipName,
index,
}) => {
const navigate = useNavigate()
let formikContext
if (relationshipName) formikContext = useFormikContext()
const setFieldValue = formikContext?.setFieldValue
const columns = [
<Box
key="products.name"
sx={{
display: 'flex',
justifyContent: 'space-between',
marginTop: '5px',
}}
>
<Typography fontSize="14px" fontWeight={400}>
{data?.name}
</Typography>
</Box>,
]
const primary = getCardTitle(data)
return (
<Box
p="5px"
m="5px"
maxWidth="200px"
sx={{
cursor: 'pointer',
}}
onClick={() => !relationshipName && navigate(data?.id.toString())}
>
<Card
sx={{
borderRadius: '7px',
}}
>
<CardHeader
title={primary}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
/>
<CardMedia
component="img"
image={getImagePath(data) ?? '/static/placeholder.png'}
height="250px"
alt={primary}
sx={{ minWidth: '200px' }}
/>
<CardContent>
{Object.values(columns).filter(
(v) => data?.[v?.key?.toString().split('.')?.pop()] !== primary
)}
</CardContent>
</Card>
</Box>
)
}
export default ProductsCardListItem
Loading

0 comments on commit 7db0edd

Please sign in to comment.