Skip to content

Commit f5e9875

Browse files
committed
Initial commit: Davince Testimonial Form
- Modern testimonial collection form with chat-like interface - Google Sheets integration for data storage - Built with Next.js 16, TypeScript, and Tailwind CSS 4 - Optimized for performance with React memoization - Production-ready with CI/CD pipeline - Comprehensive documentation and contributing guidelines
0 parents  commit f5e9875

31 files changed

Lines changed: 2568 additions & 0 deletions

.editorconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# EditorConfig helps maintain consistent coding styles
2+
# https://editorconfig.org
3+
4+
root = true
5+
6+
[*]
7+
charset = utf-8
8+
end_of_line = lf
9+
indent_style = space
10+
indent_size = 2
11+
insert_final_newline = true
12+
trim_trailing_whitespace = true
13+
14+
[*.md]
15+
trim_trailing_whitespace = false
16+
17+
[*.{yml,yaml}]
18+
indent_size = 2

.env.local.example

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Google Sheets Configuration
2+
# 1. Create a Google Cloud Service Account at https://console.cloud.google.com/
3+
# 2. Enable Google Sheets API in your project
4+
# 3. Download the JSON credentials file
5+
# 4. Share your Google Sheet with the service account email (Editor permission)
6+
# 5. Copy the values below from your credentials JSON and paste them here
7+
8+
# Email from service account credentials (format: your-app@project-id.iam.gserviceaccount.com)
9+
GOOGLE_SHEETS_CLIENT_EMAIL=your-service-account@your-project.iam.gserviceaccount.com
10+
11+
# Private key from service account credentials (include quotes and newlines as \n)
12+
GOOGLE_SHEETS_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYourPrivateKeyHere\n-----END PRIVATE KEY-----\n"
13+
14+
# Your Google Sheets Spreadsheet ID (found in the URL: docs.google.com/spreadsheets/d/{SPREADSHEET_ID}/edit)
15+
GOOGLE_SHEETS_SPREADSHEET_ID=your-spreadsheet-id-here
16+
17+
# The name of the sheet/tab where testimonials will be saved (default: "Sheet1")
18+
GOOGLE_SHEETS_SHEET_NAME=Sheet1

.eslintrc.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"extends": ["next/core-web-vitals", "next/typescript"],
3+
"rules": {
4+
"@typescript-eslint/no-unused-vars": [
5+
"warn",
6+
{
7+
"argsIgnorePattern": "^_",
8+
"varsIgnorePattern": "^_"
9+
}
10+
],
11+
"@typescript-eslint/no-explicit-any": "warn",
12+
"prefer-const": "error",
13+
"no-console": ["warn", { "allow": ["warn", "error"] }]
14+
}
15+
}

.github/workflows/ci.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main, develop]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
lint-and-type-check:
15+
name: Lint & Type Check
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Checkout code
20+
uses: actions/checkout@v4
21+
22+
- name: Setup Bun
23+
uses: oven-sh/setup-bun@v2
24+
with:
25+
bun-version: latest
26+
27+
- name: Install dependencies
28+
run: bun install --frozen-lockfile
29+
30+
- name: Run ESLint
31+
run: bun run lint
32+
33+
- name: Run TypeScript
34+
run: bun run type-check
35+
36+
- name: Check Prettier formatting
37+
run: bun run format:check
38+
39+
build:
40+
name: Build
41+
runs-on: ubuntu-latest
42+
needs: lint-and-type-check
43+
44+
steps:
45+
- name: Checkout code
46+
uses: actions/checkout@v4
47+
48+
- name: Setup Bun
49+
uses: oven-sh/setup-bun@v2
50+
with:
51+
bun-version: latest
52+
53+
- name: Install dependencies
54+
run: bun install --frozen-lockfile
55+
56+
- name: Build application
57+
run: bun run build
58+
env:
59+
GOOGLE_SHEETS_CLIENT_EMAIL: ${{ secrets.GOOGLE_SHEETS_CLIENT_EMAIL }}
60+
GOOGLE_SHEETS_PRIVATE_KEY: ${{ secrets.GOOGLE_SHEETS_PRIVATE_KEY }}
61+
GOOGLE_SHEETS_SPREADSHEET_ID: ${{ secrets.GOOGLE_SHEETS_SPREADSHEET_ID }}
62+
GOOGLE_SHEETS_SHEET_NAME: ${{ secrets.GOOGLE_SHEETS_SHEET_NAME }}
63+
64+
- name: Upload build artifacts
65+
uses: actions/upload-artifact@v4
66+
with:
67+
name: build-output
68+
path: .next
69+
retention-days: 7
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: Deploy Preview
2+
3+
on:
4+
pull_request:
5+
branches: [main]
6+
7+
jobs:
8+
deploy-preview:
9+
name: Deploy to Vercel Preview
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v4
15+
16+
- name: Setup Bun
17+
uses: oven-sh/setup-bun@v2
18+
with:
19+
bun-version: latest
20+
21+
- name: Install Vercel CLI
22+
run: bun add -g vercel
23+
24+
- name: Pull Vercel Environment
25+
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
26+
27+
- name: Build Project
28+
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
29+
30+
- name: Deploy to Vercel
31+
id: deploy
32+
run: |
33+
url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
34+
echo "url=$url" >> $GITHUB_OUTPUT
35+
36+
- name: Comment PR
37+
uses: actions/github-script@v7
38+
with:
39+
script: |
40+
github.rest.issues.createComment({
41+
issue_number: context.issue.number,
42+
owner: context.repo.owner,
43+
repo: context.repo.repo,
44+
body: '✅ Preview deployed to: ${{ steps.deploy.outputs.url }}'
45+
})

.gitignore

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# Dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.*
7+
8+
# Testing
9+
/coverage
10+
*.lcov
11+
12+
# Next.js
13+
/.next/
14+
/out/
15+
16+
# Production
17+
/build
18+
/dist
19+
20+
# Debug
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
24+
.pnpm-debug.log*
25+
bun-debug.log*
26+
27+
# Environment files
28+
.env*
29+
!.env.local.example
30+
!.env.example
31+
32+
# Vercel
33+
.vercel
34+
.vercel.json
35+
36+
# TypeScript
37+
*.tsbuildinfo
38+
next-env.d.ts
39+
40+
# IDE
41+
.vscode/*
42+
!.vscode/settings.json
43+
!.vscode/tasks.json
44+
!.vscode/launch.json
45+
!.vscode/extensions.json
46+
.idea
47+
*.swp
48+
*.swo
49+
*~
50+
.DS_Store
51+
52+
# Misc
53+
.cache
54+
.temp
55+
.tmp

.prettierignore

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Dependencies
2+
node_modules
3+
.pnp
4+
.pnp.*
5+
6+
# Build outputs
7+
.next
8+
out
9+
build
10+
dist
11+
12+
# Cache
13+
.cache
14+
*.tsbuildinfo
15+
16+
# Logs
17+
*.log
18+
19+
# Lock files
20+
bun.lock
21+
package-lock.json
22+
yarn.lock
23+
pnpm-lock.yaml

.prettierrc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"semi": false,
3+
"singleQuote": true,
4+
"tabWidth": 2,
5+
"trailingComma": "es5",
6+
"printWidth": 100,
7+
"arrowParens": "avoid",
8+
"endOfLine": "lf",
9+
"plugins": ["prettier-plugin-tailwindcss"]
10+
}

0 commit comments

Comments
 (0)