Skip to content

DT-17: Create Preact PlatformsPage with DaisyUI table/cards#56

Merged
abdotop merged 4 commits intomasterfrom
17-create-preact-platformspage-with-daisyui-tablecards
Aug 14, 2025
Merged

DT-17: Create Preact PlatformsPage with DaisyUI table/cards#56
abdotop merged 4 commits intomasterfrom
17-create-preact-platformspage-with-daisyui-tablecards

Conversation

@abdotop
Copy link
Member

@abdotop abdotop commented Aug 1, 2025

fead(ProjectsPage.tsx): Add projects page with modal and card components

@abdotop abdotop linked an issue Aug 1, 2025 that may be closed by this pull request
@abdotop abdotop self-assigned this Aug 1, 2025
@abdotop abdotop added the tournament Pull requests that are related to the Tournament team label Aug 1, 2025

export function ProjectsPage() {
const prodOpen = useComputed(() => url.params.prodopen !== 'false')
const devOpen = useComputed(() => url.params.devopen !== 'false')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const devOpen = url.params.devopen !== 'false'

@abdotop abdotop force-pushed the 17-create-preact-platformspage-with-daisyui-tablecards branch from f31b8d2 to 5b2e731 Compare August 4, 2025 11:58
@abdotop abdotop marked this pull request as draft August 4, 2025 17:20
@abdotop abdotop force-pushed the 17-create-preact-platformspage-with-daisyui-tablecards branch 5 times, most recently from 6bf2103 to 6c7d253 Compare August 5, 2025 05:41
@abdotop abdotop force-pushed the 17-create-preact-platformspage-with-daisyui-tablecards branch from 6c7d253 to 8771202 Compare August 5, 2025 05:43
@abdotop abdotop requested a review from Copilot August 5, 2025 05:48
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a comprehensive Projects page with team and project management functionality to a Preact application using DaisyUI components. The implementation includes modal dialogs for CRUD operations, user interface improvements, and database schema updates.

  • Introduces ProjectsPage component with search, filtering, and management capabilities
  • Adds modal dialogs for project creation, team management, and deletion confirmation
  • Updates user schema to include admin privileges and authentication flow

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
web/pages/ProjectsPage.tsx New comprehensive projects page with team/project management, search functionality, and modal dialogs
web/index.tsx Updates main app to render ProjectsPage instead of welcome message
web/components/Dialog.tsx New reusable dialog component with modal functionality
api/user.ts Sets new users as non-admin by default during OAuth authentication
api/schema.ts Adds isAdmin boolean field to user schema

type='button'
onClick={() => openDialog('add-project')}
class='btn btn-primary btn-sm flex items-center gap-1.5'
disabled={teams.value.length > 0 && !user.data?.isAdmin}
Copy link

Copilot AI Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for disabling the 'Add Project' button is incorrect. It should be disabled when there are no teams OR when the user is not an admin. The current condition teams.value.length > 0 && !user.data?.isAdmin will disable the button only when there are teams AND the user is not an admin, but it should also be disabled when there are no teams at all.

Suggested change
disabled={teams.value.length > 0 && !user.data?.isAdmin}
disabled={teams.value.length === 0 || !user.data?.isAdmin}

Copilot uses AI. Check for mistakes.

// valeurs initiales sans useEffect
const name = useSignal(project?.name ?? '')
const teamId = useSignal<number | null>(project?.teamId ?? null) //user.data?.teamIds[0] ?? null
Copy link

Copilot AI Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the commented code //user.data?.teamIds[0] ?? null as it appears to be leftover development code and adds no value to the implementation.

Suggested change
const teamId = useSignal<number | null>(project?.teamId ?? null) //user.data?.teamIds[0] ?? null
const teamId = useSignal<number | null>(project?.teamId ?? null)

Copilot uses AI. Check for mistakes.
Comment on lines +303 to +305
const authorized = true

return (
Copy link

Copilot AI Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The authorized variable is hardcoded to true but appears to be intended for actual authorization logic. This should either implement proper authorization checking or be removed if not needed.

Suggested change
const authorized = true
return (
// User is authorized if they are an admin or belong to the project's team
const authorized =
user.value?.isAdmin ||
(user.value?.teamIds && user.value.teamIds.includes(project.teamId));

Copilot uses AI. Check for mistakes.

function deleteTeam(id: number) {
if (projects.value.some((p) => p.teamId === id)) {
toast('Cannot delete a team that still has projects.')
Copy link

Copilot AI Aug 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toast function is called but not defined in scope. It should be imported or the function call should be qualified with the module it belongs to.

Copilot uses AI. Check for mistakes.
@@ -1,11 +1,12 @@
import { OBJ, optional, STR } from './lib/validator.ts'
import { BOOL, OBJ, optional, STR } from './lib/validator.ts'
import { Asserted } from './lib/router.ts'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deno run -A https://gistcdn.githack.com/kigiri/21df06d173fcdced5281b86ba6ac1382/raw/mod.ts

Past your secret: past your env
Input your password: ...
> f936ee830f54fb12e8376585c05a9df00ca12c438cb983

in code:

import { decrypt } from 'https://gistcdn.githack.com/kigiri/21df06d173fcdced5281b86ba6ac1382/raw/crypto.js'

const env = await decrypt(
 'f936ee830f54fb12e8376585c05a9df00ca12c438cb983',
  localStorage.password || (localStorage.password = prompt('password)),
)

await Deno.writeTextFile('./env.dev', env)

{/* Sidebar */}
<aside class='w-72 shrink-0 border-r border-divider flex flex-col'>
<div class='p-4 flex-1 flex flex-col'>
<h3 class='text-sm font-medium text-text2 mb-3'>Teams</h3>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const DialogSectionTitle = (props: JSX.props...) =>
	 <h3 class='text-sm font-medium text-text2 mb-3' {...props} />

if (idx === -1) projects.value = [...projects.value, project]
else projects.value[idx] = { ...projects.value[idx], ...project }

closeDialog()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  const projectsValues = projects.peek()
  if (!slug) {
    const base = slugify(name)
    let suffix = ''
    do {
      finalSlug = base + suffix
      slug = suffix ? String(Number(suffix) + 1) : '-1'
    } while (projectsValues.some((p) => p.slug === slug))
	  const now = new Date().toISOString()
	  const project: Project = { slug, name, teamId, createdAt: now }
    projects.value = [...projectsValues, project]
  } else {
    const idx = projectsValues.findIndex((p) => p.slug === slug)
    const copy = [...projectsValues]
    copy[idx] = { ...projectsValues[idx], name, teamId }
		project.values = copy
  }

  closeDialog()

@abdotop abdotop force-pushed the 17-create-preact-platformspage-with-daisyui-tablecards branch from a97bac6 to b16a336 Compare August 7, 2025 09:46
@abdotop abdotop force-pushed the 17-create-preact-platformspage-with-daisyui-tablecards branch from b16a336 to 09a1d7c Compare August 7, 2025 10:42
<div class='flex items-center gap-1 flex-shrink-0'>
<Calendar class='w-3.5 h-3.5' />
<span>
{new Date(project.createdAt).toLocaleDateString('fr-CA')}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better not specify and let browser default

onInput={(e) => (name.value = (e.target as HTMLInputElement).value)}
required
class='input input-bordered w-full'
/>
Copy link
Member

@kigiri kigiri Aug 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

          <input
            name='Name'
            type='text'
            defaultValue={project?.name ?? ''}
            required
            class='input input-bordered w-full'
          />

e.preventDefault()
if (!teamId.value) return
saveProject({
name: name.value,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// get value from input[name="Name"]

? projects.value.find((p) => p.slug === slug)
: undefined

const name = useSignal(project?.name ?? '')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useless

)}
{tab.value === 'settings' && (
<TeamSettingsSection team={selectedTeam} />
)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put tab in url, not useSignal

navigate({
params: { q: (e.target as HTMLInputElement).value || null },
replace: true,
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function never change, no need to redefine it on every render of ProjectPage

@abdotop abdotop force-pushed the 17-create-preact-platformspage-with-daisyui-tablecards branch from aebaee2 to 2837314 Compare August 8, 2025 12:41
@abdotop abdotop force-pushed the 17-create-preact-platformspage-with-daisyui-tablecards branch from 2837314 to f5b80f3 Compare August 11, 2025 09:47
@abdotop abdotop marked this pull request as ready for review August 14, 2025 08:41
@abdotop abdotop merged commit 8b8c986 into master Aug 14, 2025
2 checks passed
@abdotop abdotop deleted the 17-create-preact-platformspage-with-daisyui-tablecards branch August 14, 2025 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tournament Pull requests that are related to the Tournament team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create Preact PlatformsPage with DaisyUI table/cards

3 participants