Skip to content

Commit

Permalink
feat: updated client code and added shadcn button
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonpraful committed Feb 17, 2024
1 parent df78318 commit 89ffbf4
Show file tree
Hide file tree
Showing 19 changed files with 1,239 additions and 466 deletions.
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
18.13.0
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @jasonpraful/vite-boilerplate

## 0.1.0

### Minor Changes

- updated client code and added shadcn button

## 0.0.1

### Patch Changes
Expand Down
80 changes: 75 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,91 @@
# Vite Boilerplate
# Vite + React Boilerplate

All in one front-end Vite.js + React boilerplate + AWS Infrastructure via Terraform
<p align="center">
<picture>
<source srcset="https://vitejs.dev/logo.svg" media="(prefers-color-scheme: dark)">
<img src="https://vitejs.dev/logo.svg" width="100" alt="Vite Boilerplate">
</picture>
</p>
<p align="center">
All in one front-end React + Vite.js + Tailwind + Zustand + Shadcn + AWS Infrastructure via Terraform
</p>

<p align="center">
<img alt="Deployment Status" src="https://github.com/jasonpraful/vite-boilerplate/actions/workflows/deploy.yml/badge.svg"/>
</p>

## Features

- Vite.js
- React
- TypeScript
- Tailwind CSS
- [with Shadcn Ui](https://ui.shadcn.com)
- Zustand (State Management)
- Vitest + React Testing Library
- Playwright
- Playwright (E2E Testing)
- All bolts Terraform infrastructure for AWS
- S3
- CloudFront (CDN)

Boilerplate also consists of eslint, prettier, typescript, and tailwindcss
configurations.
## Getting Started

```bash
git clone https://github.com/jasonpraful/vite-boilerplate
cd vite-boilerplate
```

```bash
rm -rf .git && git init # Reset git & initialize new git
```

```bash
npm i
```

## Development

```bash
npm run dev
```

## Build

```bash
npm run build
```

## Testing

```bash
npm run test:unit # Unit Test
npm run test:e2e # E2E Test (Playwright)
```

## Deployment

```bash
npm run tf:init # Initialize Terraform
npm run tf:plan # Plan Terraform
npm run tf:apply # Apply Terraform
```

## Versioning

```bash
npm run version # Changeset versioning
```

## Linting

```bash
npm run lint # Linting
```

## Contributing

Pull requests are welcome. For major changes, please open an issue first to
discuss what you would like to change.

## License

Expand Down
17 changes: 17 additions & 0 deletions components.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/styles/global.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "src/components",
"utils": "@utils"
}
}
30 changes: 30 additions & 0 deletions e2e/counter.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { expect, test } from '@playwright/test'

test.describe.configure({ mode: 'parallel' })
test.describe('counter', () => {
test('has Heading', async ({ page }) => {
await page.goto('http://localhost:4173')
const text = await page.textContent('h1')
expect(text).toBe('Vite + React + TailwindCSS + Zustand')
})

test('has zero', async ({ page }) => {
await page.goto('http://localhost:4173')
const text = await page.getByLabel('count').textContent()
expect(text).toBe('0')
})

test('increments', async ({ page }) => {
await page.goto('http://localhost:4173')
await page.getByLabel('increment').click()
const text = await page.getByLabel('count').textContent()
expect(text).toBe('1')
})

test('decrements', async ({ page }) => {
await page.goto('http://localhost:4173')
await page.getByLabel('decrement').click()
const text = await page.getByLabel('count').textContent()
expect(text).toBe('-1')
})
})
7 changes: 0 additions & 7 deletions e2e/example.spec.ts

This file was deleted.

20 changes: 15 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "@jasonpraful/vite-boilerplate",
"version": "0.0.1",
"version": "0.1.0",
"type": "module",
"private": true,
"private": false,
"author": "Jason Praful <jason.praful@gmail.com>",
"license": "MIT",
"description": "A Vite boilerplate with React, TypeScript, Tailwind CSS, and Playwright",
Expand Down Expand Up @@ -32,16 +32,26 @@
"test:e2e:codegen": "playwright codegen",
"playwright:setup": "playwright install --with-deps",
"commitlint": "commitlint --edit",
"version": "changeset version",
"version": "changeset && changeset version",
"tf:init": "cd terraform && terraform init",
"tf:plan": "cd terraform && terraform plan",
"tf:apply": "cd terraform && terraform apply",
"tf:destroy": "cd terraform && terraform destroy"
},
"dependencies": {
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-slot": "^1.0.2",
"@tanstack/react-query": "^5.18.1",
"@tanstack/react-query-devtools": "^5.21.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"immer": "^10.0.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"zustand": "^4.5.1"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
Expand Down Expand Up @@ -79,6 +89,6 @@
"vitest": "^1.2.2"
},
"engines": {
"node": ">=18.0.0"
"node": ">=18.13.0"
}
}
25 changes: 23 additions & 2 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
import { render } from '@testing-library/react'
import { act } from 'react-dom/test-utils'
import { describe, expect, it } from 'vitest'

