Skip to content

Commit 36e6b7e

Browse files
committed
- grammar check v0.5
1 parent cb56b5a commit 36e6b7e

File tree

1 file changed

+72
-55
lines changed

1 file changed

+72
-55
lines changed

tools/grammar_check.html

Lines changed: 72 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<meta name="viewport" content="width=device-width,initial-scale=1.0">
88
<script src="https://cdn.tailwindcss.com"></script>
99
<script src="https://cdnjs.cloudflare.com/ajax/libs/json5/2.2.3/index.min.js"></script>
10-
<title>Grammar Checker</title>
10+
<title>GrammarPro</title>
1111
<style>.error-highlight {
1212
position: relative;
1313
display: inline-block;
@@ -82,76 +82,93 @@
8282
20%, 40%, 60%, 80% {
8383
transform: translateX(5px);
8484
}
85+
}
86+
87+
.fade-in {
88+
animation: fadeIn 0.3s ease-in;
89+
}
90+
91+
@keyframes fadeIn {
92+
from {
93+
opacity: 0;
94+
}
95+
to {
96+
opacity: 1;
97+
}
8598
}</style>
8699
</head>
87-
<body class="bg-gray-100 flex justify-center items-center min-h-screen">
88-
<div class="container mx-auto max-w-4xl p-5 bg-white rounded-lg shadow-lg">
89-
<div class="flex items-center justify-between mb-6"><h1 class="text-3xl font-bold">Grammar Checker</h1>
90-
<div class="flex gap-2"><select id="mode-select" class="px-3 py-1 border rounded-md text-sm dark:text-gray-900">
100+
<body class="bg-gray-100 dark:bg-gray-900 transition-colors duration-200">
101+
<div class="container mx-auto max-w-4xl p-5 bg-white dark:bg-gray-800 rounded-lg shadow-lg transition-colors duration-200">
102+
<div class="flex items-center justify-between mb-6">
103+
<div class="flex items-center gap-2"><h1
104+
class="text-3xl font-bold bg-gradient-to-r from-indigo-600 to-purple-600 text-transparent bg-clip-text dark:from-indigo-400 dark:to-purple-400">
105+
GrammarPro</h1><span
106+
class="px-2 py-1 text-xs font-medium bg-indigo-100 text-indigo-800 rounded-full dark:bg-indigo-900 dark:text-indigo-200">Beta</span>
107+
</div>
108+
<select id="mode-select"
109+
class="px-3 py-1 border rounded-md text-sm bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 border-gray-300 dark:border-gray-600 focus:ring-2 focus:ring-indigo-500 dark:focus:ring-indigo-400 transition-colors duration-200">
91110
<option value="standard">Standard Mode</option>
92111
<option value="academic">Academic Writing</option>
93112
<option value="business">Business Writing</option>
94113
<option value="casual">Casual Writing</option>
95-
</select>
96-
<button id="theme-toggle" class="p-2 rounded-md bg-gray-200 hover:bg-gray-300">🌙</button>
97-
</div>
98-
</div>
99-
<div class="mb-4">
100-
<div class="flex justify-between items-center mb-2"><label for="input"
101-
class="block text-sm font-medium text-gray-700 dark:text-gray-300">Enter
114+
</select></div>
115+
<div class="mb-4 space-y-2">
116+
<div class="flex justify-between items-center"><label for="input"
117+
class="block text-sm font-medium text-gray-700 dark:text-gray-300">Enter
102118
Text:</label>
103-
<div id="word-count" class="text-sm text-gray-500 dark:text-gray-400">0 words | 0 characters</div>
119+
<div id="word-count" class="text-sm text-gray-500 dark:text-gray-400 font-mono">0 words | 0 characters</div>
104120
</div>
105121
<textarea id="input" rows="6"
106-
class="w-full p-3 border rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:text-gray-900"
107-
placeholder="Type or paste your text here..."></textarea></div>
108-
<div class="flex flex-wrap gap-4 mb-6">
109-
<button id="check-grammar"
110-
class="px-6 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500">
111-
Check Grammar
112-
</button>
113-
<button id="clear-text"
114-
class="px-6 py-2 bg-gray-600 text-white rounded-md hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500">
115-
Clear Text
116-
</button>
117-
<button id="copy-corrected"
118-
class="px-6 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500">
119-
Copy Corrected
120-
</button>
122+
class="w-full p-3 border rounded-md shadow-sm focus:border-indigo-500 focus:ring-indigo-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 border-gray-300 dark:border-gray-600 transition-colors duration-200 resize-y"
123+
placeholder="Type or paste your text here..."></textarea>
124+
<div class="flex flex-wrap gap-3">
125+
<button id="check-grammar"
126+
class="px-4 py-2 bg-gradient-to-r from-indigo-600 to-purple-600 hover:from-indigo-700 hover:to-purple-700 text-white rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 transition-all duration-200 flex items-center gap-2">
127+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
128+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
129+
d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
130+
</svg>
131+
Check Grammar
132+
</button>
133+
<button id="clear-text"
134+
class="px-4 py-2 bg-gray-600 hover:bg-gray-700 text-white rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 transition-colors duration-200 flex items-center gap-2">
135+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
136+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
137+
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"></path>
138+
</svg>
139+
Clear
140+
</button>
141+
<button id="copy-corrected"
142+
class="px-4 py-2 bg-green-600 hover:bg-green-700 text-white rounded-md focus:outline-none focus:ring-2 focus:ring-green-500 transition-colors duration-200 flex items-center gap-2">
143+
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
144+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
145+
d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"></path>
146+
</svg>
147+
Copy
148+
</button>
149+
</div>
121150
</div>
122-
<div id="result" class="p-4 border rounded-md min-h-[100px] bg-gray-50 dark:bg-gray-800 dark:text-white"></div>
123-
<div id="history" class="mt-4"><h3 class="text-lg font-semibold mb-2 dark:text-white">Recent Corrections</h3>
151+
<div id="result"
152+
class="p-4 border rounded-md min-h-[100px] bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-gray-100 border-gray-300 dark:border-gray-600 transition-colors duration-200"></div>
153+
<div id="history" class="mt-4 space-y-2">
154+
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100 flex items-center gap-2">
155+
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
156+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
157+
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
158+
</svg>
159+
Recent Corrections
160+
</h3>
124161
<div id="history-list" class="space-y-2"></div>
125162
</div>
126163
</div>
127-
<script>let darkMode = false;
128-
let errorHistory = [];
164+
<script>let errorHistory = [];
129165
let currentText = '';
130166
let lastCheckTimestamp = 0;
131-
document.getElementById('theme-toggle').addEventListener('click', toggleTheme);
132167
document.getElementById('check-grammar').addEventListener('click', checkGrammar);
133168
document.getElementById('clear-text').addEventListener('click', clearText);
134169
document.getElementById('copy-corrected').addEventListener('click', copyCorrectText);
135170
document.getElementById('input').addEventListener('input', updateWordCount);
136171

