mirror of
https://github.com/System-End/scraps.git
synced 2026-04-19 16:28:20 +00:00
PUBLIC RELEASE: add in some checks and readme
This commit is contained in:
parent
b7bae0053b
commit
687735b053
5 changed files with 33 additions and 8 deletions
|
|
@ -1,3 +1,7 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src="frontend/static/icon.png" alt="scraps" width="128" />
|
||||||
|
</p>
|
||||||
|
|
||||||
# scraps
|
# scraps
|
||||||
|
|
||||||
nom nom nom
|
nom nom nom
|
||||||
|
|
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
# scraps backend
|
# scraps backend
|
||||||
|
|
||||||
|
just don't
|
||||||
|
|
|
||||||
|
|
@ -444,6 +444,11 @@ admin.post('/reviews/:id', async ({ params, body, headers }) => {
|
||||||
|
|
||||||
if (!project[0]) return { error: 'Project not found' }
|
if (!project[0]) return { error: 'Project not found' }
|
||||||
|
|
||||||
|
// Validate hours override doesn't exceed project hours
|
||||||
|
if (hoursOverride !== undefined && hoursOverride > (project[0].hours ?? 0)) {
|
||||||
|
return { error: `Hours override (${hoursOverride}) cannot exceed project hours (${project[0].hours})` }
|
||||||
|
}
|
||||||
|
|
||||||
// Reject if project is deleted or not waiting for review
|
// Reject if project is deleted or not waiting for review
|
||||||
if (project[0].deleted) {
|
if (project[0].deleted) {
|
||||||
return { error: 'Cannot review a deleted project' }
|
return { error: 'Cannot review a deleted project' }
|
||||||
|
|
|
||||||
3
frontend/README.md
Normal file
3
frontend/README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
# scraps frontend
|
||||||
|
|
||||||
|
at least it's not rails
|
||||||
|
|
@ -72,6 +72,12 @@
|
||||||
let hoursOverride = $state<number | undefined>(undefined)
|
let hoursOverride = $state<number | undefined>(undefined)
|
||||||
let tierOverride = $state<number | undefined>(undefined)
|
let tierOverride = $state<number | undefined>(undefined)
|
||||||
|
|
||||||
|
let hoursOverrideError = $derived(
|
||||||
|
hoursOverride !== undefined && project && hoursOverride > project.hours
|
||||||
|
? `Hours override cannot exceed project hours (${project.hours}h)`
|
||||||
|
: null
|
||||||
|
)
|
||||||
|
|
||||||
let confirmAction = $state<'approved' | 'denied' | 'permanently_rejected' | null>(null)
|
let confirmAction = $state<'approved' | 'denied' | 'permanently_rejected' | null>(null)
|
||||||
|
|
||||||
let projectId = $derived(page.params.id)
|
let projectId = $derived(page.params.id)
|
||||||
|
|
@ -421,10 +427,15 @@
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
step="0.1"
|
step="0.1"
|
||||||
|
min="0"
|
||||||
|
max={project.hours}
|
||||||
bind:value={hoursOverride}
|
bind:value={hoursOverride}
|
||||||
placeholder={String(project.hours)}
|
placeholder={String(project.hours)}
|
||||||
class="w-full px-4 py-2 border-2 border-black rounded-lg focus:outline-none focus:border-dashed"
|
class="w-full px-4 py-2 border-2 rounded-lg focus:outline-none focus:border-dashed {hoursOverrideError ? 'border-red-500' : 'border-black'}"
|
||||||
/>
|
/>
|
||||||
|
{#if hoursOverrideError}
|
||||||
|
<p class="text-red-500 text-sm mt-1">{hoursOverrideError}</p>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -465,24 +476,24 @@
|
||||||
<div class="flex gap-3 pt-4">
|
<div class="flex gap-3 pt-4">
|
||||||
<button
|
<button
|
||||||
onclick={() => requestConfirmation('approved')}
|
onclick={() => requestConfirmation('approved')}
|
||||||
disabled={submitting}
|
disabled={submitting || !!hoursOverrideError}
|
||||||
class="flex-1 px-4 py-3 bg-green-600 text-white rounded-full font-bold border-4 border-black hover:border-dashed transition-all duration-200 disabled:opacity-50 flex items-center justify-center gap-2 cursor-pointer"
|
class="flex-1 px-4 py-3 bg-green-600 text-white rounded-full font-bold border-4 border-black hover:border-dashed transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 cursor-pointer"
|
||||||
>
|
>
|
||||||
<Check size={20} />
|
<Check size={20} />
|
||||||
<span>approve</span>
|
<span>approve</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onclick={() => requestConfirmation('denied')}
|
onclick={() => requestConfirmation('denied')}
|
||||||
disabled={submitting}
|
disabled={submitting || !!hoursOverrideError}
|
||||||
class="flex-1 px-4 py-3 bg-yellow-500 text-white rounded-full font-bold border-4 border-black hover:border-dashed transition-all duration-200 disabled:opacity-50 flex items-center justify-center gap-2 cursor-pointer"
|
class="flex-1 px-4 py-3 bg-yellow-500 text-white rounded-full font-bold border-4 border-black hover:border-dashed transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 cursor-pointer"
|
||||||
>
|
>
|
||||||
<X size={20} />
|
<X size={20} />
|
||||||
<span>reject</span>
|
<span>reject</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onclick={() => requestConfirmation('permanently_rejected')}
|
onclick={() => requestConfirmation('permanently_rejected')}
|
||||||
disabled={submitting}
|
disabled={submitting || !!hoursOverrideError}
|
||||||
class="flex-1 px-4 py-3 bg-red-600 text-white rounded-full font-bold border-4 border-black hover:border-dashed transition-all duration-200 disabled:opacity-50 flex items-center justify-center gap-2 cursor-pointer"
|
class="flex-1 px-4 py-3 bg-red-600 text-white rounded-full font-bold border-4 border-black hover:border-dashed transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 cursor-pointer"
|
||||||
>
|
>
|
||||||
<Ban size={20} />
|
<Ban size={20} />
|
||||||
<span>permanently reject</span>
|
<span>permanently reject</span>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue