add personal address
This commit is contained in:
1 parent
50d1ba630e
commit
d2a153536f
17 files changed
+219
-30
No files matched your search
@@ -59,7 +59,6 @@ func (fr *TursoFileRepository) Upload(reader io.Reader, path string, name string
|
|||||||
ContentType: contentType,
|
ContentType: contentType,
|
||||||
VersionId: utility.GenID(),
|
VersionId: utility.GenID(),
|
||||||
DateCreated: time.Now(),
|
DateCreated: time.Now(),
|
||||||
DateUpdated: time.Now(),
|
|
||||||
Content: bytes,
|
Content: bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,13 +131,16 @@ func (ur *TursoUserRepository) ListUserAddresses(id string) ([]*domain.UserAddre
|
|||||||
return ur.AddressTable.SelectWhere("user_id=$1", id)
|
return ur.AddressTable.SelectWhere("user_id=$1", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ur *TursoUserRepository) CreateUserAddress(userid string, addr *domain.UserAddress) (*domain.UserAddress, error) {
|
func (ur *TursoUserRepository) GetUserAddress(addrID string) (*domain.UserAddress, error) {
|
||||||
addr.UserID = userid
|
return ur.AddressTable.Get(addrID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ur *TursoUserRepository) CreateUserAddress(addr *domain.UserAddress) (*domain.UserAddress, error) {
|
||||||
return ur.AddressTable.Insert(addr)
|
return ur.AddressTable.Insert(addr)
|
||||||
}
|
}
|
||||||
func (ur *TursoUserRepository) UpdateUserAddress(userid string, addr *domain.UserAddress) (*domain.UserAddress, error) {
|
func (ur *TursoUserRepository) UpdateUserAddress(addr *domain.UserAddress) (*domain.UserAddress, error) {
|
||||||
return ur.AddressTable.Update(addr)
|
return ur.AddressTable.Update(addr)
|
||||||
}
|
}
|
||||||
func (ur *TursoUserRepository) DeleteUserAddress(userid string, addrID string) error {
|
func (ur *TursoUserRepository) DeleteUserAddress(addrID string) error {
|
||||||
return ur.AddressTable.DeleteWhere("id=$1 and user_id=$2", addrID, userid)
|
return ur.AddressTable.DeleteWhere("id=$1", addrID)
|
||||||
}
|
}
|
||||||
@@ -117,8 +117,8 @@ func (tm *JwtTokenManager) TokenMiddleware(next echo.HandlerFunc) echo.HandlerFu
|
|||||||
|
|
||||||
// Rend les infos disponibles aux handlers suivants via c.Get(...)
|
// Rend les infos disponibles aux handlers suivants via c.Get(...)
|
||||||
c.Set(auth.ContextUserIDKey, claims.ID)
|
c.Set(auth.ContextUserIDKey, claims.ID)
|
||||||
c.Set(auth.ContextEmailKey, claims.Email)
|
//c.Set(auth.ContextEmailKey, claims.Email)
|
||||||
c.Set(auth.ContextNameKey, claims.Firstname+" "+claims.Lastname)
|
//c.Set(auth.ContextNameKey, claims.Firstname+" "+claims.Lastname)
|
||||||
|
|
||||||
return next(c)
|
return next(c)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ type File struct {
|
|||||||
StorageFilename string `db:"storage_filename" json:"-"`
|
StorageFilename string `db:"storage_filename" json:"-"`
|
||||||
Content []byte `db:"content" json:"-"`
|
Content []byte `db:"content" json:"-"`
|
||||||
DateCreated time.Time `db:"date_created" json:"-"`
|
DateCreated time.Time `db:"date_created" json:"-"`
|
||||||
DateUpdated time.Time `db:"date_updated" json:"-"`
|
DateUpdated *time.Time `db:"date_updated" json:"-"`
|
||||||
VersionId string `db:"_version" json:"-"`
|
VersionId string `db:"_version" json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ type Settings struct {
|
|||||||
DefaultLang string `db:"default_lang"`
|
DefaultLang string `db:"default_lang"`
|
||||||
RegisterEnabled bool `db:"register_enabled"`
|
RegisterEnabled bool `db:"register_enabled"`
|
||||||
PasswordEnabled bool `db:"password_enabled"`
|
PasswordEnabled bool `db:"password_enabled"`
|
||||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||||
VersionId string `db:"_version" json:"_version"`
|
VersionId string `db:"_version" json:"_version"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type User struct {
|
|||||||
Theme string `db:"theme" json:"theme"`
|
Theme string `db:"theme" json:"theme"`
|
||||||
Lang string `db:"lang" json:"lang"`
|
Lang string `db:"lang" json:"lang"`
|
||||||
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||||
DateUpdated time.Time `db:"_date_updated" json:"_date_updated"`
|
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||||
VersionId string `db:"_version" json:"_version"`
|
VersionId string `db:"_version" json:"_version"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ type Team struct {
|
|||||||
ID string `db:"id" json:"id"`
|
ID string `db:"id" json:"id"`
|
||||||
Label string `db:"label" json:"label"`
|
Label string `db:"label" json:"label"`
|
||||||
DefaultModelID *string `db:"default_model_id" json:"default_model_id"`
|
DefaultModelID *string `db:"default_model_id" json:"default_model_id"`
|
||||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||||
VersionId string `db:"_version" json:"_version"`
|
VersionId string `db:"_version" json:"_version"`
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ type UserTeam struct {
|
|||||||
UserID string `db:"user_id" json:"user_id"`
|
UserID string `db:"user_id" json:"user_id"`
|
||||||
TeamID string `db:"team_id" json:"team_id"`
|
TeamID string `db:"team_id" json:"team_id"`
|
||||||
Administrator bool `db:"administrator" json:"administrator"`
|
Administrator bool `db:"administrator" json:"administrator"`
|
||||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||||
VersionId string `db:"_version" json:"_version"`
|
VersionId string `db:"_version" json:"_version"`
|
||||||
}
|
}
|
||||||
@@ -42,8 +42,8 @@ type UserAddress struct {
|
|||||||
ID string `db:"id" json:"id"`
|
ID string `db:"id" json:"id"`
|
||||||
UserID string `db:"user_id" json:"user_id"`
|
UserID string `db:"user_id" json:"user_id"`
|
||||||
Type string `db:"type" json:"type"`
|
Type string `db:"type" json:"type"`
|
||||||
Address string `db:"address_id" json:"address"`
|
Address string `db:"address" json:"address"`
|
||||||
DateCreated *time.Time `db:"_date_created" json:"_date_created"`
|
DateCreated time.Time `db:"_date_created" json:"_date_created"`
|
||||||
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
DateUpdated *time.Time `db:"_date_updated" json:"_date_updated"`
|
||||||
VersionId string `db:"_version" json:"_version"`
|
VersionId string `db:"_version" json:"_version"`
|
||||||
}
|
}
|
||||||
@@ -58,6 +58,15 @@ type UserWithTeams struct {
|
|||||||
Teams []*TeamRelation `json:"teams"`
|
Teams []*TeamRelation `json:"teams"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddressTypes() []string {
|
||||||
|
return []string{
|
||||||
|
"email",
|
||||||
|
"telegram",
|
||||||
|
"whatsapp",
|
||||||
|
"signal",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type UserRepository interface {
|
type UserRepository interface {
|
||||||
FindUser(id string) (*User, error)
|
FindUser(id string) (*User, error)
|
||||||
FindUserByEmail(email string) (*User, error)
|
FindUserByEmail(email string) (*User, error)
|
||||||
@@ -81,7 +90,8 @@ type UserRepository interface {
|
|||||||
PopulateUserWithTeams(user *User) (*UserWithTeams, error)
|
PopulateUserWithTeams(user *User) (*UserWithTeams, error)
|
||||||
|
|
||||||
ListUserAddresses(userid string) ([]*UserAddress, error)
|
ListUserAddresses(userid string) ([]*UserAddress, error)
|
||||||
CreateUserAddress(userid string, addr *UserAddress) (*UserAddress, error)
|
GetUserAddress(addrID string) (*UserAddress, error)
|
||||||
UpdateUserAddress(userid string, addr *UserAddress) (*UserAddress, error)
|
CreateUserAddress(addr *UserAddress) (*UserAddress, error)
|
||||||
DeleteUserAddress(userid string, addrID string) error
|
UpdateUserAddress(addr *UserAddress) (*UserAddress, error)
|
||||||
|
DeleteUserAddress(addrID string) error
|
||||||
}
|
}
|
||||||
@@ -17,6 +17,10 @@ func NewUserGroup(prefix string, e *echo.Group, service *user.Service, middlewar
|
|||||||
auth := e.Group(prefix, middlewares...)
|
auth := e.Group(prefix, middlewares...)
|
||||||
auth.GET("/me", userHandler.Me)
|
auth.GET("/me", userHandler.Me)
|
||||||
auth.PUT("/:id", userHandler.Update)
|
auth.PUT("/:id", userHandler.Update)
|
||||||
|
auth.GET("/:id/address", userHandler.Addresses)
|
||||||
|
auth.POST("/:id/address", userHandler.CreateAddress)
|
||||||
|
auth.PUT("/:id/address", userHandler.UpdateAddress)
|
||||||
|
auth.DELETE("/:id/address/:address", userHandler.DeleteAddress)
|
||||||
return auth
|
return auth
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,15 +47,86 @@ func (h UserHandler) Update(c *echo.Context) error {
|
|||||||
}
|
}
|
||||||
updUser.ID = id
|
updUser.ID = id
|
||||||
|
|
||||||
isAdmin := false // TODO : check if caller is admin
|
if !(userID == id) {
|
||||||
if !(isAdmin || userID == id) {
|
|
||||||
return echo.NewHTTPError(http.StatusForbidden, "unauthorized to update user")
|
return echo.NewHTTPError(http.StatusForbidden, "unauthorized to update user")
|
||||||
}
|
}
|
||||||
|
|
||||||
user, err := h.userService.UpdateUser(&updUser, isAdmin)
|
user, err := h.userService.UpdateUser(&updUser, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.String(http.StatusBadRequest, err.Error())
|
return c.String(http.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, user)
|
return c.JSON(http.StatusOK, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h UserHandler) Addresses(c *echo.Context) error {
|
||||||
|
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||||
|
id := c.Param("id")
|
||||||
|
if !(userID == id) {
|
||||||
|
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||||
|
}
|
||||||
|
addresses, err := h.userService.ListAdresses(userID)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, addresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h UserHandler) CreateAddress(c *echo.Context) error {
|
||||||
|
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||||
|
id := c.Param("id")
|
||||||
|
if !(userID == id) {
|
||||||
|
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
|
var address domain.UserAddress
|
||||||
|
if err := c.Bind(&address); err != nil {
|
||||||
|
return c.String(http.StatusBadRequest, "bad request")
|
||||||
|
}
|
||||||
|
address.UserID = userID
|
||||||
|
|
||||||
|
newaddress, err := h.userService.AddAddress(userID, address.Type, address.Address)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "internal error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, newaddress)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h UserHandler) UpdateAddress(c *echo.Context) error {
|
||||||
|
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||||
|
id := c.Param("id")
|
||||||
|
if !(userID == id) {
|
||||||
|
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
|
var address domain.UserAddress
|
||||||
|
if err := c.Bind(&address); err != nil {
|
||||||
|
return c.String(http.StatusBadRequest, "bad request")
|
||||||
|
}
|
||||||
|
address.UserID = userID
|
||||||
|
|
||||||
|
newaddress, err := h.userService.UpdateAddress(userID, &address)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "internal error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, newaddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h UserHandler) DeleteAddress(c *echo.Context) error {
|
||||||
|
userID := c.Get(auth.ContextUserIDKey).(string)
|
||||||
|
id := c.Param("id")
|
||||||
|
addressID := c.Param("address")
|
||||||
|
if !(userID == id) {
|
||||||
|
return echo.NewHTTPError(http.StatusForbidden, "forbidden")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := h.userService.DeleteAddress(userID, addressID)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusInternalServerError, "internal error")
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, "deleted")
|
||||||
|
}
|
||||||
@@ -31,8 +31,10 @@ type Session struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const ContextUserIDKey = "userID"
|
const ContextUserIDKey = "userID"
|
||||||
const ContextEmailKey = "userEmail"
|
const ContextUserAdminKey = "userAdmin"
|
||||||
const ContextNameKey = "userName"
|
|
||||||
|
//const ContextEmailKey = "userEmail"
|
||||||
|
//const ContextNameKey = "userName"
|
||||||
|
|
||||||
// Interface définie ici car c'est un port propre au cas d'usage "auth"
|
// Interface définie ici car c'est un port propre au cas d'usage "auth"
|
||||||
type Authenticator interface {
|
type Authenticator interface {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"trankilou.fr/lassistanoque/backend/internal/domain"
|
"trankilou.fr/lassistanoque/backend/internal/domain"
|
||||||
)
|
)
|
||||||
@@ -53,8 +54,10 @@ func (s *Service) Register(registration Registration) (*Session, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
now := time.Now()
|
||||||
_, err = s.userRepository.CreateTeam(session.User.ID, &domain.Team{
|
_, err = s.userRepository.CreateTeam(session.User.ID, &domain.Team{
|
||||||
Label: "Espace personnel",
|
Label: "Espace personnel",
|
||||||
|
DateCreated: now,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -45,3 +45,38 @@ func (s *Service) UpdateUser(updUser *domain.User, fromAdmin bool) (*domain.User
|
|||||||
return s.repo.UpdateUser(user)
|
return s.repo.UpdateUser(user)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) ListAdresses(userId string) ([]*domain.UserAddress, error) {
|
||||||
|
return s.repo.ListUserAddresses(userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) AddAddress(userId string, typ string, address string) (*domain.UserAddress, error) {
|
||||||
|
addr := &domain.UserAddress{
|
||||||
|
UserID: userId,
|
||||||
|
Type: typ,
|
||||||
|
Address: address,
|
||||||
|
}
|
||||||
|
return s.repo.CreateUserAddress(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) UpdateAddress(userId string, address *domain.UserAddress) (*domain.UserAddress, error) {
|
||||||
|
old, err := s.repo.GetUserAddress(address.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if old.UserID != userId {
|
||||||
|
return nil, fmt.Errorf("unauthorized")
|
||||||
|
}
|
||||||
|
return s.repo.UpdateUserAddress(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) DeleteAddress(userId string, addressId string) error {
|
||||||
|
old, err := s.repo.GetUserAddress(addressId)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if old.UserID != userId {
|
||||||
|
return fmt.Errorf("unauthorized")
|
||||||
|
}
|
||||||
|
return s.repo.DeleteUserAddress(addressId)
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -1,7 +1,12 @@
|
|||||||
import { api } from '../client';
|
import { api } from '../client';
|
||||||
import { type User } from "$lib/types/api"
|
import type { User, Address } from "$lib/types/api"
|
||||||
|
|
||||||
export const userApi = {
|
export const userApi = {
|
||||||
me: () => api.get<User>('/user/me'),
|
me: () => api.get<User>('/user/me'),
|
||||||
update: (id: string, data: Partial<User>) => api.put<User>(`/user/${id}`, data),
|
update: (id: string, data: Partial<User>) => api.put<User>(`/user/${id}`, data),
|
||||||
|
|
||||||
|
listAddresses: (id: string) => api.get<Address[]>(`/user/${id}/address`),
|
||||||
|
createAddress: (id: string, data: Partial<Address>) => api.post<Address>(`/user/${id}/address`, data),
|
||||||
|
updateAddress: (id: string, data: Partial<Address>) => api.put<Address>(`/user/${id}/address`, data),
|
||||||
|
deleteAddress: (id:string, addrid: string) => api.delete<Address[]>(`/user/${id}/address/${addrid}`),
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { uiState } from "$lib/state/ui.svelte"
|
import { uiState } from "$lib/state/ui.svelte"
|
||||||
import { auth } from "$lib/state/auth.svelte"
|
|
||||||
import Menu from "$lib/components/Menu.svelte"
|
import Menu from "$lib/components/Menu.svelte"
|
||||||
import { logout } from "$lib/state/auth.svelte"
|
import { logout } from "$lib/state/auth.svelte"
|
||||||
import logo from "$lib/assets/logo-txt.png"
|
import logo from "$lib/assets/logo-txt.png"
|
||||||
@@ -31,9 +30,7 @@
|
|||||||
<Menu label="Tâches" icon="icon-tasks" link="/tasks"/>
|
<Menu label="Tâches" icon="icon-tasks" link="/tasks"/>
|
||||||
<Menu label="Connaissances" icon="icon-graduation-cap" link="/kb"/>
|
<Menu label="Connaissances" icon="icon-graduation-cap" link="/kb"/>
|
||||||
<Menu label="Historique" icon="icon-history" link="/history"/>
|
<Menu label="Historique" icon="icon-history" link="/history"/>
|
||||||
{#if auth.user?.administrator}
|
|
||||||
<Menu label="Paramétrage" icon="icon-cog" link="/settings"/>
|
<Menu label="Paramétrage" icon="icon-cog" link="/settings"/>
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="profile" class="w-full flex flex-row items-center border-t border-stone-200 dark:border-stone-800">
|
<div id="profile" class="w-full flex flex-row items-center border-t border-stone-200 dark:border-stone-800">
|
||||||
|
|||||||
@@ -3,8 +3,14 @@ export interface User {
|
|||||||
firstname: string
|
firstname: string
|
||||||
lastname: string
|
lastname: string
|
||||||
email: string
|
email: string
|
||||||
administrator: boolean
|
|
||||||
theme: string
|
theme: string
|
||||||
lang: string
|
lang: string
|
||||||
_version: string
|
_version: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Address {
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
address: string
|
||||||
|
_version: string
|
||||||
|
}
|
||||||
@@ -2,17 +2,24 @@
|
|||||||
|
|
||||||
import { SvelteMap } from 'svelte/reactivity';
|
import { SvelteMap } from 'svelte/reactivity';
|
||||||
import type { PageProps } from './$types';
|
import type { PageProps } from './$types';
|
||||||
import { type User } from '$lib/types/api'
|
import type { User, Address } from '$lib/types/api'
|
||||||
import { userApi } from '$lib/api/endpoints/user'
|
import { userApi } from '$lib/api/endpoints/user'
|
||||||
import FormError from '$lib/components/FormError.svelte';
|
import FormError from '$lib/components/FormError.svelte';
|
||||||
import { applyTheme, themeToLocalStorage } from '$lib/ui/themeswitcher';
|
import { applyTheme, themeToLocalStorage } from '$lib/ui/themeswitcher';
|
||||||
import { validateEmail } from '$lib/utilities/validators'
|
import { validateEmail } from '$lib/utilities/validators'
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
|
||||||
let { data }: PageProps = $props();
|
let { data }: PageProps = $props();
|
||||||
|
|
||||||
let form : User = $state(data.me)
|
let form : User = $state(data.me)
|
||||||
|
let addresses : Address[] = $state([] as Address[])
|
||||||
|
let newAddress : Address = $state({} as Address)
|
||||||
let errors = new SvelteMap<string,string>()
|
let errors = new SvelteMap<string,string>()
|
||||||
|
|
||||||
|
onMount(async ()=> {
|
||||||
|
addresses = await userApi.listAddresses(form.id)
|
||||||
|
})
|
||||||
|
|
||||||
$effect(()=>{
|
$effect(()=>{
|
||||||
themeToLocalStorage(form.theme)
|
themeToLocalStorage(form.theme)
|
||||||
applyTheme()
|
applyTheme()
|
||||||
@@ -36,6 +43,21 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleAddAddress = () => {
|
||||||
|
userApi.createAddress(form.id, newAddress)
|
||||||
|
.then((data)=>{
|
||||||
|
addresses.push(data)
|
||||||
|
newAddress = {} as Address
|
||||||
|
})
|
||||||
|
.catch((error)=>{ console.log(error) })
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeleteAddress = (id: string) => {
|
||||||
|
userApi.deleteAddress(form.id,id).then(()=>{
|
||||||
|
addresses = addresses.filter((a)=> a.id!=id)
|
||||||
|
}).catch((error)=>{console.log(error)})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="mb-4 formgroup">
|
<div class="mb-4 formgroup">
|
||||||
@@ -106,4 +128,30 @@
|
|||||||
|
|
||||||
<div class="mb-4 formgroup">
|
<div class="mb-4 formgroup">
|
||||||
<h2>Canaux de communication</h2>
|
<h2>Canaux de communication</h2>
|
||||||
|
|
||||||
|
{#each addresses as address (address.id) }
|
||||||
|
<div class="m-2">
|
||||||
|
<div class="bg-stone-600 rounded flex inline px-2 py-1">
|
||||||
|
<span>{address.type} : </span>
|
||||||
|
<span class="font-bold">{address.address}</span>
|
||||||
|
<button class="ml-4 pointer" onclick={()=>{handleDeleteAddress(address.id)}}>X</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
<div class="flex gap-2 mt-6">
|
||||||
|
<div>
|
||||||
|
<select bind:value={newAddress.type} class="textinput">
|
||||||
|
<option>Email</option>
|
||||||
|
<option>Telegram</option>
|
||||||
|
<option>Whatsapp</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex-1">
|
||||||
|
<input type="text" bind:value={newAddress.address} class="textinput" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button class="bt" onclick={handleAddAddress}>Ajouter</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@@ -31,6 +31,12 @@
|
|||||||
if (!validateEmail(form.email)) {
|
if (!validateEmail(form.email)) {
|
||||||
errors.set("email","Adresse email invalide !")
|
errors.set("email","Adresse email invalide !")
|
||||||
}
|
}
|
||||||
|
if (!form.firstname) {
|
||||||
|
errors.set("firstname","Le prénom est obligatoire !")
|
||||||
|
}
|
||||||
|
if (!form.lastname) {
|
||||||
|
errors.set("lastname","Le nom est obligatoire !")
|
||||||
|
}
|
||||||
if (form.password!==form.verifPassword) {
|
if (form.password!==form.verifPassword) {
|
||||||
errors.set("verifPassword","Les mots de pass ne correspondent pas.")
|
errors.set("verifPassword","Les mots de pass ne correspondent pas.")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ h2 {
|
|||||||
@apply cursor-pointer;
|
@apply cursor-pointer;
|
||||||
}
|
}
|
||||||
.bt {
|
.bt {
|
||||||
@apply cursor-pointer rounded bg-stone-200 px-4 py-2 hover:bg-stone-300 dark:bg-stone-800 dark:hover:bg-stone-700;
|
@apply cursor-pointer rounded bg-stone-200 px-4 py-1 hover:bg-stone-300 dark:bg-stone-800 dark:hover:bg-stone-700;
|
||||||
}
|
}
|
||||||
.menuitem {
|
.menuitem {
|
||||||
@apply text-stone-800 text-stone-950 dark:text-stone-300 hover:dark:text-stone-50;
|
@apply text-stone-800 text-stone-950 dark:text-stone-300 hover:dark:text-stone-50;
|
||||||
|
|||||||
Reference in new issue
Block a user