├── .gitignore ├── README.md ├── app ├── favicon.ico ├── fonts │ ├── GeistMonoVF.woff │ └── GeistVF.woff ├── globals.css ├── layout.tsx └── page.tsx ├── components.json ├── components ├── CommitForm.tsx ├── CopyButton.tsx ├── DescriptionInput.tsx ├── GuideContent.tsx ├── PreviewBox.tsx ├── ScopeInput.tsx ├── ThemeToggle.tsx ├── TypeSelector.tsx ├── theme-provider.tsx └── ui │ ├── background-paths.tsx │ ├── button.tsx │ ├── card.tsx │ ├── input.tsx │ ├── label.tsx │ ├── select.tsx │ ├── tabs.tsx │ └── textarea.tsx ├── lib ├── generateCommitMessage.ts ├── schemas │ └── commit-form-schema.ts └── utils.ts ├── next.config.mjs ├── package-lock.json ├── package.json ├── postcss.config.mjs ├── tailwind.config.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Commit Mesaj Yardımcısı 2 | 3 | Conventional Commits standartlarına uygun commit mesajları oluşturmanıza yardımcı olan modern bir web uygulaması. 4 | 5 | ## Özellikler 6 | 7 | - 🎨 Modern ve minimalist tasarım 8 | - 🌓 Koyu/açık tema desteği 9 | - ⚡ Hızlı ve kullanıcı dostu arayüz 10 | - 📝 Conventional Commits rehberi 11 | - 🔍 Anlık commit mesajı önizleme 12 | - 🎯 Doğru commit türü seçimi için yönlendirme 13 | 14 | ## Teknolojiler 15 | 16 | - [Next.js](https://nextjs.org/) 17 | - [React](https://reactjs.org/) 18 | - [Tailwind CSS](https://tailwindcss.com/) 19 | - [React Hook Form](https://react-hook-form.com/) 20 | - [Zod](https://zod.dev/) 21 | 22 | ## Başlangıç 23 | 24 | Projeyi yerel ortamınızda çalıştırmak için: 25 | 26 | ```bash 27 | # Repoyu klonlayın 28 | git clone https://github.com/gamzesirin/commit-message-helper.git 29 | 30 | # Proje dizinine gidin 31 | cd commit-message-helper 32 | 33 | # Bağımlılıkları yükleyin 34 | npm install 35 | 36 | # Geliştirme sunucusunu başlatın 37 | npm run dev 38 | ``` 39 | 40 | Tarayıcınızda [http://localhost:3000](http://localhost:3000) adresini açarak uygulamayı görüntüleyebilirsiniz. 41 | 42 | ## Kullanım 43 | 44 | 1. Ana sayfada "Get Started" butonuna tıklayın 45 | 2. "Kılavuz" sekmesinden Conventional Commits hakkında bilgi alın 46 | 3. "Commit Oluştur" sekmesinde: 47 | - Commit türünü seçin 48 | - Kapsamı (scope) belirtin 49 | - Açıklama yazın 50 | - Detaylı açıklama ekleyin (opsiyonel) 51 | 52 | ## Katkıda Bulunma 53 | 54 | 1. Bu repoyu fork edin 55 | 2. Yeni bir branch oluşturun (`git checkout -b feature/yeniOzellik`) 56 | 3. Değişikliklerinizi commit edin (`git commit -am 'Yeni özellik: Açıklama'`) 57 | 4. Branch'inizi push edin (`git push origin feature/yeniOzellik`) 58 | 5. Pull Request oluşturun 59 | 60 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamzesirin/Commit-Message-Helper/df731cd7e76a28ae1d15bc1504568c8bfba965bc/app/favicon.ico -------------------------------------------------------------------------------- /app/fonts/GeistMonoVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamzesirin/Commit-Message-Helper/df731cd7e76a28ae1d15bc1504568c8bfba965bc/app/fonts/GeistMonoVF.woff -------------------------------------------------------------------------------- /app/fonts/GeistVF.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gamzesirin/Commit-Message-Helper/df731cd7e76a28ae1d15bc1504568c8bfba965bc/app/fonts/GeistVF.woff -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer utilities { 6 | .text-balance { 7 | text-wrap: balance; 8 | } 9 | } 10 | 11 | @layer base { 12 | :root { 13 | --background: 0 0% 100%; 14 | --foreground: 0 0% 3.9%; 15 | --card: 0 0% 100%; 16 | --card-foreground: 0 0% 3.9%; 17 | --popover: 0 0% 100%; 18 | --popover-foreground: 0 0% 3.9%; 19 | --primary: 0 0% 9%; 20 | --primary-foreground: 0 0% 98%; 21 | --secondary: 0 0% 96.1%; 22 | --secondary-foreground: 0 0% 9%; 23 | --muted: 0 0% 96.1%; 24 | --muted-foreground: 0 0% 45.1%; 25 | --accent: 0 0% 96.1%; 26 | --accent-foreground: 0 0% 9%; 27 | --destructive: 0 84.2% 60.2%; 28 | --destructive-foreground: 0 0% 98%; 29 | --border: 0 0% 89.8%; 30 | --input: 0 0% 89.8%; 31 | --ring: 0 0% 3.9%; 32 | --chart-1: 12 76% 61%; 33 | --chart-2: 173 58% 39%; 34 | --chart-3: 197 37% 24%; 35 | --chart-4: 43 74% 66%; 36 | --chart-5: 27 87% 67%; 37 | --radius: 0.5rem; 38 | } 39 | .dark { 40 | --background: 0 0% 3.9%; 41 | --foreground: 0 0% 98%; 42 | --card: 0 0% 3.9%; 43 | --card-foreground: 0 0% 98%; 44 | --popover: 0 0% 3.9%; 45 | --popover-foreground: 0 0% 98%; 46 | --primary: 0 0% 98%; 47 | --primary-foreground: 0 0% 9%; 48 | --secondary: 0 0% 14.9%; 49 | --secondary-foreground: 0 0% 98%; 50 | --muted: 0 0% 14.9%; 51 | --muted-foreground: 0 0% 63.9%; 52 | --accent: 0 0% 14.9%; 53 | --accent-foreground: 0 0% 98%; 54 | --destructive: 0 62.8% 30.6%; 55 | --destructive-foreground: 0 0% 98%; 56 | --border: 0 0% 14.9%; 57 | --input: 0 0% 14.9%; 58 | --ring: 0 0% 83.1%; 59 | --chart-1: 220 70% 50%; 60 | --chart-2: 160 60% 45%; 61 | --chart-3: 30 80% 55%; 62 | --chart-4: 280 65% 60%; 63 | --chart-5: 340 75% 55%; 64 | } 65 | } 66 | 67 | @layer base { 68 | * { 69 | @apply border-border; 70 | } 71 | body { 72 | @apply bg-background text-foreground; 73 | } 74 | } 75 | 76 | /* Prose stilleri için özelleştirmeler */ 77 | .prose { 78 | @apply text-foreground; 79 | } 80 | 81 | .prose code { 82 | @apply bg-muted/50 rounded px-1 py-0.5; 83 | } 84 | 85 | .prose pre { 86 | @apply bg-muted/50 rounded-lg p-4; 87 | } 88 | 89 | .prose pre code { 90 | @apply bg-transparent p-0; 91 | } 92 | 93 | .prose strong { 94 | @apply text-foreground; 95 | } 96 | 97 | .prose h2, 98 | .prose h3 { 99 | @apply text-foreground; 100 | } 101 | 102 | /* Tabs için özel stiller */ 103 | @layer components { 104 | /* Scrollbar stilleri */ 105 | .custom-scrollbar { 106 | scrollbar-width: thin; 107 | scrollbar-color: rgba(155, 155, 155, 0.3) transparent; 108 | } 109 | 110 | .custom-scrollbar::-webkit-scrollbar { 111 | width: 6px; 112 | } 113 | 114 | .custom-scrollbar::-webkit-scrollbar-track { 115 | background: transparent; 116 | } 117 | 118 | .custom-scrollbar::-webkit-scrollbar-thumb { 119 | background-color: rgba(155, 155, 155, 0.3); 120 | border-radius: 20px; 121 | border: transparent; 122 | } 123 | 124 | /* Dark mode için özel scrollbar stilleri */ 125 | .dark .custom-scrollbar { 126 | scrollbar-color: rgba(255, 255, 255, 0.1) transparent; 127 | } 128 | 129 | .dark .custom-scrollbar::-webkit-scrollbar-thumb { 130 | background-color: rgba(255, 255, 255, 0.1); 131 | } 132 | 133 | .dark .custom-scrollbar::-webkit-scrollbar-track { 134 | background: transparent; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next' 2 | import { Inter } from 'next/font/google' 3 | import './globals.css' 4 | import { ThemeProvider } from '@/components/theme-provider' 5 | 6 | const inter = Inter({ subsets: ['latin'] }) 7 | 8 | export const metadata: Metadata = { 9 | title: 'Commit Mesaj Yardımcısı', 10 | description: 'Conventional Commits standartlarına uygun commit mesajları oluşturun' 11 | } 12 | 13 | export default function RootLayout({ children }: { children: React.ReactNode }) { 14 | return ( 15 | 16 | 17 | 18 | {children} 19 | 20 | 21 | 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /app/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useState } from 'react' 4 | import { ThemeToggle } from '@/components/ThemeToggle' 5 | import { BackgroundPaths } from '@/components/ui/background-paths' 6 | import { motion } from 'framer-motion' 7 | import { CommitForm } from '@/components/CommitForm' 8 | import { Card, CardContent } from '@/components/ui/card' 9 | import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs' 10 | 11 | export default function Home() { 12 | const [isStarted, setIsStarted] = useState(false) 13 | 14 | if (!isStarted) { 15 | return setIsStarted(true)} /> 16 | } 17 | 18 | return ( 19 | 20 | 25 |
26 |
27 | 28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | Kılavuz 37 | 38 | 39 | Commit Oluştur 40 | 41 | 42 | 43 |
44 | 45 |
46 |

