diff --git a/packages/core/installMachine/index.ts b/packages/core/installMachine/index.ts index b618232..74e912d 100644 --- a/packages/core/installMachine/index.ts +++ b/packages/core/installMachine/index.ts @@ -15,6 +15,8 @@ import { createDocFiles } from './installSteps/docs/create'; import { pushToGitHub } from './installSteps/github/repositoryManager'; import { InstallMachineContext, StepsCompleted } from '../types'; import { saveStateToRcFile } from '../utils/rcFileManager'; +import { installTailwind } from './installSteps/tailwind/install'; +import { modifyHomepage } from './installSteps/homepage/install'; const isStepCompleted = (stepName: keyof StepsCompleted) => { return ({ context }: { context: InstallMachineContext; event: AnyEventObject }) => { @@ -58,12 +60,40 @@ const createInstallMachine = (initialContext: InstallMachineContext) => { always: [ { guard: isStepCompleted('initializeProject'), - target: 'installSupabase', + target: 'installTailwind', }, ], invoke: { src: 'initializeProjectActor', input: ({ context }) => context, + onDone: 'installTailwind', + onError: 'failed', + }, + }, + installTailwind: { + always: [ + { + guard: isStepCompleted('installTailwind'), + target: 'modifyHomepage', + }, + ], + invoke: { + src: 'installTailwindActor', + input: ({ context }) => context, + onDone: 'modifyHomepage', + onError: 'failed', + }, + }, + modifyHomepage: { + always: [ + { + guard: isStepCompleted('modifyHomepage'), + target: 'installSupabase', + }, + ], + invoke: { + src: 'modifyHomepageActor', + input: ({ context }) => context, onDone: 'installSupabase', onError: 'failed', }, @@ -273,6 +303,30 @@ const createInstallMachine = (initialContext: InstallMachineContext) => { } }), ), + installTailwindActor: createStepMachine( + fromPromise(async ({ input }) => { + try { + installTailwind(input.projectDir); + input.stateData.stepsCompleted.installTailwind = true; + saveStateToRcFile(input.stateData, input.projectDir); + } catch (error) { + console.error('Error in installTailwindActor:', error); + throw error; + } + }), + ), + modifyHomepageActor: createStepMachine( + fromPromise(async ({ input }) => { + try { + modifyHomepage(input.projectDir); + input.stateData.stepsCompleted.modifyHomepage = true; + saveStateToRcFile(input.stateData, input.projectDir); + } catch (error) { + console.error('Error in modifyHomepageActor:', error); + throw error; + } + }), + ), installSupabaseActor: createStepMachine( fromPromise(async ({ input }) => { try { diff --git a/packages/core/installMachine/installSteps/homepage/install.ts b/packages/core/installMachine/installSteps/homepage/install.ts new file mode 100644 index 0000000..a8b2026 --- /dev/null +++ b/packages/core/installMachine/installSteps/homepage/install.ts @@ -0,0 +1,16 @@ +import { homepageFiles } from '../../../templates/homepage/installConfig'; +import { templateGenerator } from '../../../utils/generator/generator'; +import { getTemplateDirectory } from '../../../utils/getTemplateDirectory'; +import { logger } from '../../../utils/logger'; + +export const modifyHomepage = async (destinationDirectory: string) => { + await logger.withSpinner('tailwind', 'Setting up your welcome homepage...', async (spinner) => { + try { + const templateDirectory = getTemplateDirectory(`/templates/homepage/files/`); + templateGenerator(homepageFiles, templateDirectory, destinationDirectory); + } catch (error) { + spinner.fail('Tailwind installation failed'); + console.error('Error during tailwind installation:', error); + } + }); +}; diff --git a/packages/core/installMachine/installSteps/tailwind/install.ts b/packages/core/installMachine/installSteps/tailwind/install.ts new file mode 100644 index 0000000..b56c845 --- /dev/null +++ b/packages/core/installMachine/installSteps/tailwind/install.ts @@ -0,0 +1,36 @@ +import { execSync } from 'child_process'; +import fs from 'fs'; +import path from 'path'; +import { tailwindFiles } from '../../../templates/tailwind/installConfig'; +import { templateGenerator } from '../../../utils/generator/generator'; +import { getTemplateDirectory } from '../../../utils/getTemplateDirectory'; +import { logger } from '../../../utils/logger'; + +export const installTailwind = async (destinationDirectory: string) => { + await logger.withSpinner('tailwind', 'Adding Tailwind...', async (spinner) => { + try { + installTailwindPackage(destinationDirectory); + copyTailwindFiles(destinationDirectory); + spinner.succeed('Tailwind installed.'); + } catch (error) { + spinner.fail('Tailwind installation failed'); + console.error('Error during tailwind installation:', error); + } + }); +}; + +const copyTailwindFiles = (destinationDirectory: string) => { + const templateDirectory = getTemplateDirectory(`/templates/tailwind/files/`); + templateGenerator(tailwindFiles, templateDirectory, destinationDirectory); +}; + +const installTailwindPackage = async (destinationDirectory: string) => { + const packageJsonPath = path.join(destinationDirectory, 'apps/web/package.json'); + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); + delete packageJson.dependencies['@repo/ui']; + fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); + process.chdir(path.join(destinationDirectory, 'apps/web')); + execSync('pnpm add -D tailwindcss postcss autoprefixer', { stdio: 'inherit' }); + process.chdir(destinationDirectory); + execSync('pnpm install', { stdio: 'inherit' }); +}; diff --git a/packages/core/templates/homepage/files/globals.css b/packages/core/templates/homepage/files/globals.css new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/packages/core/templates/homepage/files/globals.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/packages/core/templates/homepage/files/layout.tsx b/packages/core/templates/homepage/files/layout.tsx new file mode 100644 index 0000000..3b35c1f --- /dev/null +++ b/packages/core/templates/homepage/files/layout.tsx @@ -0,0 +1,31 @@ +import type { Metadata } from 'next'; +import { Roboto, Playfair_Display } from 'next/font/google'; +import './globals.css'; + +const roboto = Roboto({ + subsets: ['latin'], + weight: ['400', '700'], + variable: '--font-roboto', +}); + +const playfair = Playfair_Display({ + subsets: ['latin'], + variable: '--font-playfair', +}); + +export const metadata: Metadata = { + title: 'Welcome to Stapler', + description: 'Experience the future of organization with Stapler', +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + {children} + + ); +} diff --git a/packages/core/templates/homepage/files/page.tsx b/packages/core/templates/homepage/files/page.tsx new file mode 100644 index 0000000..621e5bc --- /dev/null +++ b/packages/core/templates/homepage/files/page.tsx @@ -0,0 +1,358 @@ +import Link from 'next/link'; + +const hLineTransforms = [545.79, 635.35, 723.689, 813.69, 902.448, 991.201]; +const vLineTransforms = [ + { x: 586.769, id: 7 }, + { x: 675.878, id: 8 }, + { x: 764.079, id: 9 }, + { x: 143.554, id: 10 }, + { x: 852.7, id: 11 }, + { x: 232.175, id: 12 }, + { x: 941.885, id: 13 }, + { x: 321.361, id: 14 }, + { x: 1030.37, id: 15 }, + { x: 409.843, id: 16 }, + { x: 1120.75, id: 17 }, + { x: 500.226, id: 18 }, +]; + +export default function Home() { + return ( +
+ + +
+
+
+ + + + {hLineTransforms.map((yPos, index) => ( + + + + ))} + {vLineTransforms.map(({ x, id }, index) => ( + + + + ))} + + + + {Array.from({ length: 6 }, (_, i) => ( + + + + + + ))} + {Array.from({ length: 12 }, (_, i) => ( + + + + + + + + ))} + + +
+
+
+
+
+

Welcome to your Stapler! 📎

+

+ We hope you saved a lot of time and effort by using Stapler. At Tonik we are always looking for ways to + make your life easier. If you have any feedback or suggestions, please let us know. We would love to hear + from you! Edit this page in the apps/web/app/page.tsx file! 🚀 +

+
+
+ +
+

This stapler use following stack:

+
+
+ + + + + + + + + + +
+
+ + + + + {' '} + + {' '} + + {' '} + {' '} + {' '} + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+ ); +} diff --git a/packages/core/templates/homepage/installConfig.ts b/packages/core/templates/homepage/installConfig.ts new file mode 100644 index 0000000..0f69086 --- /dev/null +++ b/packages/core/templates/homepage/installConfig.ts @@ -0,0 +1,6 @@ +export const homepageFiles = [ + { + path: 'apps/web/app/', + files: ['page.tsx', 'layout.tsx', 'globals.css'], + }, +]; diff --git a/packages/core/templates/tailwind/files/postcss.config.js b/packages/core/templates/tailwind/files/postcss.config.js new file mode 100644 index 0000000..12a703d --- /dev/null +++ b/packages/core/templates/tailwind/files/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; diff --git a/packages/core/templates/tailwind/files/tailwind.config.ts b/packages/core/templates/tailwind/files/tailwind.config.ts new file mode 100644 index 0000000..f5c2c31 --- /dev/null +++ b/packages/core/templates/tailwind/files/tailwind.config.ts @@ -0,0 +1,14 @@ +import type { Config } from 'tailwindcss'; +import { fontFamily } from 'tailwindcss/defaultTheme'; + +export default { + content: ['app/**/*.{ts,tsx}'], + theme: { + extend: { + fontFamily: { + sans: ['var(--font-roboto)', ...fontFamily.sans], + mono: ['var(--font-playfair)', ...fontFamily.mono], + }, + }, + }, +} satisfies Config; diff --git a/packages/core/templates/tailwind/installConfig.ts b/packages/core/templates/tailwind/installConfig.ts new file mode 100644 index 0000000..58402cd --- /dev/null +++ b/packages/core/templates/tailwind/installConfig.ts @@ -0,0 +1,6 @@ +export const tailwindFiles = [ + { + path: 'apps/web/', + files: ['postcss.config.js', 'tailwind.config.ts'], + }, +]; diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 6ec5d22..f6783a2 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -10,13 +10,6 @@ "rootDir": ".", "composite": true }, - "include": [ - "index.ts", - "types.ts", - "utils/**/*.ts", - "installMachine/**/*.ts", - "templates/supabase/installConfig.ts", - "templates/docs/installConfig.ts" - ], - "exclude": ["node_modules", "dist", "templates/supabase/files/**/*", "templates/docs/files/**/*"] + "include": ["index.ts", "types.ts", "utils/**/*.ts", "installMachine/**/*.ts", "templates/**/installConfig.ts"], + "exclude": ["node_modules", "dist", "templates/**/files/**/*"] } diff --git a/packages/core/types.ts b/packages/core/types.ts index 0afe23f..17dad53 100644 --- a/packages/core/types.ts +++ b/packages/core/types.ts @@ -5,6 +5,8 @@ export interface ProjectOptions { export interface StepsCompleted { initializeProject: boolean; + installTailwind: boolean; + modifyHomepage: boolean; installSupabase: boolean; installPayload: boolean; createDocFiles: boolean; diff --git a/packages/core/utils/logger.ts b/packages/core/utils/logger.ts index dea889b..26dab5b 100644 --- a/packages/core/utils/logger.ts +++ b/packages/core/utils/logger.ts @@ -6,6 +6,7 @@ type Name = | 'stapler' | 'turborepo' | 'supabase' + | 'tailwind' | 'payload' | 'github' | 'prettier' @@ -36,6 +37,11 @@ const names: NameProps[] = [ prefix: 'Supabase', colors: ['#3ABC82', '#259764'], }, + { + name: 'tailwind', + prefix: 'Tailwind', + colors: ['#38B2AC', '#0099F7'], + }, { name: 'payload', prefix: 'Payload',