shortcut-next 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hadi87s
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Quickstart Next ⚡
1
+ # Shortcut Next ⚡
2
2
 
3
3
  > Scaffold modern **Next.js 15+ projects** in seconds — with **MUI**, **React Hook Form**, and **TanStack Query** built-in.
4
4
  > Optionally add **Tailwind CSS v4** with a single command.
@@ -22,4 +22,5 @@
22
22
  You don’t need to install globally. Use `npx`:
23
23
 
24
24
  ```bash
25
- npx @hadi87s/quickstart-next@latest
25
+ npx shortcut-next@latest
26
+
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  import('../src/run.mjs').catch(e => {
3
3
  console.error(e);
4
4
  process.exit(1);
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "shortcut-next",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Scaffold Next.js apps with MUI base or Tailwind v4 preset.",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "shortcut-next": "bin/quickstart-next.mjs"
7
+ "shortcut-next": "bin/shortcut-next.mjs"
8
8
  },
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/hadi87s/quickstart-next.git"
11
+ "url": "git+https://github.com/hadi87s/shortcut-next.git"
12
12
  },
13
13
  "bugs": {
14
- "url": "https://github.com/hadi87s/quickstart-next/issues"
14
+ "url": "https://github.com/hadi87s/shortcut-next/issues"
15
15
  },
16
- "homepage": "https://github.com/hadi87s/quickstart-next#readme",
16
+ "homepage": "https://github.com/hadi87s/shortcut-next#readme",
17
17
  "publishConfig": {
18
18
  "access": "public"
19
19
  },
@@ -26,9 +26,19 @@
26
26
  "scripts": {
27
27
  "test": "echo \"Error: no test specified\" && exit 1"
28
28
  },
29
- "keywords": [],
29
+ "engines": {
30
+ "node": ">=18"
31
+ },
32
+ "keywords": [
33
+ "nextjs",
34
+ "cli",
35
+ "scaffold",
36
+ "starter",
37
+ "mui",
38
+ "tailwind"
39
+ ],
30
40
  "author": "",
31
- "license": "ISC",
41
+ "license": "MIT",
32
42
  "type": "module",
33
43
  "dependencies": {
34
44
  "@clack/prompts": "^0.11.0",
@@ -0,0 +1,42 @@
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import { CssBaseline, PaletteMode, ThemeProvider, createTheme } from '@mui/material'
5
+ import GlobalStyles from './globalStyles'
6
+ import { buildThemeOptions } from './ThemeOptions'
7
+
8
+ type Ctx = { mode: PaletteMode; toggle: () => void; set: (m: PaletteMode) => void }
9
+ export const ColorModeContext = React.createContext<Ctx>({ mode: 'dark', toggle: () => {}, set: () => {} })
10
+
11
+ function getInitialMode(): PaletteMode {
12
+ if (typeof window === 'undefined') return 'dark'
13
+ const stored = window.localStorage.getItem('color-scheme') as PaletteMode | null
14
+ if (stored === 'light' || stored === 'dark') return stored
15
+ return window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'
16
+ }
17
+
18
+ export default function ThemeComponent({ children }: { children: React.ReactNode }) {
19
+ const [mode, setMode] = React.useState<PaletteMode>(getInitialMode)
20
+
21
+ React.useEffect(() => {
22
+ document.documentElement.setAttribute('data-color-scheme', mode)
23
+ window.localStorage.setItem('color-scheme', mode)
24
+ }, [mode])
25
+
26
+ const ctx = React.useMemo<Ctx>(
27
+ () => ({ mode, toggle: () => setMode(m => (m === 'light' ? 'dark' : 'light')), set: setMode }),
28
+ [mode]
29
+ )
30
+
31
+ const theme = React.useMemo(() => createTheme(buildThemeOptions(mode)), [mode])
32
+
33
+ return (
34
+ <ColorModeContext.Provider value={ctx}>
35
+ <ThemeProvider theme={theme}>
36
+ <CssBaseline />
37
+ <GlobalStyles />
38
+ {children}
39
+ </ThemeProvider>
40
+ </ColorModeContext.Provider>
41
+ )
42
+ }
@@ -0,0 +1,21 @@
1
+ import { createTheme, PaletteMode, ThemeOptions } from '@mui/material'
2
+ import { makePalette } from './palette'
3
+ import { makeTypography } from './typography'
4
+ import { makeShadows } from './shadows'
5
+ import { makeSpacing } from './spacing'
6
+ import { makeBreakpoints } from './breakpoints'
7
+ import { makeOverrides } from './overrides'
8
+
9
+ export function buildThemeOptions(mode: PaletteMode): ThemeOptions {
10
+ const options: ThemeOptions = {
11
+ palette: makePalette(mode),
12
+ typography: makeTypography(),
13
+ spacing: makeSpacing(),
14
+ breakpoints: makeBreakpoints(),
15
+ shape: { borderRadius: 12 },
16
+ shadows: makeShadows(),
17
+ components: makeOverrides(createTheme({ palette: makePalette(mode) }))
18
+ }
19
+
20
+ return options
21
+ }
@@ -0,0 +1,7 @@
1
+ import type { ThemeOptions } from '@mui/material'
2
+
3
+ export function makeBreakpoints(): ThemeOptions['breakpoints'] {
4
+ return {
5
+ values: { xs: 0, sm: 600, md: 900, lg: 1200, xl: 1536 }
6
+ }
7
+ }
@@ -0,0 +1,13 @@
1
+ import * as React from 'react'
2
+ import { GlobalStyles as MUIGlobalStyles } from '@mui/material'
3
+
4
+ export default function GlobalStyles() {
5
+ return (
6
+ <MUIGlobalStyles
7
+ styles={{
8
+ '*, *::before, *::after': { boxSizing: 'border-box' },
9
+ body: { margin: 0 }
10
+ }}
11
+ />
12
+ )
13
+ }
@@ -0,0 +1,58 @@
1
+ import type { Components, Theme } from '@mui/material/styles'
2
+
3
+ export function makeOverrides(theme: Theme): Components<Theme> {
4
+ const isDark = theme.palette.mode === 'dark'
5
+
6
+ return {
7
+ MuiCssBaseline: {
8
+ styleOverrides: {
9
+ ':root': {
10
+ '--blob-1': 'radial-gradient(closest-side, #7C4DFF 0%, rgba(124,77,255,0) 70%)',
11
+ '--blob-2': 'radial-gradient(closest-side, #00E5FF 0%, rgba(0,229,255,0) 70%)'
12
+ },
13
+ body: {
14
+ backgroundImage: isDark
15
+ ? `radial-gradient(1200px 600px at 10% -10%, rgba(124,77,255,0.07), transparent),
16
+ radial-gradient(900px 500px at 110% 110%, rgba(0,229,255,0.06), transparent)`
17
+ : undefined
18
+ }
19
+ }
20
+ },
21
+
22
+ MuiContainer: { defaultProps: { maxWidth: 'lg' } },
23
+
24
+ MuiCard: {
25
+ styleOverrides: {
26
+ root: {
27
+ borderRadius: 12,
28
+ border: `1px solid ${isDark ? 'rgba(255,255,255,0.08)' : 'rgba(0,0,0,0.06)'}`,
29
+ background: isDark
30
+ ? 'linear-gradient(180deg, rgba(255,255,255,0.04), rgba(255,255,255,0.02))'
31
+ : 'linear-gradient(180deg, #FFFFFF, #FAFBFF)'
32
+ }
33
+ }
34
+ },
35
+
36
+ MuiButton: {
37
+ defaultProps: { disableElevation: true },
38
+ styleOverrides: {
39
+ root: { borderRadius: 12, paddingInline: 16 },
40
+ containedPrimary: {
41
+ background: `linear-gradient(180deg, ${theme.palette.primary.main}, ${theme.palette.primary.dark})`
42
+ }
43
+ }
44
+ },
45
+
46
+ MuiTextField: { defaultProps: { size: 'small', fullWidth: true } },
47
+ MuiInputLabel: { styleOverrides: { root: { fontWeight: 600 } } },
48
+ MuiChip: { styleOverrides: { root: { borderRadius: 10 } } },
49
+ MuiAppBar: {
50
+ styleOverrides: {
51
+ root: {
52
+ backgroundColor: isDark ? 'rgba(16,19,26,0.72)' : 'rgba(255,255,255,0.72)',
53
+ backdropFilter: 'saturate(120%) blur(8px)'
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,37 @@
1
+ import type { PaletteMode, ThemeOptions } from '@mui/material'
2
+
3
+ const brand = {
4
+ 50: '#EEF0FF',
5
+ 100: '#DDE2FF',
6
+ 200: '#BEC7FF',
7
+ 300: '#9DABFF',
8
+ 400: '#7C8FFF',
9
+ 500: '#5B74FF', // main
10
+ 600: '#415BEE',
11
+ 700: '#2F46CF',
12
+ 800: '#2132A6',
13
+ 900: '#1A2880'
14
+ }
15
+
16
+ export function makePalette(mode: PaletteMode): ThemeOptions['palette'] {
17
+ const isDark = mode === 'dark'
18
+ return {
19
+ mode,
20
+ primary: { light: brand[400], main: brand[500], dark: brand[700], contrastText: '#fff' },
21
+ brand: { light: brand[400], main: brand[500], dark: brand[700], contrastText: '#fff' },
22
+ secondary: { light: '#64E1FF', main: '#00D0FF', dark: '#00A3CC', contrastText: '#001219' },
23
+ error: { light: '#FF7A7A', main: '#FF4D4F', dark: '#C62828' },
24
+ warning: { light: '#FFD166', main: '#FFB703', dark: '#C98A00' },
25
+ info: { light: '#9AD0FF', main: '#55ADFF', dark: '#1E7ED6' },
26
+ success: { light: '#33D69F', main: '#11C28B', dark: '#0E9B6F' },
27
+ divider: isDark ? 'rgba(255,255,255,0.12)' : 'rgba(0,0,0,0.12)',
28
+ background: {
29
+ default: isDark ? '#0B0D12' : '#F7F8FB',
30
+ paper: isDark ? '#10131A' : '#FFFFFF'
31
+ },
32
+ text: {
33
+ primary: isDark ? '#E6E8EF' : '#10141D',
34
+ secondary: isDark ? 'rgba(230,232,239,0.7)' : '#4A5568'
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,13 @@
1
+ import type { ThemeOptions } from '@mui/material'
2
+
3
+ export function makeShadows(): ThemeOptions['shadows'] {
4
+ // start from MUI defaults and tweak a few
5
+ const base = [
6
+ 'none',
7
+ '0 1px 3px rgba(0,0,0,0.12)',
8
+ '0 2px 6px rgba(0,0,0,0.12)',
9
+ '0 4px 12px rgba(0,0,0,0.12)',
10
+ ...Array(21).fill('0 10px 30px rgba(0,0,0,0.12)')
11
+ ] as unknown as ThemeOptions['shadows']
12
+ return base
13
+ }
@@ -0,0 +1,5 @@
1
+ import type { ThemeOptions } from '@mui/material'
2
+
3
+ export function makeSpacing(): ThemeOptions['spacing'] {
4
+ return 8 // 8px grid
5
+ }
@@ -0,0 +1,10 @@
1
+ import type { PaletteColor, PaletteColorOptions } from '@mui/material/styles'
2
+
3
+ declare module '@mui/material/styles' {
4
+ interface Palette {
5
+ brand: PaletteColor
6
+ }
7
+ interface PaletteOptions {
8
+ brand?: PaletteColorOptions
9
+ }
10
+ }
@@ -0,0 +1,15 @@
1
+ import type { ThemeOptions } from '@mui/material'
2
+
3
+ export function makeTypography(): ThemeOptions['typography'] {
4
+ return {
5
+ fontFamily:
6
+ 'Inter, ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, "Apple Color Emoji","Segoe UI Emoji"',
7
+ h1: { fontWeight: 800, letterSpacing: 0.2 },
8
+ h2: { fontWeight: 800, letterSpacing: 0.2 },
9
+ h3: { fontWeight: 800 },
10
+ h4: { fontWeight: 700 },
11
+ h5: { fontWeight: 700 },
12
+ h6: { fontWeight: 700 },
13
+ button: { textTransform: 'none', fontWeight: 600, letterSpacing: 0.2 }
14
+ } as const
15
+ }
@@ -14,8 +14,8 @@ const geistMono = Geist_Mono({
14
14
  })
15
15
 
16
16
  export const metadata: Metadata = {
17
- title: 'Create Next App',
18
- description: 'Generated by create next app'
17
+ title: 'Shortcut Nextjs Template',
18
+ description: 'Stop starting projects from scratch, start in the middle and save time!'
19
19
  }
20
20
 
21
21
  export default function RootLayout({
@@ -18,8 +18,9 @@ import {
18
18
  } from '@mui/material'
19
19
  import ContentCopyIcon from '@mui/icons-material/ContentCopy'
20
20
  import OpenInNewIcon from '@mui/icons-material/OpenInNew'
21
- import { Github, Package, LayoutDashboard, FormInput } from 'lucide-react'
21
+ import { Github, Package, LayoutDashboard, FormInput, Sun, Moon } from 'lucide-react'
22
22
  import { Icon } from '@iconify/react'
23
+ import { ColorModeContext } from '@/@core/theme/ThemeComponent'
23
24
 
24
25
  const Code = ({ children }: { children: React.ReactNode }) => (
25
26
  <Box
@@ -41,6 +42,213 @@ const Code = ({ children }: { children: React.ReactNode }) => (
41
42
  </Box>
42
43
  )
43
44
 
45
+ function HeroSection({}: { copied: boolean; handleCopy: (text: string) => void }) {
46
+ const colorMode = React.useContext(ColorModeContext)
47
+ const { mode, toggle } = colorMode || { mode: 'light', toggle: () => {} }
48
+
49
+ return (
50
+ <Stack spacing={3} alignItems='center' textAlign='center' sx={{ mb: { xs: 6, md: 10 } }}>
51
+ <Stack direction='row' spacing={1} alignItems='center'>
52
+ <LayoutDashboard size={28} style={{ verticalAlign: 'middle' }} />
53
+ <Typography variant='h4' fontWeight={800} letterSpacing={0.2} sx={{ ml: 1 }}>
54
+ Shortcut Next
55
+ </Typography>
56
+ </Stack>
57
+ <Typography variant='h6' sx={{ maxWidth: 860, opacity: 0.9 }}>
58
+ A modern Next.js boilerplate powered by <b>MUI</b> with room for <b>React Query</b>, <b>React Hook Form</b>, and
59
+ optional <b>Tailwind&nbsp;v4</b>.
60
+ </Typography>
61
+ <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} useFlexGap flexWrap='wrap'>
62
+ <Chip
63
+ icon={<Icon icon='simple-icons:mui' width={18} height={18} style={{ borderRadius: 4 }} />}
64
+ label='MUI'
65
+ color='primary'
66
+ variant='filled'
67
+ />
68
+ <Chip icon={<FormInput size={18} />} label='React Hook Form' variant='outlined' />
69
+ <Chip
70
+ icon={<Icon icon='devicon:tailwindcss' width={18} height={18} />}
71
+ label='Tailwind v4 (optional)'
72
+ variant='outlined'
73
+ />
74
+ <Chip
75
+ icon={<Icon icon='devicon:typescript' width={18} height={18} style={{ borderRadius: 4 }} />}
76
+ label='TypeScript'
77
+ variant='outlined'
78
+ />
79
+ <Chip icon={<Icon icon='devicon:nextjs' width={18} height={18} />} label='App Router' variant='outlined' />
80
+ </Stack>
81
+ <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ pt: 1 }}>
82
+ <Button
83
+ size='large'
84
+ variant='contained'
85
+ onClick={toggle}
86
+ startIcon={mode === 'dark' ? <Sun size={20} /> : <Moon size={20} />}
87
+ >
88
+ Toggle Theme ({mode === 'dark' ? 'Dark' : 'Light'})
89
+ </Button>
90
+ <Button
91
+ size='large'
92
+ variant='outlined'
93
+ endIcon={<OpenInNewIcon />}
94
+ component={Link}
95
+ href='#'
96
+ target='_blank'
97
+ rel='noopener'
98
+ >
99
+ View Docs
100
+ </Button>
101
+ </Stack>
102
+ </Stack>
103
+ )
104
+ }
105
+
106
+ function WhatsIncludedCard({ copied, handleCopy }: { copied: boolean; handleCopy: (text: string) => void }) {
107
+ return (
108
+ <Card
109
+ sx={{
110
+ backdropFilter: 'saturate(120%) blur(6px)',
111
+ background: 'rgba(255,255,255,0.04)',
112
+ border: '1px solid',
113
+ borderColor: 'rgba(255,255,255,0.08)'
114
+ }}
115
+ >
116
+ <CardContent>
117
+ <Typography variant='h6' fontWeight={700} gutterBottom>
118
+ What’s included
119
+ </Typography>
120
+ <Stack spacing={1.25} sx={{ opacity: 0.9 }}>
121
+ <Typography>• Next.js 15 (App Router) + TypeScript</Typography>
122
+ <Typography>• MUI ThemeProvider + dark-ready UI</Typography>
123
+ <Typography>
124
+ • RHF starter form at <code>/sample-form</code>
125
+ </Typography>
126
+ <Typography>• Easy opt-in Tailwind v4 (via CLI preset)</Typography>
127
+ </Stack>
128
+ <Divider sx={{ my: 3 }} />
129
+ <Typography variant='subtitle2' gutterBottom>
130
+ Scaffold via npx
131
+ </Typography>
132
+ <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} alignItems='center'>
133
+ <Code>npx shortcut-next@latest</Code>
134
+ <Tooltip title={copied ? 'Copied!' : 'Copy'}>
135
+ <Button
136
+ variant='outlined'
137
+ size='small'
138
+ startIcon={<ContentCopyIcon fontSize='small' />}
139
+ onClick={() => handleCopy('npx shortcut-next@latest')}
140
+ >
141
+ {copied ? 'Copied' : 'Copy'}
142
+ </Button>
143
+ </Tooltip>
144
+ </Stack>
145
+ </CardContent>
146
+ </Card>
147
+ )
148
+ }
149
+
150
+ function TechLogosCard() {
151
+ return (
152
+ <Card
153
+ sx={{
154
+ height: '100%',
155
+ backdropFilter: 'saturate(120%) blur(6px)',
156
+ background: 'rgba(255,255,255,0.04)',
157
+ border: '1px solid',
158
+ borderColor: 'rgba(255,255,255,0.08)'
159
+ }}
160
+ >
161
+ <CardContent>
162
+ <Typography variant='h6' fontWeight={700} gutterBottom>
163
+ Current Tech
164
+ </Typography>
165
+ <Stack direction='row' spacing={2} alignItems='center' sx={{ pb: 1.5 }}>
166
+ <Tooltip title='MUI' arrow placement='top'>
167
+ <span>
168
+ <Icon icon='simple-icons:mui' width={28} height={28} style={{ borderRadius: 4 }} />
169
+ </span>
170
+ </Tooltip>
171
+ <Tooltip title='Tailwind CSS' arrow placement='top'>
172
+ <span>
173
+ <Icon icon='devicon:tailwindcss' width={28} height={28} />
174
+ </span>
175
+ </Tooltip>
176
+ <Tooltip title='React' arrow placement='top'>
177
+ <span>
178
+ <Icon icon='devicon:react' width={28} height={28} />
179
+ </span>
180
+ </Tooltip>
181
+ <Tooltip title='Next.js' arrow placement='top'>
182
+ <span>
183
+ <Icon icon='devicon:nextjs' width={28} height={28} />
184
+ </span>
185
+ </Tooltip>
186
+ <Tooltip title='React Hook Form' arrow placement='top'>
187
+ <span>
188
+ <Icon icon='simple-icons:reacthookform' width={28} height={28} />
189
+ </span>
190
+ </Tooltip>
191
+ <Tooltip title='TypeScript' arrow placement='top'>
192
+ <span>
193
+ <Icon icon='devicon:typescript' width={28} height={28} style={{ borderRadius: 4 }} />
194
+ </span>
195
+ </Tooltip>
196
+ </Stack>
197
+ <Typography variant='body2' sx={{ opacity: 0.85 }}>
198
+ These are the core technologies powering this template. Hover over each logo to see its name.
199
+ </Typography>
200
+ <Divider sx={{ my: 2 }} />
201
+ <Stack direction='row' spacing={1.5}>
202
+ <Button
203
+ variant='outlined'
204
+ size='small'
205
+ startIcon={<Github size={18} />}
206
+ endIcon={<OpenInNewIcon />}
207
+ component={Link}
208
+ href='https://github.com/Hadi87s/shortcut-next'
209
+ target='_blank'
210
+ rel='noopener'
211
+ >
212
+ GitHub
213
+ </Button>
214
+ <Button
215
+ variant='outlined'
216
+ size='small'
217
+ startIcon={<Package size={18} />}
218
+ endIcon={<OpenInNewIcon />}
219
+ component={Link}
220
+ href='https://www.npmjs.com/package/shortcut-next'
221
+ target='_blank'
222
+ rel='noopener'
223
+ >
224
+ npm
225
+ </Button>
226
+ </Stack>
227
+ </CardContent>
228
+ </Card>
229
+ )
230
+ }
231
+
232
+ function Footer() {
233
+ return (
234
+ <Stack alignItems='center' sx={{ mt: 8, opacity: 0.65 }}>
235
+ <Typography variant='body2'>
236
+ Built with ❤️ by{' '}
237
+ <MuiLink
238
+ href='https://github.com/hadi87s/quickstart-next'
239
+ underline='none'
240
+ color='primary'
241
+ sx={{ fontWeight: 600 }}
242
+ target='_blank'
243
+ rel='noopener'
244
+ >
245
+ Hadi
246
+ </MuiLink>{' '}
247
+ using MUI. Ready for Tailwind v4, React Query, and more.
248
+ </Typography>
249
+ </Stack>
250
+ )
251
+ }
44
252
  export default function Page() {
45
253
  const [copied, setCopied] = React.useState(false)
46
254
 
@@ -64,7 +272,6 @@ export default function Page() {
64
272
  color: 'text.primary'
65
273
  }}
66
274
  >
67
- {/* --- Glowing blobs --- */}
68
275
  <Box
69
276
  aria-hidden
70
277
  sx={{
@@ -72,7 +279,7 @@ export default function Page() {
72
279
  position: 'absolute',
73
280
  inset: 0,
74
281
  '&::before, &::after': {
75
- content: '""',
282
+ content: "''",
76
283
  position: 'absolute',
77
284
  width: 520,
78
285
  height: 520,
@@ -105,210 +312,17 @@ export default function Page() {
105
312
  }
106
313
  }}
107
314
  />
108
-
109
315
  <Container maxWidth='lg' sx={{ position: 'relative', zIndex: 1, py: { xs: 6, md: 10 } }}>
110
- {/* Hero */}
111
- <Stack spacing={3} alignItems='center' textAlign='center' sx={{ mb: { xs: 6, md: 10 } }}>
112
- <Stack direction='row' spacing={1} alignItems='center'>
113
- <LayoutDashboard size={28} style={{ verticalAlign: 'middle' }} />
114
- <Typography variant='h4' fontWeight={800} letterSpacing={0.2} sx={{ ml: 1 }}>
115
- Quickstart Next
116
- </Typography>
117
- </Stack>
118
-
119
- <Typography variant='h6' sx={{ maxWidth: 860, opacity: 0.9 }}>
120
- A modern Next.js boilerplate powered by <b>MUI</b> with room for <b>React Query</b>, <b>React Hook Form</b>,
121
- and optional <b>Tailwind&nbsp;v4</b>.
122
- </Typography>
123
-
124
- <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} useFlexGap flexWrap='wrap'>
125
- <Chip
126
- icon={<Icon icon='simple-icons:mui' width={18} height={18} style={{ borderRadius: 4 }} />}
127
- label='MUI'
128
- color='primary'
129
- variant='filled'
130
- />
131
- <Chip icon={<FormInput size={18} />} label='React Hook Form' variant='outlined' />
132
- <Chip
133
- icon={<Icon icon='devicon:tailwindcss' width={18} height={18} />}
134
- label='Tailwind v4 (optional)'
135
- variant='outlined'
136
- />
137
- <Chip
138
- icon={<Icon icon='devicon:typescript' width={18} height={18} style={{ borderRadius: 4 }} />}
139
- label='TypeScript'
140
- variant='outlined'
141
- />
142
- <Chip icon={<Icon icon='devicon:nextjs' width={18} height={18} />} label='App Router' variant='outlined' />
143
- </Stack>
144
-
145
- <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ pt: 1 }}>
146
- <Button size='large' variant='contained' component={Link} href='/sample-form'>
147
- Open Sample Form
148
- </Button>
149
- <Button
150
- size='large'
151
- variant='outlined'
152
- endIcon={<OpenInNewIcon />}
153
- component={Link}
154
- href='#'
155
- target='_blank'
156
- rel='noopener'
157
- >
158
- View Docs
159
- </Button>
160
- </Stack>
161
- </Stack>
162
-
163
- {/* Content */}
316
+ <HeroSection copied={copied} handleCopy={handleCopy} />
164
317
  <Grid container spacing={3}>
165
318
  <Grid size={{ xs: 12, md: 7 }}>
166
- <Card
167
- sx={{
168
- backdropFilter: 'saturate(120%) blur(6px)',
169
- background: 'rgba(255,255,255,0.04)',
170
- border: '1px solid',
171
- borderColor: 'rgba(255,255,255,0.08)'
172
- }}
173
- >
174
- <CardContent>
175
- <Typography variant='h6' fontWeight={700} gutterBottom>
176
- What’s included
177
- </Typography>
178
- <Stack spacing={1.25} sx={{ opacity: 0.9 }}>
179
- <Typography>• Next.js 15 (App Router) + TypeScript</Typography>
180
- <Typography>• MUI ThemeProvider + dark-ready UI</Typography>
181
- <Typography>
182
- • RHF starter form at <code>/sample-form</code>
183
- </Typography>
184
- <Typography>• Easy opt-in Tailwind v4 (via CLI preset)</Typography>
185
- </Stack>
186
-
187
- <Divider sx={{ my: 3 }} />
188
-
189
- <Typography variant='subtitle2' gutterBottom>
190
- Scaffold via npx
191
- </Typography>
192
-
193
- <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} alignItems='center'>
194
- <Code>npx @hadi87s/quickstart-next@latest</Code>
195
- <Tooltip title={copied ? 'Copied!' : 'Copy'}>
196
- <Button
197
- variant='outlined'
198
- size='small'
199
- startIcon={<ContentCopyIcon fontSize='small' />}
200
- onClick={() => handleCopy('npx @hadi87s/quickstart-next@latest')}
201
- >
202
- {copied ? 'Copied' : 'Copy'}
203
- </Button>
204
- </Tooltip>
205
- </Stack>
206
- </CardContent>
207
- </Card>
319
+ <WhatsIncludedCard copied={copied} handleCopy={handleCopy} />
208
320
  </Grid>
209
-
210
321
  <Grid size={{ xs: 12, md: 5 }}>
211
- <Card
212
- sx={{
213
- height: '100%',
214
- backdropFilter: 'saturate(120%) blur(6px)',
215
- background: 'rgba(255,255,255,0.04)',
216
- border: '1px solid',
217
- borderColor: 'rgba(255,255,255,0.08)'
218
- }}
219
- >
220
- <CardContent>
221
- <Typography variant='h6' fontWeight={700} gutterBottom>
222
- Tech Logos
223
- </Typography>
224
- <Stack direction='row' spacing={2} alignItems='center' sx={{ pb: 1.5 }}>
225
- <Tooltip title='MUI' arrow placement='top'>
226
- <span>
227
- <Icon icon='simple-icons:mui' width={28} height={28} style={{ borderRadius: 4 }} />
228
- </span>
229
- </Tooltip>
230
- <Tooltip title='Tailwind CSS' arrow placement='top'>
231
- <span>
232
- <Icon icon='devicon:tailwindcss' width={28} height={28} />
233
- </span>
234
- </Tooltip>
235
- <Tooltip title='React' arrow placement='top'>
236
- <span>
237
- <Icon icon='devicon:react' width={28} height={28} />
238
- </span>
239
- </Tooltip>
240
- <Tooltip title='Next.js' arrow placement='top'>
241
- <span>
242
- <Icon icon='devicon:nextjs' width={28} height={28} />
243
- </span>
244
- </Tooltip>
245
- <Tooltip title='React Hook Form' arrow placement='top'>
246
- <span>
247
- <Icon icon='simple-icons:reacthookform' width={28} height={28} />
248
- </span>
249
- </Tooltip>
250
- <Tooltip title='TypeScript' arrow placement='top'>
251
- <span>
252
- <Icon icon='devicon:typescript' width={28} height={28} style={{ borderRadius: 4 }} />
253
- </span>
254
- </Tooltip>
255
- </Stack>
256
-
257
- <Typography variant='body2' sx={{ opacity: 0.85 }}>
258
- This template ships with MUI by default. You can enable Tailwind v4 at scaffold time. React Query and
259
- other integrations can be added as the stack grows.
260
- </Typography>
261
-
262
- <Divider sx={{ my: 2 }} />
263
-
264
- <Stack direction='row' spacing={1.5}>
265
- <Button
266
- variant='outlined'
267
- size='small'
268
- startIcon={<Github size={18} />}
269
- endIcon={<OpenInNewIcon />}
270
- component={Link}
271
- href='https://github.com/hadi87s/quickstart-next'
272
- target='_blank'
273
- rel='noopener'
274
- >
275
- GitHub
276
- </Button>
277
- <Button
278
- variant='outlined'
279
- size='small'
280
- startIcon={<Package size={18} />}
281
- endIcon={<OpenInNewIcon />}
282
- component={Link}
283
- href='https://www.npmjs.com/package/@hadi87s/quickstart-next'
284
- target='_blank'
285
- rel='noopener'
286
- >
287
- npm
288
- </Button>
289
- </Stack>
290
- </CardContent>
291
- </Card>
322
+ <TechLogosCard />
292
323
  </Grid>
293
324
  </Grid>
294
-
295
- {/* Footer */}
296
- <Stack alignItems='center' sx={{ mt: 8, opacity: 0.65 }}>
297
- <Typography variant='body2'>
298
- Built with ❤️ by{' '}
299
- <MuiLink
300
- href='https://github.com/hadi87s/quickstart-next'
301
- underline='none'
302
- color='primary'
303
- sx={{ fontWeight: 600 }}
304
- target='_blank'
305
- rel='noopener'
306
- >
307
- Hadi
308
- </MuiLink>{' '}
309
- using MUI. Ready for Tailwind v4, React Query, and more.
310
- </Typography>
311
- </Stack>
325
+ <Footer />
312
326
  </Container>
313
327
  </Box>
314
328
  )
@@ -1,22 +1,14 @@
1
1
  'use client'
2
2
 
3
3
  import { PropsWithChildren, useState } from 'react'
4
- import { CssBaseline, ThemeProvider, createTheme } from '@mui/material'
5
4
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
6
-
7
- const theme = createTheme({
8
- palette: { mode: 'dark' },
9
- shape: { borderRadius: 12 },
10
- typography: { fontFamily: 'system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif' }
11
- })
5
+ import ThemeComponent from '@/@core/theme/ThemeComponent'
12
6
 
13
7
  export default function BaseProviders({ children }: PropsWithChildren) {
14
8
  const [client] = useState(() => new QueryClient())
15
9
  return (
16
- <ThemeProvider theme={theme}>
17
- {/* If you kept Tailwind preflight OFF, keep CssBaseline ON */}
18
- <CssBaseline />
10
+ <ThemeComponent>
19
11
  <QueryClientProvider client={client}>{children}</QueryClientProvider>
20
- </ThemeProvider>
12
+ </ThemeComponent>
21
13
  )
22
14
  }