import App from './App'

describe('App', () => {
it('renders hello world', () => {
it('renders heading', () => {
const { getByText } = render(<App />)
expect(getByText('Hello, world!👋')).toBeInTheDocument()
expect(
getByText('Vite + React + TailwindCSS + Zustand'),
).toBeInTheDocument()
})

it('renders count', () => {
const { getByLabelText } = render(<App />)
expect(getByLabelText('count')).toBeInTheDocument()
expect(getByLabelText('count')).toHaveTextContent('0')
})

it('increments and decrements count', () => {
const { getByLabelText } = render(<App />)
act(() => {
getByLabelText('decrement').click()
})
expect(getByLabelText('count')).toHaveTextContent('-1')
act(() => {
getByLabelText('increment').click()
})
expect(getByLabelText('count')).toHaveTextContent('0')
})
})
47 changes: 42 additions & 5 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,47 @@
import { ArrowDownIcon, ArrowUpIcon } from '@radix-ui/react-icons'
import { useCounterStore } from '@store/counter.store'

import { Button } from './components/ui/button'

function App() {
const { count, increment, decrement } = useCounterStore()

return (
<div className="h-dvh bg-slate-400 antialiased">
<div className="relative flex h-screen items-center justify-center ">
<div className="relative flex animate-bounce">
<div className="rounded-md border border-black bg-slate-900 px-10 py-2 text-white">
<h1 className="text-4xl font-bold">Hello, world!👋</h1>
<div className="h-dvh">
<div className="flex h-screen flex-col items-center justify-center">
<p className="mb-5 text-center text-3xl">
<img
src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/React-icon.svg/1024px-React-icon.svg.png"
alt="React Logo"
className="inline-block h-10 mr-5 motion-safe:animate-[spin_5s_linear_infinite]"
/>
Vite + React + TailwindCSS + Zustand
</p>
<div className="flex flex-col">
<div className="flex h-auto w-auto items-center justify-center rounded-md border p-2 shadow-sm">
<p aria-label="count" className="text-3xl">
{count}
</p>
</div>
<div className="mt-2 flex gap-5">
<Button
aria-label="increment"
aria-description="Increment the count by 1"
variant={'outline'}
size={'icon'}
onClick={increment}
>
<ArrowUpIcon />
</Button>
<Button
variant={'outline'}
aria-label="decrement"
aria-description="Decrement the count by 1"
size={'icon'}
onClick={decrement}
>
<ArrowDownIcon />
</Button>
</div>
</div>
</div>
Expand Down
55 changes: 55 additions & 0 deletions src/components/ui/button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Button created via Shadcn UI (https://ui.shadcn.com/docs)
import { Slot } from '@radix-ui/react-slot'
import { cn } from '@utils/cn'
import { cva, type VariantProps } from 'class-variance-authority'
import * as React from 'react'

const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default:
'bg-primary text-primary-foreground shadow hover:bg-primary/90 active:shadow-none',
destructive:
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90 active:shadow-none',
outline:
'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground active:bg-accent/90 active:shadow-none',
secondary:
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80 active:shadow-none',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 rounded-md px-3 text-xs',
lg: 'h-10 rounded-md px-8',
icon: 'h-9 w-9',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
)

export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean
}

export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : 'button'
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
)
},
)
Button.displayName = 'Button'
Empty file added src/hooks/.gitkeep
Empty file.
3 changes: 0 additions & 3 deletions src/index.css

This file was deleted.

11 changes: 9 additions & 2 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import './index.css'
import '@styles/global.css'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import React from 'react'
import ReactDOM from 'react-dom/client'

import App from './App.tsx'

const queryClient = new QueryClient()

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
<ReactQueryDevtools client={queryClient} position="bottom" />
</React.StrictMode>,
)
Loading

0 comments on commit 89ffbf4

Please sign in to comment.