Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions GEMINI.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Project Guidelines & Automated Checks

## Formatting and Linting
When asked to fix or check formatting/linting issues, or before committing code changes, always run the automated fix commands directly instead of manually inspecting and fixing errors one by one:

```bash
npm run format && composer lint && npm run lint
```
2 changes: 1 addition & 1 deletion app/Http/Controllers/Admin/EmailController.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function store(Request $request): RedirectResponse

foreach ($rawLines as $line) {
$email = strtolower(trim($line));
if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
if (! empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$cleanedEmails[$email] = true;
}
}
Expand Down
15 changes: 8 additions & 7 deletions resources/js/components/NotificationDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,14 @@ const handleScroll = (e: Event) => {
return;
}

// Ignore scroll events originating from inside the dropdown itself (e.g. scrolling the notification items)
if (
dropdownRef.value &&
e.target instanceof Node &&
dropdownRef.value.contains(e.target)
) {
return;
// Ignore scroll events originating from inside the dropdown or panel itself (e.g. scrolling the notification items)
if (e.target instanceof Node) {
if (
(dropdownRef.value && dropdownRef.value.contains(e.target)) ||
(panelRef.value && panelRef.value.contains(e.target))
) {
return;
}
}

closeDropdown();
Expand Down
19 changes: 15 additions & 4 deletions resources/js/pages/admin/EmailSend.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
import { computed, onBeforeUnmount, onMounted, ref } from 'vue';
import HTMLEditor from '@/components/HTMLEditor.vue';

const props = defineProps({
defineProps({
recipientCount: {
type: Number,
default: 0,
Expand Down Expand Up @@ -87,6 +87,7 @@ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

const recipientStats = computed(() => {
const raw = form.recipients.trim();

if (!raw) {
return {
validEmails: [] as string[],
Expand All @@ -107,6 +108,7 @@ const recipientStats = computed(() => {

for (const token of tokens) {
const lower = token.toLowerCase();

if (emailRegex.test(lower)) {
if (seen.has(lower)) {
duplicateCount++;
Expand Down Expand Up @@ -148,7 +150,10 @@ const handleRemoveImage = () => {

// Import helper
const importSubscribers = async (type: 'all' | 'students' | 'staff') => {
if (isImporting.value) return;
if (isImporting.value) {
return;
}

isImporting.value = true;
isImportDropdownOpen.value = false;

Expand Down Expand Up @@ -191,11 +196,13 @@ const handleSendClick = () => {
'recipients',
'Please provide at least one valid recipient email.',
);

return;
}

if (!form.subject.trim() || !form.body.trim()) {
form.validate();

return;
}

Expand Down Expand Up @@ -333,7 +340,9 @@ const submitForm = () => {
class="flex w-full items-center justify-between rounded-xl px-3 py-2 text-left text-xs font-semibold text-slate-700 transition hover:bg-indigo-50 hover:text-indigo-600 disabled:cursor-not-allowed disabled:opacity-50 dark:text-gray-200 dark:hover:bg-indigo-950/40 dark:hover:text-indigo-400"
>
<div class="flex items-center gap-2">
<Users class="h-4 w-4 text-indigo-500" />
<Users
class="h-4 w-4 text-indigo-500"
/>
<span>All Subscribed</span>
</div>
<span
Expand Down Expand Up @@ -449,7 +458,9 @@ const submitForm = () => {
>
<AlertCircle class="h-3.5 w-3.5" />
<span
>{{ recipientStats.invalidItems.length }}
>{{
recipientStats.invalidItems.length
}}
invalid ignored</span
>
</span>
Expand Down