diff --git a/config/config-dev.json b/config/config-dev.json
index 9308ae9e42a106a4b7a21fa2ffb36f679f8f4ea6..e154cc463bc6600168812652f7d706e0b587c0fb 100644
--- a/config/config-dev.json
+++ b/config/config-dev.json
@@ -4,5 +4,8 @@
   },
   "resources": {
     "url": "https://kong-dev.alpha.grandlyon.com/resources/"
+  },
+  "mediaLibrary": {
+    "url": "https://kong-dev.alpha.grandlyon.com/media-library/"
   }
-}
\ No newline at end of file
+}
diff --git a/config/config-rec.json b/config/config-rec.json
index a7de2abe2bba321edc2b665835b59d7146cd7e41..99666bacf0611bdb0dc575d1877ca8fd1161b41f 100644
--- a/config/config-rec.json
+++ b/config/config-rec.json
@@ -4,5 +4,8 @@
   },
   "resources": {
     "url": "https://kong-rec.alpha.grandlyon.com/resources/"
+  },
+  "mediaLibrary": {
+    "url": "https://kong-rec.alpha.grandlyon.com/media-library/"
   }
-}
\ No newline at end of file
+}
diff --git a/src/app/app.component.html b/src/app/app.component.html
index f752e2e749bef88d778a4a25316c122aa1536965..3043831d86a8dae809137666c003e22eeb3ad9cc 100644
--- a/src/app/app.component.html
+++ b/src/app/app.component.html
@@ -1,23 +1,23 @@
 <div class="grid">
 
-  <header class="main-header">
-      <div class="hamburger" 
-      (click)="sidebarOpened = !sidebarOpened"
-      [ngClass]="{'expanded': sidebarOpened}">
+    <header class="main-header">
+        <div class="hamburger" (click)="sidebarOpened = !sidebarOpened" [ngClass]="{'expanded': sidebarOpened}">
 
-      </div>
-      <h4>Plateforme Data Admin</h4>
-      <div class="logo">
-          <img src="assets/img/logo.svg" alt="Le Grand Lyon, la métropole">
+        </div>
+        <h4>Plateforme Data Admin</h4>
+        <div class="logo">
+            <img src="assets/img/logo.svg" alt="Le Grand Lyon, la métropole">
 
-      </div>
-  </header>
-  <nav class="main-nav" [ngClass]="{'is-active': sidebarOpened}">
-      <app-menu [expanded]="sidebarOpened"></app-menu>
-  </nav>
-  <div class="main-content" [ngClass]="{'wide': !sidebarOpened}">
-      <router-outlet></router-outlet>
+        </div>
+    </header>
+    <nav class="main-nav" [ngClass]="{'is-active': sidebarOpened}">
+        <app-menu [expanded]="sidebarOpened"></app-menu>
+    </nav>
+    <div class="main-content" [ngClass]="{'wide': !sidebarOpened}">
+        <router-outlet></router-outlet>
 
-  </div>
+    </div>
 
 </div>
+
+<app-notifications></app-notifications>
\ No newline at end of file
diff --git a/src/app/components/image-upload/image-upload.component.html b/src/app/components/image-upload/image-upload.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..72e3400a5b9ffda47784a569bdcaca09f18d99ff
--- /dev/null
+++ b/src/app/components/image-upload/image-upload.component.html
@@ -0,0 +1,11 @@
+<div class="field">
+  <label class="label" [for]="fieldParams.inputName">{{ fieldParams.label }}</label>
+  <div class="image-preview-container" *ngIf="fieldParams.existingImageUrl && !removeImageBtnClicked">
+    <button class="button" (click)="removeImage()"><i class="far fa-times-circle"></i></button>
+    <img [src]="fieldParams.existingImageUrl" alt="" class="image-preview">
+  </div>
+  <div class="control">
+    <input *ngIf="!fieldParams.existingImageUrl || removeImageBtnClicked" class="input" type="file"
+      [name]="fieldParams.inputName" [id]="fieldParams.inputName" (change)="setFile($event)">
+  </div>
+</div>
\ No newline at end of file
diff --git a/src/app/components/image-upload/image-upload.component.scss b/src/app/components/image-upload/image-upload.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..d4a9d5613206de3aa75a786ce5adcc2bb26cfa48
--- /dev/null
+++ b/src/app/components/image-upload/image-upload.component.scss
@@ -0,0 +1,17 @@
+.image-preview-container {
+  display: inline-block;
+  position: relative;
+  max-height: 5rem;
+}
+
+button {
+  position: absolute;
+  top: 0;
+  right: 0;
+  border: none;
+  background: transparent;
+}
+
+.field {
+  margin-bottom: 0.75rem;
+}
diff --git a/src/app/components/image-upload/image-upload.component.ts b/src/app/components/image-upload/image-upload.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..476ad0fffdc9e7b2634d8def54e4c4d9e4826780
--- /dev/null
+++ b/src/app/components/image-upload/image-upload.component.ts
@@ -0,0 +1,35 @@
+import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
+import { IImageUploadFieldParams } from 'src/app/models/image-upload.model';
+
+@Component({
+  selector: 'app-image-upload',
+  templateUrl: './image-upload.component.html',
+  styleUrls: ['./image-upload.component.scss']
+})
+export class ImageUploadComponent implements OnInit {
+
+  removeImageBtnClicked: boolean = false;
+
+  @Input() fieldParams: IImageUploadFieldParams;
+  @Output() fileChanged = new EventEmitter<FileList>();
+  @Output() imageRemoved = new EventEmitter<boolean>();
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+  setFile(event) {
+    const files = event.srcElement.files;
+    if (!files) {
+      return;
+    }
+
+    this.fileChanged.emit(files);
+  }
+
+  removeImage() {
+    this.removeImageBtnClicked = true;
+    this.imageRemoved.emit(true);
+  }
+}
diff --git a/src/app/components/index.ts b/src/app/components/index.ts
index 89665a7ff83dd6f5194d383a3563407781116bbd..5b89ff87ce224523dc22b61a682d4166c34024d6 100644
--- a/src/app/components/index.ts
+++ b/src/app/components/index.ts
@@ -12,6 +12,8 @@ import { CrudButtonsComponent } from './crud-buttons/crud-buttons.component';
 import { FormatsComponent } from './formats/list/formats.component';
 import { FormatDetailComponent } from './formats/detail/format-detail.component';
 import { FormatFormComponent } from './formats/edit/format-form.component';
