diff --git a/frontend/components/user/UserDrawer.vue b/frontend/components/user/UserDrawer.vue
index 0f7fcf1..964f818 100644
--- a/frontend/components/user/UserDrawer.vue
+++ b/frontend/components/user/UserDrawer.vue
@@ -11,6 +11,16 @@
:error="touched.username && !form.username.trim() ? 'Le nom est requis' : ''"
@blur="touched.username = true"
/>
+
+
props.modelValue, (open) => {
if (open) {
if (props.item) {
form.username = props.item.username ?? ''
+ form.firstName = props.item.firstName ?? ''
+ form.lastName = props.item.lastName ?? ''
form.password = ''
form.roles = [...props.item.roles]
form.isEmployee = props.item.isEmployee ?? false
} else {
form.username = ''
+ form.firstName = ''
+ form.lastName = ''
form.password = ''
form.roles = ['ROLE_USER']
form.isEmployee = false
@@ -124,6 +140,8 @@ async function handleSubmit() {
try {
const payload: UserWrite = {
username: form.username.trim(),
+ firstName: form.firstName.trim() || null,
+ lastName: form.lastName.trim() || null,
roles: form.roles,
isEmployee: form.isEmployee,
}
diff --git a/frontend/services/dto/user-data.ts b/frontend/services/dto/user-data.ts
index 84e4608..3f5f5df 100644
--- a/frontend/services/dto/user-data.ts
+++ b/frontend/services/dto/user-data.ts
@@ -4,6 +4,8 @@ export type UserData = {
id: number
'@id'?: string
username: string
+ firstName?: string | null
+ lastName?: string | null
roles: string[]
avatarUrl?: string | null
apiToken?: string | null
@@ -20,6 +22,8 @@ export type UserData = {
export type UserWrite = {
username: string
+ firstName?: string | null
+ lastName?: string | null
plainPassword?: string
roles: string[]
// HR / absence management
diff --git a/migrations/Version20260526120000.php b/migrations/Version20260526120000.php
new file mode 100644
index 0000000..5d02af7
--- /dev/null
+++ b/migrations/Version20260526120000.php
@@ -0,0 +1,31 @@
+addSql('ALTER TABLE "user" ADD first_name VARCHAR(100) DEFAULT NULL');
+ $this->addSql('ALTER TABLE "user" ADD last_name VARCHAR(100) DEFAULT NULL');
+ }
+
+ public function down(Schema $schema): void
+ {
+ $this->addSql('ALTER TABLE "user" DROP COLUMN IF EXISTS first_name');
+ $this->addSql('ALTER TABLE "user" DROP COLUMN IF EXISTS last_name');
+ }
+}
diff --git a/src/DataFixtures/AppFixtures.php b/src/DataFixtures/AppFixtures.php
index ef9f2cb..0b5de94 100644
--- a/src/DataFixtures/AppFixtures.php
+++ b/src/DataFixtures/AppFixtures.php
@@ -43,6 +43,8 @@ class AppFixtures extends Fixture
// Users
$admin = new User();
$admin->setUsername('admin');
+ $admin->setFirstName('Alex');
+ $admin->setLastName('Martin');
$admin->setRoles(['ROLE_ADMIN']);
$admin->setPassword($this->passwordHasher->hashPassword($admin, 'admin'));
$admin->setApiToken('dev-mcp-token-for-testing-only-do-not-use-in-production');
@@ -50,18 +52,24 @@ class AppFixtures extends Fixture
$userAlice = new User();
$userAlice->setUsername('alice');
+ $userAlice->setFirstName('Alice');
+ $userAlice->setLastName('Dupont');
$userAlice->setRoles(['ROLE_USER']);
$userAlice->setPassword($this->passwordHasher->hashPassword($userAlice, 'alice'));
$manager->persist($userAlice);
$userBob = new User();
$userBob->setUsername('bob');
+ $userBob->setFirstName('Bob');
+ $userBob->setLastName('Leroy');
$userBob->setRoles(['ROLE_USER']);
$userBob->setPassword($this->passwordHasher->hashPassword($userBob, 'bob'));
$manager->persist($userBob);
$userCharlie = new User();
$userCharlie->setUsername('charlie');
+ $userCharlie->setFirstName('Charlie');
+ $userCharlie->setLastName('Moreau');
$userCharlie->setRoles(['ROLE_USER']);
$userCharlie->setPassword($this->passwordHasher->hashPassword($userCharlie, 'charlie'));
$manager->persist($userCharlie);
diff --git a/src/Entity/User.php b/src/Entity/User.php
index 22b8a8d..fd75f39 100644
--- a/src/Entity/User.php
+++ b/src/Entity/User.php
@@ -55,6 +55,14 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
#[Groups(['me:read', 'task:read', 'user:list', 'user:write', 'time_entry:read', 'absence_request:read', 'absence_balance:read'])]
private ?string $username = null;
+ #[ORM\Column(length: 100, nullable: true)]
+ #[Groups(['me:read', 'user:list', 'user:write'])]
+ private ?string $firstName = null;
+
+ #[ORM\Column(length: 100, nullable: true)]
+ #[Groups(['me:read', 'user:list', 'user:write'])]
+ private ?string $lastName = null;
+
/** @var list */
#[ORM\Column]
#[ApiProperty(security: "is_granted('ROLE_ADMIN') or object == user")]
@@ -147,6 +155,30 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this;
}
+ public function getFirstName(): ?string
+ {
+ return $this->firstName;
+ }
+
+ public function setFirstName(?string $firstName): static
+ {
+ $this->firstName = $firstName;
+
+ return $this;
+ }
+
+ public function getLastName(): ?string
+ {
+ return $this->lastName;
+ }
+
+ public function setLastName(?string $lastName): static
+ {
+ $this->lastName = $lastName;
+
+ return $this;
+ }
+
public function getUserIdentifier(): string
{
return (string) $this->username;