diff --git a/electron-builder.conf.js b/electron-builder.conf.js
index 5bf93b249ff19b9fa9f196ec800a0d17699a3583..beacc054f0807a0e4a12e7701ca1cf03a77880fa 100644
--- a/electron-builder.conf.js
+++ b/electron-builder.conf.js
@@ -58,15 +58,26 @@ module.exports = {
         };
         fs.writeFileSync('dist/appInfo.json', JSON.stringify(appInfo, null, 2));
     },
-    fileAssociations: {
-        ext: 'epoc',
-        name: 'ePoc Project',
-        description: 'ePoc project content package',
-        mimeType: 'application/zip',
-        role: 'Editor',
-        isPackage: false,
-        rank: 'Default'
-    },
+    fileAssociations: [
+        {
+            ext: 'epoc',
+            name: 'ePoc',
+            description: 'ePoc publication',
+            mimeType: 'application/zip',
+            role: 'Mobile Application',
+            isPackage: false,
+            rank: 'Default'
+        },
+        {
+            ext: 'epocproject',
+            name: 'ePoc Project',
+            description: 'ePoc project content package',
+            mimeType: 'application/zip',
+            role: 'Editor',
+            isPackage: false,
+            rank: 'Default'
+        }
+    ],
     afterSign: async (context) => {
         const { electronPlatformName, appOutDir } = context;
         if (electronPlatformName !== 'darwin' || process.env.NO_NOTARIZE) {
diff --git a/electron/components/file.js b/electron/components/file.js
index deef92381b3c242c0b14d957aced53d85b0cbc7b..8663ae8a322718201bae5b6315d660d89ded7748 100644
--- a/electron/components/file.js
+++ b/electron/components/file.js
@@ -62,11 +62,23 @@ const pickEpocToImport = async function () {
     const startTime = performance.now();
     const files = dialog.showOpenDialogSync(BrowserWindow.getFocusedWindow(), {
         properties: ['openFile'],
-        filters: [{ name: 'ePoc export archive', extensions: ['zip'] }],
+        filters: [{ name: 'ePoc export archive', extensions: ['zip', 'epoc'] }],
     });
     if (!files || !files[0]) return null;
     const filepath = files[0];
+
     const workdir = createWorkDir();
+    return importEpoc(filepath, startTime, workdir);
+};
+
+/**
+ * Import an ePoc project to the workdir
+ * @param {string} filepath - the path to the ePoc
+ * @param {number} startTime - the time when the import started
+ * @param {string} workdir - the path to the workdir
+ * @returns {{filepath: null, workdir: string, name: null, modified: Date} | null}
+ */
+const importEpoc = async function(filepath, startTime, workdir) {
     const zip = new AdmZip(filepath, {});
     zip.extractAllTo(workdir, true, false, null);
 
@@ -93,7 +105,7 @@ const pickEpocToImport = async function () {
 const pickEpocProject = function () {
     const files = dialog.showOpenDialogSync(BrowserWindow.getFocusedWindow(), {
         properties: ['openFile'],
-        filters: [{ name: 'ePoc', extensions: ['epoc'] }],
+        filters: [{ name: 'ePoc', extensions: ['epocproject', 'epoc'] }],
     });
     if (!files || !files[0]) return null;
 
@@ -107,19 +119,29 @@ const pickEpocProject = function () {
 
 /**
  * Unzip the content of an ePoc project file to the project workdir
- * @returns {{filepath: string, workdir: null, name: null, modified: Date}}
+ * @returns {{project: {filepath: string, workdir: null, name: null, modified: Date} | null, import: boolean} | null}
  */
 const openEpocProject = async function (filepath) {
     if (!filepath) return null;
     const startTime = performance.now();
+
     const workdir = createWorkDir();
     const zip = new AdmZip(filepath, {});
     try {
         zip.extractAllTo(workdir, true, false, null);
+        if(!fs.existsSync(path.join(workdir, 'project.json'))) {
+            const project = await importEpoc(filepath, startTime, workdir);
+            return {
+                project,
+                imported: true
+            };
+        }
     } catch (err) {
         return null;
     }
 
+    console.log('continuing the function');
+
     const project = {
         name: path.basename(filepath),
         modified: fs.statSync(filepath).mtime,
@@ -132,11 +154,14 @@ const openEpocProject = async function (filepath) {
     const ellapsed = performance.now() - startTime;
     if (ellapsed < 500) await wait(500 - ellapsed);
 
-    return project;
+    return {
+        project,
+        imported: false,
+    };
 };
 
 /**
- * Save the content of the ePoc project workdir to the currently opened .epoc file or call for saveAs
+ * Save the content of the ePoc project workdir to the currently opened .epocproject file or call for saveAs
  * @returns {string}
  */
 const saveEpocProject = async function (project) {
@@ -148,12 +173,12 @@ const saveEpocProject = async function (project) {
 };
 
 /**
- * Save the content of the ePoc project workdir to a new .epoc file
+ * Save the content of the ePoc project workdir to a new .epocproject file
  * @returns {string}
  */
 const saveAsEpocProject = async function (project) {
     const files = dialog.showSaveDialogSync(BrowserWindow.getFocusedWindow(), {
-        filters: [{ name: 'ePoc', extensions: ['epoc'] }],
+        filters: [{ name: 'ePoc', extensions: ['epocproject'] }],
     });
 
     if (!files) return null;
@@ -166,7 +191,7 @@ const saveAsEpocProject = async function (project) {
 /**
  * Zip files of an ePoc project
  * @param {string} workdir the path to the workdir
- * @param {string} filepath the path to the .epoc project file
+ * @param {string} filepath the path to the .epocproject file
  * @param {boolean} exporting if true, the project.json file will not be included
  */
 const zipFiles = async function (workdir, filepath, exporting) {
@@ -198,19 +223,19 @@ const zipEpocProject = async function (workdir, filepath) {
 };
 
 /**
- * Export the content of an ePoc next to the .epoc file
+ * Export the content of an ePoc next to the .epocproject file
  * @param {string} workdir the path to the workdir
- * @param {string} filepath the path to the .epoc project file
+ * @param {string} filepath the path to the .epocproject file
  * @return {string|null}
  */
 const exportProject = async function (workdir, filepath) {
     const defaultPath = filepath
-        ? path.join(path.dirname(filepath), path.basename(filepath, path.extname(filepath)) + '.zip')
+        ? path.join(path.dirname(filepath), path.basename(filepath, path.extname(filepath)) + '.epoc')
         : '';
 
     const exportPath = dialog.showSaveDialogSync(BrowserWindow.getFocusedWindow(), {
         defaultPath: defaultPath,
-        filters: [{ name: 'zip', extensions: ['zip'] }],
+        filters: [{ name: 'epoc', extensions: ['epoc'] }],
     });
 
     if (!exportPath) return null;
diff --git a/electron/components/ipc.js b/electron/components/ipc.js
index 6f686072e473c140996f90cffb9124a0ef6e8cab..1ace93ee223c9c703caa83710fda121157ba2af0 100644
--- a/electron/components/ipc.js
+++ b/electron/components/ipc.js
@@ -52,15 +52,21 @@ const setupIpcListener = function (targetWindow) {
     ipcMain.on('openEpocProject', async (event, epocProjectPath) => {
         if (event.sender !== targetWindow.webContents) return;
 
-        const project = await openEpocProject(epocProjectPath);
+        const { project, imported } = await openEpocProject(epocProjectPath);
         if (!project) {
             sendToFrontend(event.sender, 'epocProjectError');
             return;
         }
 
-        const flow = await readProjectData(project.workdir);
-        sendToFrontend(event.sender, 'epocProjectReady', { project, flow });
-        store.updateState('projects', { [targetWindow.id]: project });
+
+        if(imported) {
+            sendToFrontend(event.sender, 'importRequired', project);
+        } else {
+            const flow = await readProjectData(project.workdir);
+            sendToFrontend(event.sender, 'epocProjectReady', { project, flow });
+            store.updateState('projects', { [targetWindow.id]: project });
+        }
+
     });
 
     ipcMain.on('newEpocProject', async (event) => {
diff --git a/electron/components/menu.js b/electron/components/menu.js
index 1b9a22ed08a042cffa472922f2b3f34178ee4806..323ccaa6563bd893ad13a2fa8cb4b7591333ea39 100644
--- a/electron/components/menu.js
+++ b/electron/components/menu.js
@@ -59,7 +59,7 @@ module.exports.setupMenu = function () {
                     ],
                 },
                 {
-                    label: 'Importer un fichier zip',
+                    label: 'Importer un fichier .epoc',
                     click: async function () {
                         sendToFrontend(BrowserWindow.getFocusedWindow(), 'epocImportPicked');
                         const project = await pickEpocToImport();
diff --git a/src/components/ChoiceModal.vue b/src/components/ChoiceModal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..0202008aa448f6ed7d706a0579e43b05baa96d1d
--- /dev/null
+++ b/src/components/ChoiceModal.vue
@@ -0,0 +1,98 @@
+<script setup lang="ts">
+import { ref, onMounted } from 'vue';
+
+interface Props {
+    acceptLabel: string;
+    cancelLabel: string;
+}
+
+withDefaults(defineProps<Props>(), {
+    acceptLabel: 'Accepter',
+    cancelLabel: 'Annuler',
+});
+
+const emits = defineEmits<{
+    (e: 'accept'): void;
+    (e: 'cancel'): void;
+}>();
+
+const modalScreen = ref<HTMLElement | null>(null);
+
+function validate() {
+    emits('accept');
+}
+
+function cancel() {
+    emits('cancel');
+}
+
+onMounted(() => {
+    modalScreen.value.focus();
+});
+</script>
+
+<template>
+    <div
+        ref="modalScreen"
+        class="modal-backdrop"
+        tabindex="0"
+        @keyup.enter="validate"
+        @keyup.esc="cancel"
+    >
+        <div class="modal">
+            <slot />
+            <button class="btn btn-close" @click="cancel"><i class="icon-x"></i></button>
+            <button class="btn-choice accept" @click="validate">{{ acceptLabel }}</button>
+            <button class="btn-choice cancel" @click="cancel">{{ cancelLabel }}</button>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.modal-backdrop {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    background-color: rgba(0, 0, 0, 0.3);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    z-index: 500;
+}
+
+.modal {
+    user-select: none;
+    position: relative;
+    padding: 2rem;
+    background-color: white;
+    display: flex;
+    flex-direction: column;
+    border-radius: 10px;
+    gap: 1rem;
+    width: 22rem;
+}
+
+.btn-choice {
+    cursor: pointer;
+    border: none;
+    border-radius: 30px;
+    font-size: 1rem;
+    font-weight: 500;
+    padding: 1rem;
+
+    &:hover {
+        filter: brightness(95%);
+    }
+    &.cancel {
+        background-color: #fff;
+        color: var(--inria-grey);
+        border: 1px solid var(--inria-grey);
+    }
+    &.accept {
+        background-color: #e93100;
+        color: #fff;
+    }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/ValidationModal.vue b/src/components/ValidationModal.vue
index 368e89ceee9d02c57a0a6ca5632612846b4291f6..11a0db7e67722c5181942e9601a88bad7194ac3f 100644
--- a/src/components/ValidationModal.vue
+++ b/src/components/ValidationModal.vue
@@ -1,17 +1,11 @@
 <script setup lang="ts">
-import { onMounted, ref } from 'vue';
-import { useEditorStore } from '../shared/stores';
-import { deleteSelectedNodes } from '../shared/services/graph';
-import { saveState } from '../shared/services/undoRedo.service';
+import { useEditorStore } from '@/src/shared/stores';
+import { deleteSelectedNodes } from '@/src/shared/services/graph';
+import { saveState } from '@/src/shared/services/undoRedo.service';
+import ChoiceModal from '@/src/components/ChoiceModal.vue';
 
 const editorStore = useEditorStore();
 
-const modalScreen = ref(null);
-
-onMounted(() => {
-    modalScreen.value.focus();
-});
-
 function confirmDelete() {
     saveState();
     deleteSelectedNodes();
@@ -19,73 +13,18 @@ function confirmDelete() {
 </script>
 
 <template>
-    <div
-        ref="modalScreen"
-        class="modal-backdrop"
-        tabindex="0"
-        @keyup.enter="confirmDelete"
-        @keyup.esc="editorStore.validationModal = false"
+    <ChoiceModal
+        accept-label="OUI, SUPPRIMER"
+        cancel-label="NON, NE PAS SUPPRIMER"
+        @cancel="editorStore.validationModal = false"
+        @accept="confirmDelete"
     >
-        <div class="modal">
-            <h3>Souhaitez-vous vraiment supprimer cet élément ?</h3>
-            <button class="btn btn-close" @click="editorStore.validationModal = false"><i class="icon-x"></i></button>
-            <button class="btn-choice accept" @click="confirmDelete">OUI, SUPPRIMER</button>
-            <button class="btn-choice cancel" @click="editorStore.validationModal = false">
-                NON, NE PAS SUPPRIMER
-            </button>
-        </div>
-    </div>
+        <h3>Souhaitez-vous vraiment supprimer cet élément ?</h3>
+    </ChoiceModal>
 </template>
 
 <style lang="scss" scoped>
-.modal-backdrop {
-    position: fixed;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    right: 0;
-    background-color: rgba(0, 0, 0, 0.3);
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    z-index: 500;
-}
-
-.modal {
-    user-select: none;
-    position: relative;
-    padding: 2rem;
-    background-color: white;
-    display: flex;
-    flex-direction: column;
-    border-radius: 10px;
-    gap: 1rem;
-    width: 22rem;
-}
-
 h3 {
     text-align: center;
 }
-
-.btn-choice {
-    cursor: pointer;
-    border: none;
-    border-radius: 30px;
-    font-size: 1rem;
-    font-weight: 500;
-    padding: 1rem;
-
-    &:hover {
-        filter: brightness(95%);
-    }
-    &.cancel {
-        background-color: #fff;
-        color: var(--inria-grey);
-        border: 1px solid var(--inria-grey);
-    }
-    &.accept {
-        background-color: #e93100;
-        color: #fff;
-    }
-}
 </style>
diff --git a/src/shared/services/editor.service.ts b/src/shared/services/editor.service.ts
index d66dada7731a291229d2c4b09e772cf2df922a7a..bd063213e0f66c65ab23317d45e9e6fba707085d 100644
--- a/src/shared/services/editor.service.ts
+++ b/src/shared/services/editor.service.ts
@@ -4,7 +4,7 @@ import { useEditorStore, useGraphStore, useUndoRedoStore } from '@/src/shared/st
 import { ePocProject } from '@/src/shared/interfaces';
 import { createToaster } from '@meforma/vue-toaster';
 import { closeFormPanel, graphService } from '.';
-import { createGraphEpocFromData } from '@/src/shared/services/import.service';
+import { createGraphEpocFromData, createGraphFromImport } from '@/src/shared/services/import.service';
 import { useVueFlow } from '@vue-flow/core';
 import { saveState } from '@/src/shared/services/undoRedo.service';
 import { applyBackwardCompatibility } from '@/src/shared/utils/backwardCompability';
@@ -112,15 +112,11 @@ const setup = function () {
     });
 
     api.receive('epocImportExtracted', (data: string) => {
-        const importedEpoc = JSON.parse(data);
-        graphStore.setFlow(null);
-        router.push('/editor').then(() => {
-            editorStore.loading = false;
-            if (!importedEpoc || !importedEpoc.workdir) return;
-
-            createGraphEpocFromData(importedEpoc.epoc);
-            saveState();
-        });
+        createGraphFromImport(JSON.parse(data));
+    });
+    
+    api.receive('importRequired', (data: string) => {
+        editorStore.projectToImport = data;
     });
 
     api.receive('previewReady', () => {
@@ -186,6 +182,7 @@ function pickEpocProject(): void {
 function openEpocProject(project: ePocProject): void {
     editorStore.currentProject = project;
     editorStore.loading = true;
+    
     router.push('/landingpage').then(() => {
         api.send('openEpocProject', project.filepath);
     });
diff --git a/src/shared/services/import.service.ts b/src/shared/services/import.service.ts
index cc807d053576f322d0886e47c609da79550e20b2..5f54449529f8202be540c1154b77966cd2b2e296 100644
--- a/src/shared/services/import.service.ts
+++ b/src/shared/services/import.service.ts
@@ -12,6 +12,9 @@ import { Assessment, ChoiceCondition, SimpleQuestion } from '@epoc/epoc-types/sr
 import { createRule, getConditions } from '@/src/shared/services/graph/badge.service';
 import { Node } from '@vue-flow/core';
 import { Badge } from '@/src/shared/interfaces';
+import { router } from '@/src/router';
+import { saveState } from '@/src/shared/services/undoRedo.service';
+import { useEditorStore, useGraphStore } from '@/src/shared/stores';
 
 const mapType = {
     video: standardPages.find((s) => s.type === 'video'),
@@ -196,3 +199,17 @@ function setQuestionData(type: string, question: any) {
 
     return questionData;
 }
+
+export function createGraphFromImport(importedEpoc) {
+    const graphStore = useGraphStore();
+    const editorStore = useEditorStore();
+    
+    graphStore.setFlow(null);
+    router.push('/editor').then(() => {
+        editorStore.loading = false;
+        if (!importedEpoc || !importedEpoc.workdir) return;
+        
+        createGraphEpocFromData(importedEpoc.epoc);
+        saveState();
+    });
+}
\ No newline at end of file
diff --git a/src/shared/stores/editorStore.ts b/src/shared/stores/editorStore.ts
index 2c67a1a7dd73b172fb15440f08d244c7149373b4..52b68714a02f7228a175a3c8bd2c793caa5891fb 100644
--- a/src/shared/stores/editorStore.ts
+++ b/src/shared/stores/editorStore.ts
@@ -10,6 +10,7 @@ type uid = string;
 interface EditorState {
     // Landing page
     loading: boolean;
+    projectToImport: string | null;
     recentProjects: ePocProject[];
     currentProject: ePocProject;
 
@@ -65,6 +66,7 @@ export const useEditorStore = defineStore('editor', {
     state: (): EditorState => ({
         // Landing page
         loading: false,
+        projectToImport: null,
         recentProjects: [],
         currentProject: { filepath: null, workdir: null, name: null, modified: null },
 
diff --git a/src/views/LandingPage.vue b/src/views/LandingPage.vue
index 4c0f68e8155b79c0ac7302b86ed2605e51a9cd7c..edd993040c45b821b0caacb6484a6f02edf2dfc8 100644
--- a/src/views/LandingPage.vue
+++ b/src/views/LandingPage.vue
@@ -2,6 +2,8 @@
 import { useEditorStore } from '@/src/shared/stores';
 import { editorService } from '@/src/shared/services';
 import { ePocProject } from '@/src/shared/interfaces';
+import ChoiceModal from '@/src/components/ChoiceModal.vue';
+import { createGraphFromImport } from '@/src/shared/services/import.service';
 
 const editorStore = useEditorStore();
 
@@ -17,6 +19,16 @@ function openProject(filepath: ePocProject) {
 function createProject() {
     editorService.newEpocProject();
 }
+
+function cancelImport() {
+    editorStore.projectToImport = null;
+    editorStore.loading = false;
+}
+
+function importProject() {
+    createGraphFromImport(JSON.parse(editorStore.projectToImport));
+    editorStore.projectToImport = null;
+}
 </script>
 
 <template>
@@ -25,7 +37,25 @@ function createProject() {
             <img alt="logo epoc" src="/img/epoc.svg" />
             <img alt="logo inria" src="/img/inria.svg" />
         </div>
-        <div v-if="!editorStore.loading">
+
+        <ChoiceModal
+            v-if="editorStore.projectToImport"
+            accept-label="Importer"
+            @accept="importProject"
+            @cancel="cancelImport"
+        >
+            <h3>Cet ePoc est une publication, vous devez l'importer avant de pouvoir l'éditer ici</h3>
+        </ChoiceModal>
+
+        <div v-if="editorStore.loading" class="loading">
+            <div class="spinner"></div>
+            <span v-if="editorStore.currentProject.filepath">
+                Chargement de "{{ editorStore.currentProject.filepath }}"
+            </span>
+            <span v-else>Chargement de l'ePoc</span>
+        </div>
+
+        <div v-else>
             <div class="buttons">
                 <button class="btn btn-outline btn-large" @click="pickProject">
                     <i class="icon-ouvrir" />
@@ -52,13 +82,6 @@ function createProject() {
                 </div>
             </div>
         </div>
-        <div v-if="editorStore.loading" class="loading">
-            <div class="spinner"></div>
-            <span v-if="editorStore.currentProject.filepath">
-                Chargement de "{{ editorStore.currentProject.filepath }}"
-            </span>
-            <span v-else>Chargement de l'ePoc</span>
-        </div>
     </div>
 </template>