+import { ImageUploadComponent } from './image-upload/image-upload.component';
+import { NotificationsComponent } from './notifications/notifications.component';
 
 export {
   MenuComponent,
@@ -28,6 +30,8 @@ export {
   FormatsComponent,
   FormatDetailComponent,
   FormatFormComponent,
+  ImageUploadComponent,
+  NotificationsComponent,
 };
 
 // tslint:disable-next-line:variable-name
@@ -46,4 +50,6 @@ export const AppComponents = [
   FormatsComponent,
   FormatDetailComponent,
   FormatFormComponent,
+  ImageUploadComponent,
+  NotificationsComponent,
 ];
diff --git a/src/app/components/notifications/notifications.component.html b/src/app/components/notifications/notifications.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..8c0b6dbd5b8e3ca86bb68010e18fbe0c8b448a92
--- /dev/null
+++ b/src/app/components/notifications/notifications.component.html
@@ -0,0 +1,21 @@
+<div *ngIf="notifications.length > 0" class="app-notifications">
+  <div *ngFor="let notification of notifications; index as i" class="app-notification" [class.success]="notification.type === 'success'"
+    [class.warning]="notification.type === 'warning'" [class.error]="notification.type === 'error'">
+    <ng-container [ngSwitch]="notification.type">
+      <div class="app-notification-type" *ngSwitchCase="'success'">
+        <img src="./assets/img/notif_ok.svg" alt="Ok icon">
+        <span>Ok!</span>
+      </div>
+      <div class="app-notification-type" *ngSwitchCase="'warning'">
+        <img src="./assets/img/notif_warning.svg" alt="Warning icon">
+        <span i18n="@@notification.oops">Oops!</span>
+      </div>
+      <div class="app-notification-type" *ngSwitchCase="'error'">
+        <img src="./assets/img/notif_error.svg" alt="Error icon">
+        <span i18n="@@notification.ouch">Ouch!</span>
+      </div>
+    </ng-container>
+    <p class="app-notification-content">{{ notification.message }}</p>
+    <button class="close-button" (click)="hide(i)"><i class="fas fa-times"></i></button>
+  </div>
+</div>
diff --git a/src/app/components/notifications/notifications.component.scss b/src/app/components/notifications/notifications.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..2c212c343bd7e3ad437add33026feaba335856b9
--- /dev/null
+++ b/src/app/components/notifications/notifications.component.scss
@@ -0,0 +1,118 @@
+@import '../../../../node_modules/bulma/sass/utilities/_all.sass';
+
+$app-notification-width: 29rem;
+
+.app-notifications {
+  position: fixed;
+  z-index: 10;
+  bottom: 0.5rem;
+  right: 0.5rem;
+
+  @media screen and (max-width: $tablet) {
+    bottom: 0;
+    right: 0;
+    width: 100%;
+  }
+}
+
+.app-notification {
+  position: relative;
+  min-width: $app-notification-width;
+  max-width: $app-notification-width;
+  padding: 1rem;
+  margin-top: 0.5rem;
+  border: 2px solid white;
+  border-radius: 4px;
+
+  @media screen and (max-width: $tablet) {
+    min-width: 100%;
+    max-width: 100%;
+  }
+
+  // Adding slideFromRight animation on notification classe
+  // The div come from the right and go back after a while
+  // The animation lasts 5s and is runned only one time
+  animation: slideFromRight 8s 1;
+
+  @media screen and (max-width: $tablet) {
+    animation: slideFromRightMobile 8s 1;
+  }
+
+  span,
+  p,
+  button {
+    color: white;
+  }
+
+  div.app-notification-type {
+    display: flex;
+    margin-bottom: 0.75rem;
+
+    img {
+      width: 1.125rem;
+      height: 1.125rem;
+      margin-right: 0.5rem;
+    }
+
+    span {
+      font-size: 1rem;
+      font-weight: bold;
+    }
+  }
+
+  p.app-notification-content {
+    font-size: 0.875rem;
+  }
+}
+
+.success {
+  background-color: rgba(84, 180, 51, 0.9);
+}
+
+.warning {
+  background-color: rgba(239, 114, 23, 0.9);
+}
+
+.error {
+  background-color: rgba(217, 3, 3, 0.9);
+}
+
+.close-button {
+  position: absolute;
+  top: 0;
+  right: 0;
+  border: none;
+  background-color: transparent;
+  cursor: pointer;
+}
+
+// Animation
+@keyframes slideFromRight {
+  0% {
+    transform: translateX($app-notification-width);
+  }
+
+  15%,
+  85% {
+    transform: translateX(0);
+  }
+
+  100% {
+    transform: translateX($app-notification-width);
+  }
+}
+
+@keyframes slideFromRightMobile {
+  0% {
+    transform: translateX(100%);
+  }
+
+  15%,
+  85% {
+    transform: translateX(0);
+  }
+
+  100% {
+    transform: translateX(100%);
+  }
+}
diff --git a/src/app/components/notifications/notifications.component.ts b/src/app/components/notifications/notifications.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cc9bf93d5aa81ec68fc9e804b58fb67ce506e34c
--- /dev/null
+++ b/src/app/components/notifications/notifications.component.ts
@@ -0,0 +1,34 @@
+import { Component, OnInit } from '@angular/core';
+import { NotificationService } from '../../services';
+import { Notification } from '../../models/notification.model';
+
+@Component({
+  selector: 'app-notifications',
+  templateUrl: './notifications.component.html',
+  styleUrls: ['./notifications.component.scss'],
+})
+export class NotificationsComponent implements OnInit {
+  notifications: Notification[] = [];
+
+  constructor(
+    private _notificationService: NotificationService,
+  ) { }
+
+  ngOnInit() {
+    this._notificationService.notification$.subscribe(
+      (notification) => {
+        if (notification) {
+          this.notifications.push(notification);
+          // Remove notification from array after 5 seconds
+          // IMPORTANT (if you change this value also change the value of the css animation)
+          setTimeout(() => this.notifications.shift(), 8000);
+        }
+      },
+    );
+  }
+
+  hide(index) {
+    this.notifications.splice(index, 1);
+  }
+
+}
diff --git a/src/app/components/organizations/detail/organization-detail.component.html b/src/app/components/organizations/detail/organization-detail.component.html
index 75135cd0dd854c228f45256ec5028023803795e1..3d17686ee4cdaecaee0b39828686063c00b39507 100644
--- a/src/app/components/organizations/detail/organization-detail.component.html
+++ b/src/app/components/organizations/detail/organization-detail.component.html
@@ -13,7 +13,7 @@
           </header>
           <div class="card-image">
             <figure class="image">
-              <img src="{{organization.logo}}" alt="Logo de l'organization">
+              <img [src]="organization.logo" alt="Logo de l'organization">
             </figure>
           </div>
           <div class="card-content">
@@ -49,4 +49,4 @@
 
   </section>
 
-</ng-container>
+</ng-container>
\ No newline at end of file
diff --git a/src/app/components/organizations/edit/organization-form.component.html b/src/app/components/organizations/edit/organization-form.component.html
index 6eebb451d147460c0d3a59c5d5dd77d835cbe82f..d00a3415c96010844093813d85249076880e9878 100644
--- a/src/app/components/organizations/edit/organization-form.component.html
+++ b/src/app/components/organizations/edit/organization-form.component.html
@@ -20,12 +20,9 @@
         </div>
       </div>
 
-      <div class="field">
-        <label class="label" for="logo">Logo</label>
-        <div class="control">
-          <input class="input" type="text" [value]="organization.logo" formControlName="logo" id="logo">
-        </div>
-      </div>
+      <app-image-upload [fieldParams]="logoFieldParams" (fileChanged)="logoChanged($event)"
+        (imageRemoved)="removeLogo()">
+      </app-image-upload>
 
       <div class="field">
         <label class="label required" for="description">Description</label>
@@ -90,6 +87,4 @@
       </div>
     </div>
   </form>
-
-
-</ng-container>
+</ng-container>
\ No newline at end of file
diff --git a/src/app/components/organizations/edit/organization-form.component.ts b/src/app/components/organizations/edit/organization-form.component.ts
index 7c8e5e506f175a320dfb65e0d0e3c9011827a992..6952b5acf2765a670c81d8a822bc13353d8917a8 100644
--- a/src/app/components/organizations/edit/organization-form.component.ts
+++ b/src/app/components/organizations/edit/organization-form.component.ts
@@ -3,7 +3,9 @@ import { ActivatedRoute, ParamMap, Router } from '@angular/router';
 import { Organization } from 'src/app/models/organization.model';
 import { OrganizationService } from 'src/app/services/organization.service';
 import { FormBuilder, FormGroup, Validators, FormArray } from '@angular/forms';
-import { tap, filter, switchMap } from 'rxjs/operators';
+import { filter, switchMap, mergeMap } from 'rxjs/operators';
+import { IImageUploadFieldParams } from 'src/app/models/image-upload.model';
+import { NotificationService } from 'src/app/services';
 
 @Component({
   selector: 'app-organization-form',
@@ -14,23 +16,31 @@ export class OrganizationFormComponent implements OnInit {
 
   organization: Organization;
   form: FormGroup;
+  logoFile: File;
+  logoFieldParams: IImageUploadFieldParams = {
+    inputName: 'logo',
+    label: 'Logo',
+    existingImageUrl: null,
+  };
+  logo: File;
   title: string;
 
   constructor(
-    private organizationService: OrganizationService,
-    private route: ActivatedRoute,
-    private router: Router,
+    private _organizationService: OrganizationService,
+    private _notificationService: NotificationService,
+    private _route: ActivatedRoute,
+    private _router: Router,
     private _fb: FormBuilder,
   ) {
   }
 
   ngOnInit() {
-    this.title = this.route.snapshot.data.title;
+    this.title = this._route.snapshot.data.title;
     this.initForm();
 
-    this.route.paramMap.pipe(
+    this._route.paramMap.pipe(
       filter((paramMap: ParamMap) => (paramMap.get('id') !== null)),
-      switchMap((paramMap: ParamMap) => this.organizationService.findById(paramMap.get('id'))))
+      switchMap((paramMap: ParamMap) => this._organizationService.findById(paramMap.get('id'))))
       .subscribe((organization: Organization) => {
 
         this.organization = organization;
@@ -43,16 +53,17 @@ export class OrganizationFormComponent implements OnInit {
           }));
         });
 
+        this.logoFieldParams.existingImageUrl = organization.logo;
+
         this.form = this._fb.group(
           {
             id: [this.organization.id],
             name: [organization.name, Validators.required],
             description: [organization.description, Validators.required],
-            logo: [organization.logo],
             elasticSearchName: [organization.elasticSearchName],
+            logo: [organization.logo],
             links: arr,
           });
-
       });
 
   }
