-
Notifications
You must be signed in to change notification settings - Fork 10
feat(basic/ts): add typescript basic react chef #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
27eddfd
2dc06d5
5985b0f
e6f4ce9
c146681
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| const getConfig = () => { | ||
| return { | ||
| bundler: "webpack", | ||
| ui: "material-ui", | ||
| state: "none", | ||
| buildDir: "public", | ||
| sourceDir: { | ||
| main: "src", | ||
| static: "static", | ||
| assets: "assets", | ||
| images: "images", | ||
| containers: "modules", | ||
| i18n: "i18n", | ||
| components: "components", | ||
| businessLogic: "blocks", | ||
| userInterface: "ui", | ||
| utility: "utils", | ||
| hooks: "hooks", | ||
| theme: "theme", | ||
| store: "store", | ||
| services: "services", | ||
| locales: "translations", | ||
| }, | ||
| modules: { | ||
| signIn: "SignIn", | ||
| dashboard: "Dashboard", | ||
| notFound: "NotFound", | ||
| }, | ||
| canAdd: { | ||
| gitIgnore: true, | ||
| eslint: true, | ||
| environment: true, | ||
| prettier: true, | ||
| husky: true, | ||
| hooks: true, | ||
| hookForm: true, | ||
| routes: true, | ||
| utils: true, | ||
| static: true, | ||
| i18n: true, | ||
| modules: true, | ||
| componentsCopy: false, | ||
| fullComponents: true, | ||
| }, | ||
| }; | ||
| }; | ||
|
|
||
| const getModulesList = () => { | ||
| return [ | ||
| "reactWithI18n", | ||
| "router", | ||
| "services", | ||
| "utils" | ||
| ]; | ||
| }; | ||
|
|
||
| const getDevModulesList = () => { | ||
| return [ | ||
| "webpack", | ||
| "webpackPlugins", | ||
| "webpackLoaders", | ||
| "babel", | ||
| "basicTypescriptDev" | ||
| ]; | ||
| }; | ||
|
|
||
| module.exports = { | ||
| getConfig, | ||
| getModulesList, | ||
| getDevModulesList, | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| { | ||
| "presets": [ | ||
| [ | ||
| "@babel/preset-env", | ||
| { | ||
| "targets": { | ||
| "node": "current" | ||
| } | ||
| } | ||
| ], | ||
| "@babel/preset-react", | ||
| "@babel/preset-typescript" | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| { | ||
| "extends": ["airbnb-base", "prettier"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| { | ||
| "arrowParens": "always", | ||
| "bracketSpacing": true, | ||
| "embeddedLanguageFormatting": "auto", | ||
| "htmlWhitespaceSensitivity": "css", | ||
| "insertPragma": false, | ||
| "jsxBracketSameLine": false, | ||
| "jsxSingleQuote": false, | ||
| "printWidth": 100, | ||
| "proseWrap": "preserve", | ||
| "quoteProps": "as-needed", | ||
| "requirePragma": false, | ||
| "semi": true, | ||
| "singleQuote": false, | ||
| "tabWidth": 2, | ||
| "trailingComma": "all", | ||
| "useTabs": false, | ||
| "vueIndentScriptAndStyle": false, | ||
| "plugins": ["prettier-plugin-tailwindcss"] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| const shell = require('shelljs') | ||
| const { getWebPackConfig } = require('./webpack.config') | ||
| const rootIndex = require('./sources/index') | ||
| const rootApp = require('./sources/App') | ||
| const rootRoutes = require('./sources/Routes') | ||
| const withI18n = require('./sources/withI18n') | ||
| const signInModule = require('./sources/SignIn') | ||
| const dashboardModule = require('./sources/Dashboard') | ||
| const pageLoaderBlock = require('./sources/PageLoader') | ||
| const sidebarBlock = require('./sources/Sidebar') | ||
| const topBarBlock = require('./sources/TopBar') | ||
|
|
||
| const sourceCodes = { | ||
| index: rootIndex, | ||
| App: rootApp, | ||
| Routes: rootRoutes, | ||
| withI18n: withI18n, | ||
| SignIn: signInModule, | ||
| Dashboard: dashboardModule, | ||
| PageLoader: pageLoaderBlock, | ||
| Sidebar: sidebarBlock, | ||
| TopBar: topBarBlock, | ||
| } | ||
|
|
||
|
|
||
| const getFileContent = (fileName) => { | ||
| return shell.cat(`${__dirname}/${fileName}`) | ||
| } | ||
|
|
||
| const getDynamicSourceCode = (fileName, appName, baseConfig) => { | ||
| const key = fileName.replace(/\.(js|ts|tsx)$/, '') | ||
| const source = sourceCodes[key] | ||
|
|
||
| if (!source) { | ||
| throw new Error(`Source template not found: ${key}`) | ||
| } | ||
|
|
||
| return source.getSourceCode(appName, baseConfig) | ||
| } | ||
|
|
||
| module.exports = { | ||
| getFileContent, | ||
| getWebPackConfig, | ||
| getDynamicSourceCode, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| function getSourceCode(appName, { sourceDir }) { | ||
| return `import React, { FC } from 'react' | ||
| import { unstable_HistoryRouter as HistoryRouter } from 'react-router-dom' | ||
| import { createBrowserHistory, History } from 'history' | ||
|
|
||
| import Routes from './Routes' | ||
|
|
||
| // Block Components | ||
| import { ErrorHandler, PageLoader } from '@/components/blocks' | ||
|
|
||
| import { withTranslation } from '@/${sourceDir.i18n}' | ||
|
|
||
| const browserHistory = createBrowserHistory() | ||
|
|
||
| interface AppProps extends WithTranslation {} | ||
|
|
||
| function App(props: AppProps) { | ||
| return ( | ||
| <ErrorHandler> | ||
| <PageLoader /> | ||
| <HistoryRouter history={browserHistory}> | ||
| <Routes /> | ||
| </HistoryRouter> | ||
| </ErrorHandler> | ||
| ) | ||
| } | ||
|
|
||
| export default withTranslation(App) | ||
|
|
||
| ` | ||
| } | ||
|
|
||
| module.exports = { | ||
| getSourceCode, | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| function getSourceCode(appName, { sourceDir }) { | ||
| return `import React from 'react' | ||
| import { useNavigate } from 'react-router-dom' | ||
|
|
||
| import { I18nMsg } from '@/${sourceDir.i18n}' | ||
|
|
||
| // Utils. | ||
| import { RoutePaths } from '@/${sourceDir.utility}' | ||
|
|
||
| // Service Hooks | ||
| import useFetch from '@/${sourceDir.hooks}/useFetch' | ||
|
|
||
| const SAMPLE_GET_API_URL = 'https://jsonplaceholder.typicode.com/users' | ||
|
|
||
| interface DashboardProps { | ||
| title?: string | ||
| } | ||
|
Comment on lines
+15
to
+17
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this need to be separate file in
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already this file after installation it will add inside module folder |
||
|
|
||
| interface User { | ||
| id: number | ||
| name: string | ||
| } | ||
|
|
||
| const Dashboard: React.FC<DashboardProps> = (props) => { | ||
| const navigate = useNavigate() | ||
|
|
||
| const { loading, error, response = [] } = useFetch<User[]>(SAMPLE_GET_API_URL) | ||
|
|
||
| if (loading) return 'Loading..' | ||
| if (error) return error.message | ||
|
|
||
| return ( | ||
| <> | ||
| <section> | ||
| <div> | ||
| <h1> | ||
| <I18nMsg id="dashboard" /> goes here | ||
| </h1> | ||
| {response.map((user) => { | ||
| return <li key={user.id}>{user.name}</li> | ||
| })} | ||
| <button | ||
| onClick={() => { | ||
| navigate(RoutePaths.SignIn) | ||
| }} | ||
| > | ||
| Click back | ||
| </button> | ||
| </div> | ||
| </section> | ||
| </> | ||
| ) | ||
| } | ||
|
|
||
| export default Dashboard | ||
| ` | ||
| } | ||
|
|
||
| module.exports = { | ||
| getSourceCode, | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| function getSourceCode(appName, { sourceDir }) { | ||
| return `import React, { Fragment } from 'react' | ||
|
|
||
| // UI Components. | ||
| import { Spinner } from '@/components/ui' | ||
|
|
||
| interface PageLoaderProps { | ||
| loading: boolean | ||
| } | ||
|
|
||
| export default function PageLoader({ loading }: PageLoaderProps) { | ||
| return loading ? <Spinner /> : null | ||
| } | ||
|
|
||
| ` | ||
|
|
||
| } | ||
|
|
||
| module.exports = { | ||
| getSourceCode, | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| function getSourceCode(appName, { modules }) { | ||
| return `import React, { Suspense } from 'react' | ||
| import { Route, Routes } from 'react-router-dom' | ||
|
|
||
| // Block Components | ||
| import { PageLoader } from '@/components/blocks' | ||
|
|
||
| // Utils | ||
| import { RoutePaths } from '@/utils' | ||
|
|
||
| // Lazy-loaded modules | ||
| const SignInModule = React.lazy(() => | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. typed code is missing. its javascript
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
| import(/* webpackChunkName: "${modules.signIn}" */ '@/modules/${modules.signIn}') | ||
| ) | ||
|
|
||
| const DashBoardModule = React.lazy(() => | ||
| import(/* webpackChunkName: "${modules.dashboard}" */ '@/modules/${modules.dashboard}') | ||
| ) | ||
|
|
||
| const NotFoundModule = React.lazy(() => | ||
| import(/* webpackChunkName: "${modules.notFound}" */ '@/modules/${modules.notFound}') | ||
| ) | ||
|
|
||
| function RoutesComponent() { | ||
| return ( | ||
| <Suspense fallback={<PageLoader />}> | ||
| <Routes> | ||
| <Route path={RoutePaths.SignIn} element={<SignInModule />} /> | ||
| <Route path={RoutePaths.DashBoard} element={<DashBoardModule />} /> | ||
| <Route path="*" element={<NotFoundModule />} /> | ||
| </Routes> | ||
| </Suspense> | ||
| ) | ||
| } | ||
|
|
||
| export default RoutesComponent | ||
| ` | ||
| } | ||
|
|
||
| module.exports = { | ||
| getSourceCode, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| function getSourceCode(appName, { sourceDir }) { | ||
| return `import React, { HTMLAttributes } from 'react' | ||
| import { useI18n } from '@/${sourceDir.i18n}' | ||
|
|
||
| // Domain Components. | ||
| import SidebarNav from './SidebarNav' | ||
|
|
||
| // Utils. | ||
| import { RoutePaths } from '@/${sourceDir.utility}' | ||
|
|
||
| interface Page { | ||
| title: string | ||
| href: string | ||
| icon: string | ||
| } | ||
|
|
||
| interface SidebarProps extends HTMLAttributes<HTMLDivElement> { | ||
| open: boolean | ||
| variant: string | ||
| onClose?: () => void | ||
| className?: string | ||
| } | ||
|
|
||
| const Sidebar: React.FC<SidebarProps> = (props) => { | ||
| const { open, variant, onClose, className, ...rest } = props | ||
| const { formatMessage } = useI18n() | ||
|
|
||
| const pages: Page[] = [ | ||
| { | ||
| title: formatMessage({ id: 'dashboard' }), | ||
| href: RoutePaths.dashboard, | ||
| icon: '', | ||
| }, | ||
| { | ||
| title: formatMessage({ id: 'other_module' }), | ||
| href: RoutePaths.dashboard, | ||
| icon: '', | ||
| }, | ||
| ] | ||
|
|
||
| return ( | ||
| <section> | ||
| <div {...rest}> | ||
| <SidebarNav pages={pages} /> | ||
| </div> | ||
| </section> | ||
| ) | ||
| } | ||
|
|
||
| export default Sidebar | ||
| ` | ||
|
|
||
| } | ||
|
|
||
| module.exports = { | ||
| getSourceCode, | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep 1 space
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done