137-
function toggleTheme() {
138-
darkMode = !darkMode;
139-
const body = document.body;
140-
const container = document.querySelector('.container');
141-
const themeToggle = document.getElementById('theme-toggle');
142-
if (darkMode) {
143-
body.classList.add('bg-gray-900');
144-
container.classList.remove('bg-white');
145-
container.classList.add('bg-gray-800');
146-
themeToggle.textContent = '☀️';
147-
} else {
148-
body.classList.remove('bg-gray-900');
149-
container.classList.remove('bg-gray-800');
150-
container.classList.add('bg-white');
151-
themeToggle.textContent = '🌙';
152-
}
153-
}
154-
155172
function updateWordCount() {
156173
const text = document.getElementById('input').value;
157174
const words = text.trim().split(/\s+/).filter(word => word.length > 0).length;
@@ -180,7 +197,7 @@
180197

181198
function showNotification(message, type = 'success') {
182199
const notification = document.createElement('div');
183-
notification.className = `fixed top-4 right-4 p-4 rounded-md ${type === 'success' ? 'bg-green-500' : 'bg-red-500'} text-white`;
200+
notification.className = `fixed top-4 right-4 p-4 rounded-md ${type === 'success' ? 'bg-green-500' : 'bg-red-500'} text-white fade-in`;
184201
notification.textContent = message;
185202
document.body.appendChild(notification);
186203
setTimeout(() => notification.remove(), 3000);
@@ -204,7 +221,7 @@
204221
return;
205222
}
206223
button.disabled = true;
207-
button.innerHTML = 'Checking<span class="loading-dots"></span>';
224+
button.innerHTML = '<svg class="animate-spin h-4 w-4 mr-2" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>Checking';
208225
const botMessage = `I am a grammar checking API. I analyze text for grammar errors with a focus on ${mode} writing. I always respond in this JSON format:{"errors":[{"type":"grammar","text":"original text","suggestion":"suggested correction","description":"error description"}]}`;
209226
try {
210227
const response = await fetch('https://chatgpt.tobiasmue91.workers.dev/', {
@@ -234,7 +251,7 @@
234251
showNotification('Error checking grammar', 'error');
235252
} finally {
236253
button.disabled = false;
237-
button.textContent = 'Check Grammar';
254+
button.innerHTML = '<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg>Check Grammar';
238255
}
239256
}
240257

@@ -247,7 +264,7 @@
247264

248265
function updateHistoryDisplay() {
249266
const historyList = document.getElementById('history-list');
250-
historyList.innerHTML = errorHistory.map((entry, index) => `<div class="p-2 bg-gray-50 dark:bg-gray-700 rounded border cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600" onclick="restoreHistoryEntry(${index})"><div class="text-sm text-gray-500 dark:text-gray-300">${entry.timestamp}</div><div class="text-sm truncate dark:text-white">${entry.text.substring(0, 50)}...</div><div class="text-xs text-gray-600 dark:text-gray-400">${entry.errors.length} errors found</div></div>`).join('');
267+
historyList.innerHTML = errorHistory.map((entry, index) => `<div class="p-3 bg-gray-50 dark:bg-gray-700 rounded-lg border border-gray-200 dark:border-gray-600 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors duration-200 group" onclick="restoreHistoryEntry(${index})"><div class="flex justify-between items-center"><div class="text-sm text-gray-500 dark:text-gray-400">${entry.timestamp}</div><div class="text-xs px-2 py-1 bg-indigo-100 dark:bg-indigo-900 text-indigo-800 dark:text-indigo-200 rounded-full">${entry.errors.length} errors</div></div><div class="text-sm text-gray-900 dark:text-gray-100 mt-1 truncate">${entry.text.substring(0, 50)}...</div><div class="text-xs text-gray-500 dark:text-gray-400 mt-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200">Click to restore</div></div>`).join('');
251268
}
252269

253270
function restoreHistoryEntry(index) {

0 commit comments

Comments
 (0)