@@ -60,13 +71,14 @@ export class OrganizationFormComponent implements OnInit {
   initForm() {
     this.organization = new Organization();
     const arr = new FormArray([]);
+    this.logoFieldParams.existingImageUrl = null;
     this.form = this._fb.group(
       {
         id: [this.organization.id],
         name: [this.organization.name, Validators.required],
         description: [this.organization.description, Validators.required],
-        logo: [this.organization.logo],
         elasticSearchName: [this.organization.elasticSearchName],
+        logo: [this.organization.logo],
         links: arr,
       });
   }
@@ -102,17 +114,29 @@ export class OrganizationFormComponent implements OnInit {
   onSubmit() {
     if (!this.formInvalid) {
       this.organization = new Organization(this.form.value);
-      this.organizationService.replaceOrCreate(this.organization)
-        .subscribe(
-          (organizationCreated) => {
-            this.router.navigate(['/organizations', organizationCreated.id])
-              .then(() => {
-              });
-          },
-          (err) => {
-            alert(err.message);
-          },
-        );
+      let action;
+
+      if (this.logoFile) {
+        action = this._organizationService.uploadLogoAndSaveOrganization(this.logoFile, this.organization);
+      } else {
+        action = this._organizationService.replaceOrCreate(this.organization);
+      }
+
+      action.subscribe(
+        (organizationCreated) => {
+          this._notificationService.notify({
+            message: 'L\'organisation a été créée avec succès.',
+            type: 'success',
+          });
+          this._router.navigate(['/organizations', organizationCreated.id]);
+        },
+        () => {
+          this._notificationService.notify({
+            message: 'Une erreur est survenue lors de la création de l\'organisation.',
+            type: 'error',
+          });
+        },
+      );
     }
   }
 
@@ -126,6 +150,17 @@ export class OrganizationFormComponent implements OnInit {
   }
 
   get formInvalid() {
-    return this.form.invalid;
+    return this.form.invalid ||
+      (!this.organization.logo && !this.logoFile);
+  }
+
+  logoChanged(fileList: FileList) {
+    if (fileList && fileList.length > 0) {
+      this.logoFile = fileList[0];
+    }
+  }
+
+  removeLogo() {
+    this.form.get('logo').setValue(null);
   }
 }
diff --git a/src/app/models/image-upload.model.ts b/src/app/models/image-upload.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0c4a768dc92888a6ef1f8ee5f8f0ceba92f32b4e
--- /dev/null
+++ b/src/app/models/image-upload.model.ts
@@ -0,0 +1,5 @@
+export interface IImageUploadFieldParams {
+  label: string;
+  inputName: string;
+  existingImageUrl?: string;
+}
diff --git a/src/app/models/notification.model.ts b/src/app/models/notification.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8fdf5fcff77594e5963c191719c2bc0990403e76
--- /dev/null
+++ b/src/app/models/notification.model.ts
@@ -0,0 +1,16 @@
+type errorType = 'error' | 'warning' | 'success';
+
+export interface INotification {
+  message: string;
+  type: errorType;
+}
+
+export class Notification {
+  message: string;
+  type: errorType;
+
+  constructor(notification: INotification) {
+    this.message = notification.message;
+    this.type = notification.type;
+  }
+}
diff --git a/src/app/models/organization.model.ts b/src/app/models/organization.model.ts
index 53adbd907ffd027f9924c0d4b9376bcae8364a02..54074cb77548abbd77d3452fe686f213512f5f73 100644
--- a/src/app/models/organization.model.ts
+++ b/src/app/models/organization.model.ts
@@ -8,17 +8,25 @@ export class Organization {
 
   constructor(organization?: IOrganization) {
     if (organization) {
-      this.id = organization.id;
+      if (organization.id) {
+        this.id = organization.id;
+      }
       this.name = organization.name;
       this.description = organization.description;
       this.elasticSearchName = organization.elasticSearchName;
       this.links = organization.links;
+
+      this.links.forEach((link) => {
+        if (!link.id) {
+          delete link.id;
+        }
+      });
       this.logo = organization.logo;
     } else {
-      this.name = '';
-      this.description = '';
-      this.logo = '';
-      this.elasticSearchName = '';
+      this.name = null;
+      this.description = null;
+      this.logo = null;
+      this.elasticSearchName = null;
       this.links = [];
     }
 
diff --git a/src/app/services/app-config.service.ts b/src/app/services/app-config.service.ts
index edabf90b5de6509faaa179008aaa0cac92a70606..66e9fd31fad98efbde56154a7c9f346e8cf1dcb4 100644
--- a/src/app/services/app-config.service.ts
+++ b/src/app/services/app-config.service.ts
@@ -7,6 +7,9 @@ export class AppConfig {
   resources: {
     url: string;
   };
+  mediaLibrary: {
+    url: string;
+  };
 }
 
 export let APP_CONFIG: AppConfig;
diff --git a/src/app/services/index.ts b/src/app/services/index.ts
index b72aa77e756069957b67a0b00e1b20cd1a4a1f36..34d4ee52b65425a4c8e071ecb732d74c314446ec 100644
--- a/src/app/services/index.ts
+++ b/src/app/services/index.ts
@@ -2,12 +2,14 @@ import { AppConfigService } from './app-config.service';
 import { OrganizationService } from './organization.service';
 import { ResourceService } from './resource.service';
 import { FormatService } from './format.service';
+import { NotificationService } from './notification.service';
 
 export {
   AppConfigService,
   OrganizationService,
   ResourceService,
   FormatService,
+  NotificationService,
 };
 
 // tslint:disable-next-line:variable-name
@@ -16,4 +18,5 @@ export const AppServices = [
   OrganizationService,
   ResourceService,
   FormatService,
+  NotificationService,
 ];
diff --git a/src/app/services/notification.service.ts b/src/app/services/notification.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7a1a532e14cd3da0e832564d46e40aa03f3f447b
--- /dev/null
+++ b/src/app/services/notification.service.ts
@@ -0,0 +1,21 @@
+
+import { Injectable } from '@angular/core';
+import { BehaviorSubject } from 'rxjs';
+import { Notification } from '../models/notification.model';
+
+@Injectable()
+export class NotificationService {
+
+  private _notification: BehaviorSubject<Notification> = new BehaviorSubject(null);
+
+  constructor() { }
+
+  notify(notification: Notification) {
+    this._notification.next(notification);
+  }
+
+  get notification$() {
+    return this._notification;
+  }
+
+}
diff --git a/src/app/services/organization.service.ts b/src/app/services/organization.service.ts
index 138d0bc91698fc2cfb13a3577609f7871dc6bb8c..d5a82d7ce9d00a5b3a3aeebd765a1a93fca73923 100644
--- a/src/app/services/organization.service.ts
+++ b/src/app/services/organization.service.ts
@@ -1,6 +1,6 @@
 import { Injectable } from '@angular/core';
 import { Observable, Subject } from 'rxjs';
-import { map } from 'rxjs/operators';
+import { map, mergeMap } from 'rxjs/operators';
 import { HttpClient } from '@angular/common/http';
 import { Organization, IOrganization, OrganizationRO } from '../models/organization.model';
 import { APP_CONFIG } from './app-config.service';
@@ -53,6 +53,26 @@ export class OrganizationService {
     return this._httpClient.delete(APP_CONFIG.organizations.url + id);
   }
 
+  uploadLogoAndSaveOrganization(logoFile, organization) {
+    return this.uploadLogo(logoFile).pipe(
+      mergeMap((response: any) => {
+        organization.logo = response.mediaUrl;
+        return this.replaceOrCreate(organization);
+      }),
+    )
+  }
+
+  uploadLogo(logoFile): Observable<string> {
+    const formData = new FormData();
+    formData.append('file', logoFile);
+
+    return this._httpClient.post<string>(`${APP_CONFIG.mediaLibrary.url}media`, formData).pipe(
+      map((response) => {
+        return response;
+      }),
+    );
+  }
+
   replaceOrCreate(data: Organization): Observable<Organization> {
     if (data.id) {
       return this._httpClient.put<IOrganization>(APP_CONFIG.organizations.url + data.id, data).pipe(
@@ -61,10 +81,7 @@ export class OrganizationService {
         }),
       );
     }
-    delete data.id;
-    data.links.forEach((link) => {
-      delete link.id;
-    });
+
     return this._httpClient.post<IOrganization>(APP_CONFIG.organizations.url, data).pipe(
       map((response) => {
         return new Organization(response);
diff --git a/src/assets/config/config.json b/src/assets/config/config.json
index 9308ae9e42a106a4b7a21fa2ffb36f679f8f4ea6..43cecd099741db2447135e4a96bc1d43339ac48c 100644
--- a/src/assets/config/config.json
+++ b/src/assets/config/config.json
@@ -1,8 +1,11 @@
 {
   "organizations": {
-    "url": "https://kong-dev.alpha.grandlyon.com/organizations/"
+    "url": "http://localhost:3000/organizations/"
   },
   "resources": {
-    "url": "https://kong-dev.alpha.grandlyon.com/resources/"
+    "url": "http://localhost:3003/"
+  },
+  "mediaLibrary": {
+    "url": "http://localhost:3006/"
   }
-}
\ No newline at end of file
+}
diff --git a/src/assets/img/notif_error.svg b/src/assets/img/notif_error.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7a66bc0ae16910cb1cb4a33a133b6837e2d6651d
--- /dev/null
+++ b/src/assets/img/notif_error.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+  <style>
+    .white {
+      fill: white;
+    }
+  </style>
+  <g id="picto_x5F_warning">
+    <path d="M18.8 15.7c.2.3.2.7.2 1-.1.4-.2.6-.5.9-.3.2-.6.4-1 .4H2.6c-.4 0-.7-.1-1-.4-.3-.2-.4-.5-.5-.9-.1-.3 0-.7.2-1L8.8 2.8c.2-.3.4-.5.7-.7.4-.1.7-.1 1 0 .4.1.6.3.8.7l7.5 12.9zm-8.7-3c-.4 0-.7.1-1 .4-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4s.7-.1 1-.4c.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.2-.6-.4-1-.4zM8.8 8.1L9 12c0 .1 0 .2.1.2.1.1.2.1.3.1h1.4c.1 0 .2 0 .2-.1.1-.1.1-.2.1-.2l.2-3.9c0-.1 0-.2-.1-.3-.1-.1-.1-.1-.2-.1H9.2c-.1 0-.2 0-.3.1-.1.1-.1.2-.1.3z" class="white"/>
+    <path d="M18.8 15.7c.2.3.2.7.2 1-.1.4-.2.6-.5.9-.3.2-.6.4-1 .4H2.6c-.4 0-.7-.1-1-.4-.3-.2-.4-.5-.5-.9-.1-.3 0-.7.2-1L8.8 2.8c.2-.3.4-.5.7-.7.4-.1.7-.1 1 0 .4.1.6.3.8.7l7.5 12.9zm-8.7-3c-.4 0-.7.1-1 .4-.3.3-.4.6-.4 1s.1.7.4 1c.3.3.6.4 1 .4s.7-.1 1-.4c.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.2-.6-.4-1-.4zM8.8 8.1L9 12c0 .1 0 .2.1.2.1.1.2.1.3.1h1.4c.1 0 .2 0 .2-.1.1-.1.1-.2.1-.2l.2-3.9c0-.1 0-.2-.1-.3-.1-.1-.1-.1-.2-.1H9.2c-.1 0-.2 0-.3.1-.1.1-.1.2-.1.3z" class="white"/>
+  </g>
+</svg>
diff --git a/src/assets/img/notif_ok.svg b/src/assets/img/notif_ok.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d7d07dc1eb579c1765df18d638422344bb73e8b9
--- /dev/null
+++ b/src/assets/img/notif_ok.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+  <style>
+    .white {
+      fill: white;
+    }
+  </style>
+  <g id="picto_x5F_ok">
+    <path d="M18.8 10.1c0 1.6-.4 3.1-1.2 4.4-.8 1.4-1.9 2.4-3.2 3.2-1.4.9-2.9 1.3-4.5 1.3s-3.1-.4-4.4-1.2c-1.4-.8-2.4-1.9-3.3-3.2-.8-1.4-1.2-2.8-1.2-4.4 0-1.6.4-3.1 1.2-4.4.8-1.4 1.9-2.4 3.3-3.2 1.4-.8 2.8-1.2 4.4-1.2 1.6 0 3.1.4 4.4 1.2 1.4.8 2.4 1.9 3.2 3.2.9 1.2 1.3 2.7 1.3 4.3zm-9.9 4.7l6.6-6.6c.1-.1.2-.2.2-.4s-.1-.3-.2-.4l-.8-.8c-.1-.1-.3-.2-.4-.2-.1 0-.3.1-.4.2L8.5 12 6 9.5c-.1-.1-.3-.2-.4-.2-.1 0-.3.1-.4.2l-.8.8c-.1.1-.2.2-.2.4s.1.3.2.4l3.7 3.7c.1.1.2.2.4.2s.3-.1.4-.2z" class="white"/>
+    <path d="M18.8 10.1c0 1.6-.4 3.1-1.2 4.4-.8 1.4-1.9 2.4-3.2 3.2-1.4.9-2.9 1.3-4.5 1.3s-3.1-.4-4.4-1.2c-1.4-.8-2.4-1.9-3.3-3.2-.8-1.4-1.2-2.8-1.2-4.4 0-1.6.4-3.1 1.2-4.4.8-1.4 1.9-2.4 3.3-3.2 1.4-.8 2.8-1.2 4.4-1.2 1.6 0 3.1.4 4.4 1.2 1.4.8 2.4 1.9 3.2 3.2.9 1.2 1.3 2.7 1.3 4.3zm-9.9 4.7l6.6-6.6c.1-.1.2-.2.2-.4s-.1-.3-.2-.4l-.8-.8c-.1-.1-.3-.2-.4-.2-.1 0-.3.1-.4.2L8.5 12 6 9.5c-.1-.1-.3-.2-.4-.2-.1 0-.3.1-.4.2l-.8.8c-.1.1-.2.2-.2.4s.1.3.2.4l3.7 3.7c.1.1.2.2.4.2s.3-.1.4-.2z" class="white"/>
+  </g>
+</svg>
diff --git a/src/assets/img/notif_warning.svg b/src/assets/img/notif_warning.svg
new file mode 100644
index 0000000000000000000000000000000000000000..f544dba648d1f2479de8a24a70cfa85f3ba2f283
--- /dev/null
+++ b/src/assets/img/notif_warning.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+  <style>
+    .white {
+      fill: white;
+    }
+  </style>
+  <g id="picto_x5F_oops">
+    <path d="M17 11.3l1.6.9c.1.1.2.1.2.2s.1.2 0 .3c-.4 1.3-1.1 2.5-2.1 3.5-.1.1-.2.1-.3.2h-.3l-1.6-.9c-.7.6-1.4 1-2.3 1.3v1.8c0 .1 0 .2-.1.3 0 .1-.1.2-.2.2-1.4.3-2.7.3-4.1 0-.1 0-.2-.1-.3-.2 0-.1-.1-.2-.1-.3v-1.8c-.8-.3-1.6-.7-2.3-1.3l-1.6.9c-.1.1-.2.1-.3 0-.1 0-.2-.1-.3-.2-.9-1-1.6-2.2-2.1-3.5v-.3c0-.1.1-.2.2-.2l1.6-.9c-.1-.9-.1-1.8 0-2.6l-1.4-1-.2-.2v-.3c.4-1.3 1.1-2.5 2.1-3.5.1-.1.2-.1.3-.2h.3l1.6.9c.7-.6 1.4-1 2.3-1.3V1.3c0-.1 0-.2.1-.3.1-.1.2-.2.3-.2 1.4-.3 2.7-.3 4.1 0 .1 0 .2.1.2.2.1.1.1.2.1.3v1.8c.8.3 1.6.7 2.3 1.3l1.6-.9c.1-.1.2-.1.3 0 .1 0 .2.1.3.2.9 1 1.6 2.2 2.1 3.5v.3c0 .1-.1.2-.2.2l-1.8.9c.1.9.1 1.8 0 2.7zM13.1 10c0-.9-.3-1.6-1-2.3-.6-.6-1.4-1-2.3-1-.8 0-1.6.3-2.3 1-.6.6-.9 1.4-.9 2.3 0 .9.3 1.7.9 2.3.6.6 1.4.9 2.3.9.9 0 1.6-.3 2.3-.9.7-.7 1-1.5 1-2.3z" class="white"/>
+    <path d="M17 11.3l1.6.9c.1.1.2.1.2.2s.1.2 0 .3c-.4 1.3-1.1 2.5-2.1 3.5-.1.1-.2.1-.3.2h-.3l-1.6-.9c-.7.6-1.4 1-2.3 1.3v1.8c0 .1 0 .2-.1.3 0 .1-.1.2-.2.2-1.4.3-2.7.3-4.1 0-.1 0-.2-.1-.3-.2 0-.1-.1-.2-.1-.3v-1.8c-.8-.3-1.6-.7-2.3-1.3l-1.6.9c-.1.1-.2.1-.3 0-.1 0-.2-.1-.3-.2-.9-1-1.6-2.2-2.1-3.5v-.3c0-.1.1-.2.2-.2l1.6-.9c-.1-.9-.1-1.8 0-2.6l-1.4-1-.2-.2v-.3c.4-1.3 1.1-2.5 2.1-3.5.1-.1.2-.1.3-.2h.3l1.6.9c.7-.6 1.4-1 2.3-1.3V1.3c0-.1 0-.2.1-.3.1-.1.2-.2.3-.2 1.4-.3 2.7-.3 4.1 0 .1 0 .2.1.2.2.1.1.1.2.1.3v1.8c.8.3 1.6.7 2.3 1.3l1.6-.9c.1-.1.2-.1.3 0 .1 0 .2.1.3.2.9 1 1.6 2.2 2.1 3.5v.3c0 .1-.1.2-.2.2l-1.8.9c.1.9.1 1.8 0 2.7zM13.1 10c0-.9-.3-1.6-1-2.3-.6-.6-1.4-1-2.3-1-.8 0-1.6.3-2.3 1-.6.6-.9 1.4-.9 2.3 0 .9.3 1.7.9 2.3.6.6 1.4.9 2.3.9.9 0 1.6-.3 2.3-.9.7-.7 1-1.5 1-2.3z" class="white"/>
+  </g>
+</svg>