Conventional Commits Nedir?

47 |

48 | Conventional Commits, commit mesajları için standart bir format sağlayan spesifikasyondur. Bu 49 | format sayesinde otomatik sürüm yönetimi ve değişiklik günlükleri (CHANGELOG) oluşturmak mümkün 50 | olur. 51 |

52 | 53 |

Neden Kullanmalıyız?

54 |
    55 |
  • Otomatik sürüm numarası belirleme
  • 56 |
  • Otomatik CHANGELOG oluşturma
  • 57 |
  • Tutarlı commit geçmişi
  • 58 |
  • Kolay kod inceleme süreci
  • 59 |
60 | 61 |

Commit Mesaj Yapısı

62 |

Commit Mesaj Yapısı

63 |
 64 | 											{`[optional scope]: 
 65 | 
 66 | [optional body]
 67 | 
 68 | [optional footer(s)]`}
 69 | 										
70 | 71 |

Commit Türleri

72 |
    73 |
  • 74 | feat: Yeni bir özellik eklendiğinde 75 |
  • 76 |
  • 77 | fix: Bir hata düzeltildiğinde 78 |
  • 79 |
  • 80 | docs: Sadece dokümantasyon değişikliklerinde 81 |
  • 82 |
  • 83 | style: Kod formatı değişikliklerinde (boşluk, noktalama vb.) 84 |
  • 85 |
  • 86 | refactor: Kod yeniden düzenlendiğinde 87 |
  • 88 |
  • 89 | perf: Performans iyileştirmelerinde 90 |
  • 91 |
  • 92 | test: Test eklendiğinde veya düzeltildiğinde 93 |
  • 94 |
  • 95 | build: Build sistemini etkileyen değişikliklerde 96 |
  • 97 |
  • 98 | ci: CI konfigürasyonlarında değişiklik 99 |
  • 100 |
  • 101 | chore: Diğer değişiklikler 102 |
  • 103 |
104 | 105 |

Detaylı Örnekler

106 |
107 |
108 |

109 | feat: (kullanıcı için yeni özellik) 110 |

111 | feat(auth): kullanıcı girişi özelliği eklendi 112 |
113 | 114 |
115 |

116 | fix: (kullanıcı için hata düzeltmesi) 117 |

118 | fix(api): kullanıcı verisi çekme hatası giderildi 119 |
120 | 121 |
122 |

123 | docs: (dokümantasyon değişiklikleri) 124 |

125 | docs: kurulum adımları güncellendi 126 |
127 | 128 |
129 |

130 | style: (biçimlendirme, noktalı virgül eksikleri vb.; üretim kodu değişikliği 131 | yok) 132 |

133 | style: kod formatı düzenlendi 134 |
135 | 136 |
137 |

138 | refactor: (üretim kodunun yeniden düzenlenmesi, örn. değişken yeniden 139 | adlandırma) 140 |

141 | refactor(user): değişken isimleri düzenlendi 142 |
143 | 144 |
145 |

146 | test: (eksik testlerin eklenmesi, testlerin yeniden düzenlenmesi) 147 |

148 | test: kullanıcı girişi testleri eklendi 149 |
150 | 151 |
152 |

153 | chore: (görev güncellemeleri vb.) 154 |

155 | chore: paket bağımlılıkları güncellendi 156 |
157 |
158 |
159 |
160 | 161 | 162 | 163 | 164 |
165 |
166 |
167 |
168 |
169 |
170 | ) 171 | } 172 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "new-york", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils", 16 | "ui": "@/components/ui", 17 | "lib": "@/lib", 18 | "hooks": "@/hooks" 19 | }, 20 | "iconLibrary": "lucide" 21 | } -------------------------------------------------------------------------------- /components/CommitForm.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useForm } from 'react-hook-form' 4 | import { zodResolver } from '@hookform/resolvers/zod' 5 | import { commitFormSchema, type CommitFormData, commitTypeEnum } from '@/lib/schemas/commit-form-schema' 6 | import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' 7 | import { Input } from '@/components/ui/input' 8 | import { Textarea } from '@/components/ui/textarea' 9 | import { Label } from '@/components/ui/label' 10 | import { PreviewBox } from '@/components/PreviewBox' 11 | import { CopyButton } from '@/components/CopyButton' 12 | import { generateCommitMessage } from '@/lib/generateCommitMessage' 13 | 14 | export function CommitForm() { 15 | const { 16 | watch, 17 | setValue, 18 | formState: { errors, touchedFields } 19 | } = useForm({ 20 | resolver: zodResolver(commitFormSchema), 21 | mode: 'onTouched', 22 | defaultValues: { 23 | type: undefined, 24 | scope: '', 25 | description: '', 26 | body: '', 27 | footer: '' 28 | }, 29 | reValidateMode: 'onChange' 30 | }) 31 | 32 | const formValues = watch() 33 | const commitMessage = generateCommitMessage(formValues) 34 | 35 | const isRequiredFieldsFilled = Boolean(formValues.type && formValues.scope && formValues.description) 36 | 37 | const handleInputChange = 38 | (field: keyof CommitFormData) => (e: React.ChangeEvent) => { 39 | setValue(field, e.target.value, { shouldValidate: true }) 40 | } 41 | 42 | return ( 43 |
44 |
45 |
46 | 50 | 64 | {touchedFields.type && !formValues.type && ( 65 |

Commit türü seçilmesi zorunludur

66 | )} 67 |
68 | 69 |
70 | 74 | 82 | {touchedFields.scope && errors.scope &&

{errors.scope.message}

} 83 |
84 |
85 | 86 |
87 | 91 | 99 | {touchedFields.description && errors.description && ( 100 |

{errors.description.message}

101 | )} 102 |
103 | 104 |
105 | 106 |