Compare commits
6 Commits
agenda
...
e769dd6757
Author | SHA1 | Date | |
---|---|---|---|
e769dd6757 | |||
323cb05388 | |||
79baddb8f6 | |||
279c171ba2 | |||
9ba8e3e84e | |||
6de38a9725 |
741
Documentation/openapi/main.yaml
Normal file
741
Documentation/openapi/main.yaml
Normal file
@ -0,0 +1,741 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: MyInpulse Backend Api
|
||||
description: this document servers as a documentation for the backend api.
|
||||
version: 0.0.0
|
||||
|
||||
tags:
|
||||
- name: Entrepreneurs API
|
||||
description: La partie de l'api dédiée aux entrepreneurs
|
||||
- name: Admin API
|
||||
description: La partie de l'api dédiée aux entrepreneurs
|
||||
- name: Shared API
|
||||
description: La partie de l'api dédiée aux entrepreneurs et admins
|
||||
|
||||
|
||||
components:
|
||||
schemas:
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
nom:
|
||||
type: string
|
||||
prenom:
|
||||
type: string
|
||||
email:
|
||||
type: string
|
||||
example: "example@exmaple.com"
|
||||
secondaryEmail:
|
||||
type: string
|
||||
example: "example@exmaple.com"
|
||||
tel:
|
||||
type: string
|
||||
example: "0612345678"
|
||||
user-entrepreneur:
|
||||
type: object
|
||||
properties:
|
||||
user:
|
||||
$ref: "#/components/schemas/user"
|
||||
entrepreneur:
|
||||
type: object
|
||||
properties:
|
||||
ecole:
|
||||
type: string
|
||||
example: "enseirb"
|
||||
filiere:
|
||||
type: string
|
||||
example: "info"
|
||||
status:
|
||||
type: boolean
|
||||
example: false
|
||||
user-admin:
|
||||
type: object
|
||||
properties:
|
||||
admin:
|
||||
$ref: "#/components/schemas/user"
|
||||
|
||||
securitySchemes:
|
||||
MyINPulse:
|
||||
type: oauth2
|
||||
flows:
|
||||
implicit:
|
||||
authorizationUrl: https://petstore3.swagger.io/oauth/authorize
|
||||
scopes:
|
||||
MyINPulse-admin: Administrateur
|
||||
MyINPulse-entrepreneur: Utilisateur
|
||||
|
||||
paths:
|
||||
|
||||
# _ ____ __ __ ___ _ _ _ ____ ___
|
||||
# / \ | _ \| \/ |_ _| \ | | / \ | _ \_ _|
|
||||
# / _ \ | | | | |\/| || || \| | / _ \ | |_) | |
|
||||
# / ___ \| |_| | | | || || |\ | / ___ \| __/| |
|
||||
# /_/ \_\____/|_| |_|___|_| \_| /_/ \_\_| |___|
|
||||
#
|
||||
|
||||
/admin/projects:
|
||||
get:
|
||||
summary: Retourne la liste of projets associés à l'admin
|
||||
tags:
|
||||
- Admin API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
description:
|
||||
JSON array of who's elements are objects containing necessary information for the view
|
||||
(project name, entrepreneur names, etc..)
|
||||
of the projects an admin is watching over.
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
E_names:
|
||||
type: string
|
||||
description: entrepreneur names
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is missing or invalid
|
||||
/admin/projects/pending/decision:
|
||||
post:
|
||||
summary: valider un projet en attente de validation
|
||||
tags:
|
||||
- Admin API
|
||||
description:
|
||||
if the request is accepted the status of the
|
||||
project is changed to ongoing, entrepreneur
|
||||
account is confirmed and the project is linked
|
||||
to the admin accepting the request and the
|
||||
entrepreneur requesting it. Else the pending
|
||||
project and user info are deleted.
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
pedingProjectId:
|
||||
type: integer
|
||||
decision:
|
||||
type: boolean
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
/admin/projects/add:
|
||||
post:
|
||||
summary: Ajout manuel d'un projet
|
||||
description:
|
||||
Adds a project with the
|
||||
inputed details
|
||||
tags:
|
||||
- Admin API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
founder:
|
||||
$ref: "#/components/schemas/user-entrepreneur"
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
/admin/appointments/report/{appointmentId}:
|
||||
put:
|
||||
summary: enregistrer un rapport du rendez-vous
|
||||
description:
|
||||
Generate a PDF file formatted
|
||||
from input text and links it
|
||||
to the appointement.
|
||||
tags:
|
||||
- Admin API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
parameters:
|
||||
- in: path
|
||||
name: appointmentId
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
body:
|
||||
type: string
|
||||
conclusion:
|
||||
type: string
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
post:
|
||||
summary: modifier un rapport déja éxistant du rendez-vous
|
||||
description:
|
||||
Modifies the report file to input
|
||||
text and links it to the appointement.
|
||||
tags:
|
||||
- Admin API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
parameters:
|
||||
- in: path
|
||||
name: appointmentId
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
body:
|
||||
type: string
|
||||
conclusion:
|
||||
type: string
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
|
||||
/admin/projects/remove/{projectId}:
|
||||
delete:
|
||||
summary: supression d'un project
|
||||
description:
|
||||
Removes the project
|
||||
with the inputed id projectId
|
||||
tags:
|
||||
- Admin API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
parameters:
|
||||
- in: path
|
||||
name: projectId
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
|
||||
/admin/projects/pending:
|
||||
get:
|
||||
summary: Retourne la liste des projets en attente de validation
|
||||
tags:
|
||||
- Admin API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
description:
|
||||
JSON array of who's elements are objects containing
|
||||
necessary information for the view (project name,
|
||||
entrepreneur names, etc..) of all pending projects.
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
founder:
|
||||
$ref: "#/components/schemas/user-entrepreneur"
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is missing or invalid
|
||||
|
||||
#
|
||||
# ____ _ _ _ ____ ___
|
||||
# / ___|| |__ __ _ _ __ ___ __| | / \ | _ \_ _|
|
||||
# \___ \| '_ \ / _` | '__/ _ \/ _` | / _ \ | |_) | |
|
||||
# ___) | | | | (_| | | | __/ (_| | / ___ \| __/| |
|
||||
# |____/|_| |_|\__,_|_| \___|\__,_| /_/ \_\_| |___|
|
||||
#
|
||||
|
||||
/shared/appointments/upcoming:
|
||||
get:
|
||||
summary: Retourne la list des prochains rendez-vous de l'utilisateur
|
||||
tags:
|
||||
- Shared API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
- MyINPulse-entrepreneur
|
||||
description:
|
||||
JSON array of upcoming appointment data (name, date, time etc..) for a user.
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
date:
|
||||
type: string
|
||||
time:
|
||||
type: string
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is missing or invalid
|
||||
|
||||
/shared/projects/lcsection/{projectId}/{title}/{date}:
|
||||
get:
|
||||
summary: Retourne la liste de sections de LC avec un titre donné
|
||||
tags:
|
||||
- Shared API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
- MyINPulse-entrepreneur
|
||||
description:
|
||||
JSON array containing Lean Canvas
|
||||
section data with a title for the
|
||||
current date (or given date if the
|
||||
date parameter is passed)
|
||||
parameters:
|
||||
- in: path
|
||||
required: true
|
||||
name: projectId
|
||||
schema:
|
||||
type: integer
|
||||
- in: path
|
||||
required: true
|
||||
description: this number can be 1, 2,...,8. It is associated with the title of the lcsection
|
||||
name: title
|
||||
schema:
|
||||
type: integer
|
||||
enum: [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
|
||||
- in: path
|
||||
required: true
|
||||
name: date
|
||||
description: the date corresponding to the wanted version of lc section. "Nan" for the latest version
|
||||
example: "NaN"
|
||||
schema:
|
||||
type: string
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
section:
|
||||
type: string
|
||||
txt:
|
||||
type: string
|
||||
time:
|
||||
type: string
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is missing or invalid
|
||||
|
||||
/shared/projects/entrepreneurs/{projectId}:
|
||||
get:
|
||||
summary: Retourne la liste d'entrepreneurs associée à un projet donné
|
||||
tags:
|
||||
- Shared API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
- MyINPulse-entrepreneur
|
||||
description:
|
||||
JSON array of entrepreneur
|
||||
names associated with a project
|
||||
parameters:
|
||||
- in: path
|
||||
name: projectId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/user-entrepreneur"
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is missing or invalid
|
||||
|
||||
/shared/projects/admin/{projectId}:
|
||||
get:
|
||||
summary: Retourne les informations de l'admin qui accompagne le projet
|
||||
tags:
|
||||
- Shared API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
- MyINPulse-entrepreneur
|
||||
description:
|
||||
JSON object containing information (name, gmail, tel, etc..)
|
||||
the admin supervising the project with id projectID.
|
||||
parameters:
|
||||
- in: path
|
||||
name: projectId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/user-admin"
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
/shared/projects/appointments/{projectId}:
|
||||
get:
|
||||
summary: Retourne les rendez-vous du projet
|
||||
tags:
|
||||
- Shared API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
- MyINPulse-entrepreneur
|
||||
description:
|
||||
JSON array of upcoming and past appointment
|
||||
data for the project with id projectID.
|
||||
parameters:
|
||||
- in: path
|
||||
name: projectId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
appointementId:
|
||||
type: integer
|
||||
name:
|
||||
type: string
|
||||
date:
|
||||
type: string
|
||||
time:
|
||||
type: string
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
/shared/projects/appointments/report/{apointementId}:
|
||||
get:
|
||||
summary: Retourne le rapport pdf du rendez-vous
|
||||
tags:
|
||||
- Shared API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-admin
|
||||
- MyINPulse-entrepreneur
|
||||
description:
|
||||
PDF file containing the ap-
|
||||
pointment report
|
||||
parameters:
|
||||
- in: path
|
||||
name: apointementId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/pdf:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
/shared/appointments/request:
|
||||
post:
|
||||
summary: demander un rendez-vous
|
||||
description:
|
||||
will add an appointement request request by the applicant
|
||||
to have an appointment to be confirmed or denied by the
|
||||
specified participants of the appointement.
|
||||
tags:
|
||||
- Shared API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-entrepreneur
|
||||
- MyINPulse-admin
|
||||
requestBody:
|
||||
description: \"participants\" property is an array containing userids of the participants in the appointement
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
start_time:
|
||||
type: string
|
||||
end_time:
|
||||
type: string
|
||||
place:
|
||||
type: string
|
||||
applicantId:
|
||||
type: integer
|
||||
participants:
|
||||
#/* */
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
|
||||
|
||||
# _____ _ _ _____ ____ _____ ____ ____ _____ _ _ _____ _ _ ____
|
||||
# | ____| \ | |_ _| _ \| ____| _ \| _ \| ____| \ | | ____| | | | _ \
|
||||
# | _| | \| | | | | |_) | _| | |_) | |_) | _| | \| | _| | | | | |_) |
|
||||
# | |___| |\ | | | | _ <| |___| __/| _ <| |___| |\ | |___| |_| | _ <
|
||||
# |_____|_|_\_| |_| |_| \_\_____|_| |_| \_\_____|_| \_|_____|\___/|_| \_\
|
||||
# / \ | _ \_ _|
|
||||
# / _ \ | |_) | |
|
||||
# / ___ \| __/| |
|
||||
# /_/ \_\_| |___|
|
||||
#
|
||||
|
||||
|
||||
/entrepreneur/projects/request:
|
||||
post:
|
||||
summary: demander la création et validation d'un projet
|
||||
tags:
|
||||
- Entrepreneurs API
|
||||
description:
|
||||
Adds project to pending projects
|
||||
to then be accepted or rejected by
|
||||
an admin
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-entrepreneur
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
founder:
|
||||
$ref: "#/components/schemas/user-entrepreneur"
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
|
||||
/entrepreneur/lcsection/add/{projectId}:
|
||||
post:
|
||||
summary: ajouter une sections au LC
|
||||
description:
|
||||
Adds input data to the user's LC
|
||||
with a specified title.
|
||||
tags:
|
||||
- Entrepreneurs API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-entrepreneur
|
||||
parameters:
|
||||
- in: path
|
||||
name: projectId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
txt:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
/entrepreneur/lcsection/modify/{sectionId}:
|
||||
put:
|
||||
summary: modifier les données d'une section LC
|
||||
description:
|
||||
Modifies input Lean Canvas section by changing it to
|
||||
the information in the request body and changes the
|
||||
time stamp.
|
||||
tags:
|
||||
- Entrepreneurs API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-entrepreneur
|
||||
parameters:
|
||||
- in: path
|
||||
name: sectionId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
txt:
|
||||
type: string
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
/entrepreneur/lcsection/remove/{sectionId}:
|
||||
delete:
|
||||
summary: supprimer une section LC.
|
||||
description:
|
||||
Deletes section from Lean Canvas
|
||||
tags:
|
||||
- Entrepreneurs API
|
||||
security:
|
||||
- MyINPulse:
|
||||
- MyINPulse-entrepreneur
|
||||
parameters:
|
||||
- in: path
|
||||
name: sectionId
|
||||
schema:
|
||||
type: integer
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
"400":
|
||||
description: Bad request
|
||||
"401":
|
||||
description: Authorization information is
|
||||
missing or invalid
|
||||
|
||||
|
||||
|
||||
|
@ -1,10 +1,63 @@
|
||||
{
|
||||
"entrepreneurs": [
|
||||
{ "id": 1, "name": "Alice", "email": "alice@example.com" },
|
||||
{ "id": 2, "name": "Bob", "email": "bob@example.com" },
|
||||
{ "id": 3, "name": "Charlie", "email": "charlie@example.com" }
|
||||
{ "id": 1, "name": "Alice", "email": "alice@example.com" },
|
||||
{ "id": 2, "name": "Bob", "email": "bob@example.com" },
|
||||
{ "id": 3, "name": "Charlie", "email": "charlie@example.com" }
|
||||
],
|
||||
"data": [
|
||||
{ "canva_data": "this is a fake data to test api" }
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 1,
|
||||
"title_text": "1. Problème",
|
||||
"description": "3 problèmes essentiels à résoudre pour le client"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 2,
|
||||
"title_text": "2. Segments",
|
||||
"description": "Les segments de clientèle visés"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 3,
|
||||
"title_text": "3. Valeur",
|
||||
"description": "La proposition de valeur"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 4,
|
||||
"title_text": "4. Solution",
|
||||
"description": "Les solutions proposées"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 5,
|
||||
"title_text": "5. Avantage",
|
||||
"description": "Les avantages concurrentiels"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 6,
|
||||
"title_text": "6. Canaux",
|
||||
"description": "Les canaux de distribution"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 7,
|
||||
"title_text": "7. Indicateurs",
|
||||
"description": "Les indicateurs clés de performance"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 8,
|
||||
"title_text": "8. Coûts",
|
||||
"description": "Les coûts associés"
|
||||
},
|
||||
{
|
||||
"projectId": 1,
|
||||
"title": 9,
|
||||
"title_text": "9. Revenus",
|
||||
"description": "Les sources de revenus"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
324
front/MyINPulse-front/src/components/canvas/CanvasItem.vue
Normal file → Executable file
324
front/MyINPulse-front/src/components/canvas/CanvasItem.vue
Normal file → Executable file
@ -1,88 +1,326 @@
|
||||
<template>
|
||||
<div :class="['cell', { expanded }]"
|
||||
@click="toggleExpand"
|
||||
:style="{ justifyContent: expanded ? 'flex-start' : 'center' }"> <!-- Looking for finding a way
|
||||
to make this style in the toggleExpand event -->
|
||||
<div :class="['cell', { expanded }]" @click="handleClick">
|
||||
<h3>{{ title_text }}</h3>
|
||||
|
||||
<h3>{{ title }}</h3>
|
||||
<p>{{ currentDescription }}</p>
|
||||
<div class="section-bloc" v-for="(desc, index) in currentDescriptions" :key="index">
|
||||
<!-- Mode affichage -->
|
||||
<template v-if="!isEditing[index]">
|
||||
<div class="description">
|
||||
<p>{{ desc }}</p>
|
||||
</div>
|
||||
<div class="button-container">
|
||||
<button v-if="expanded" @click.stop="startEditing(index)" class="edit-button">Éditer</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Mode édition -->
|
||||
<template v-else>
|
||||
<textarea v-model="editedDescriptions[index]" class="edit-input"></textarea>
|
||||
<div class="button-container">
|
||||
<button @click.stop="saveEdit(index)" class="save-button">Enregistrer</button>
|
||||
<button @click.stop="cancelEdit(index)" class="cancel-button">Annuler</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineProps, onMounted } from "vue";
|
||||
import { ref, defineProps } from "vue";
|
||||
import axios from "axios";
|
||||
|
||||
const props = defineProps<{
|
||||
title: string;
|
||||
description: string;
|
||||
const IS_MOCK_MODE = true;
|
||||
|
||||
const props = defineProps<{
|
||||
projectId: number;
|
||||
title: number;
|
||||
title_text: string;
|
||||
description: string;
|
||||
}>();
|
||||
|
||||
const expanded = ref(false);
|
||||
const currentDescription = ref(props.description);
|
||||
const currentDescriptions = ref<string[]>([]);
|
||||
const editedDescriptions = ref<string[]>([]);
|
||||
const isEditing = ref<boolean[]>([]);
|
||||
|
||||
|
||||
/*
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await axios.get("http://localhost:5000/data"); // Update the URL if needed
|
||||
currentDescription.value = response.data[0].canva_data;
|
||||
const response = await axios.get("http://localhost:5000/data"); // Met à jour l'URL
|
||||
if (response.data.length > 0) {
|
||||
currentDescription.value = response.data[0].canva_data;
|
||||
editedDescription.value = response.data[0].canva_data;
|
||||
} else {
|
||||
console.warn("Aucune donnée reçue.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération des données :", error);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
// Fonction de simulation de l'API
|
||||
const mockFetch = async (projectId: number, title: number, date: string) => {
|
||||
console.log(`Mock fetch pour projectId: ${projectId}, title: ${title}, date: ${date}`);
|
||||
|
||||
return new Promise<{ txt: string }[]>((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve([
|
||||
{ txt: "Ceci est une description 1 pour tester the damn front, Why are u still reading dumbass this is just some nonsense sentence XD" },
|
||||
{ txt: "Ceci est une description 1 pour tester the damn front, Bruh are u still here?" },
|
||||
{ txt: "Ceci est une description 1 pour tester the damn front, .-. BRUH" }
|
||||
]);
|
||||
}, 500); // Simule un délai réseau de 500ms
|
||||
});
|
||||
};
|
||||
|
||||
// Fonction fetchData avec possibilité d'utiliser le mock
|
||||
const fetchData = async (projectId: number, title: number, date: string, useMock = false) => {
|
||||
try {
|
||||
const responseData = useMock
|
||||
? await mockFetch(projectId, title, date)
|
||||
: (await axios.get<{ txt: string }[]>(
|
||||
`http://localhost:5000/shared/projects/lcsection/${projectId}/${title}/${date}`
|
||||
)).data;
|
||||
|
||||
if (responseData.length > 0) {
|
||||
currentDescriptions.value = responseData.map((item) => item.txt);
|
||||
editedDescriptions.value = [...currentDescriptions.value];
|
||||
isEditing.value = Array(responseData.length).fill(false);
|
||||
} else {
|
||||
console.warn("Aucune donnée reçue.");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération des données :", error);
|
||||
}
|
||||
};
|
||||
|
||||
const toggleExpand = async () => {
|
||||
// Utilisation du mock dans handleClick pour tester sans serveur
|
||||
const handleClick = async () => {
|
||||
if (!expanded.value) {
|
||||
await fetchData();
|
||||
} else {
|
||||
currentDescription.value = props.description;
|
||||
await fetchData(props.projectId, props.title, "NaN", IS_MOCK_MODE); // true pour activer le mock
|
||||
} else if (!isEditing.value.includes(true)) {
|
||||
// Réinitialiser les descriptions si aucune édition n'est en cours
|
||||
currentDescriptions.value = [props.description];
|
||||
editedDescriptions.value = [props.description];
|
||||
}
|
||||
|
||||
if (!isEditing.value.includes(true)) {
|
||||
expanded.value = !expanded.value;
|
||||
}
|
||||
expanded.value = !expanded.value;
|
||||
};
|
||||
|
||||
|
||||
const startEditing = (index: number) => {
|
||||
isEditing.value[index] = true;
|
||||
};
|
||||
|
||||
/*
|
||||
const saveEdit = async (index: number) => {
|
||||
try {
|
||||
const id = index + 1; // À adapter selon l'ID réel des données
|
||||
await axios.put(`http://localhost:5000/data/${id}`, {
|
||||
canva_data: editedDescriptions.value[index]
|
||||
});
|
||||
|
||||
// Mettre à jour l'affichage local après la mise à jour réussie
|
||||
currentDescriptions.value[index] = editedDescriptions.value[index];
|
||||
isEditing.value[index] = false;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la mise à jour des données :", error);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
// Fonction de mock pour l'enregistrement
|
||||
const mockSaveEdit = async (index: number) => {
|
||||
try {
|
||||
const id = index + 1; // À adapter selon l'ID réel des données
|
||||
console.log(`Mock save pour l'ID ${id} avec la description : ${editedDescriptions.value[index]}`);
|
||||
|
||||
// Simuler un délai d'enregistrement comme une requête réseau
|
||||
await new Promise((resolve) => setTimeout(resolve, 500)); // Simulation de délai réseau
|
||||
|
||||
// Mettre à jour l'affichage local après la mise à jour réussie
|
||||
currentDescriptions.value[index] = editedDescriptions.value[index];
|
||||
isEditing.value[index] = false;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la mise à jour des données mockées :", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Utilisation de `mockSaveEdit` au lieu de `saveEdit` dans `handleClick` ou tout autre endroit
|
||||
const saveEdit = async (index: number) => {
|
||||
if (IS_MOCK_MODE) {
|
||||
await mockSaveEdit(index);
|
||||
} else {
|
||||
try {
|
||||
const id = index + 1;
|
||||
await axios.put(`http://localhost:5000/data/${id}`, {
|
||||
canva_data: editedDescriptions.value[index]
|
||||
});
|
||||
|
||||
// Mettre à jour l'affichage local après la mise à jour réussie
|
||||
currentDescriptions.value[index] = editedDescriptions.value[index];
|
||||
isEditing.value[index] = false;
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la mise à jour des données :", error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const cancelEdit = (index: number) => {
|
||||
editedDescriptions.value[index] = currentDescriptions.value[index];
|
||||
isEditing.value[index] = false;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped>
|
||||
@import "@/components/canvas/style-project.css";
|
||||
|
||||
.cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.expanded-content {
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
|
||||
.cell:not(.expanded):hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 8px 9px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.cell h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
/*margin-bottom: 10px;*/
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
/*margin-bottom: 10px;*/
|
||||
}
|
||||
|
||||
.cell p {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.expanded {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: white;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: white;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
.description {
|
||||
display: flex;
|
||||
align-items: center; /* Centre verticalement */
|
||||
justify-content: center; /* Centre horizontalement */
|
||||
text-align: center; /* Centre le texte à l'intérieur */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
margin-top: 10px;
|
||||
margin-left: 2%;
|
||||
}
|
||||
|
||||
.description + .p {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.edit-input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
margin-top: 10px;
|
||||
box-sizing: border-box;
|
||||
margin-left: 2%;
|
||||
}
|
||||
|
||||
|
||||
.button-container {
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.section-bloc ,.editing-section-bloc {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-right: 10%;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.edit-button {
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
font-size: 12px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.save-button, .cancel-button {
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
font-size: 12px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.edit-button {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.save-button {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.cancel-button {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.edit-button:hover {
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
.save-button:hover {
|
||||
background-color: #218838;
|
||||
}
|
||||
|
||||
.cancel-button:hover {
|
||||
background-color: #c82333;
|
||||
}
|
||||
|
||||
</style>
|
@ -4,7 +4,9 @@
|
||||
v-for="(item, index) in items"
|
||||
:key="index"
|
||||
:title="item.title"
|
||||
:title_text="item.title_text"
|
||||
:description="item.description"
|
||||
:projectId="item.projectId"
|
||||
:class="item.class"
|
||||
/>
|
||||
</div>
|
||||
@ -15,16 +17,17 @@ import { ref } from "vue";
|
||||
import CanvasItem from "@/components/canvas/CanvasItem.vue";
|
||||
|
||||
const items = ref([
|
||||
{ title: "1. Problème", description: "3 problèmes essentiels à résoudre pour le client", class: "Probleme" },
|
||||
{ title: "2. Segments", description: "Les segments de clientèle visés", class: "Segments" },
|
||||
{ title: "3. Valeur", description: "La proposition de valeur", class: "Valeur" },
|
||||
{ title: "4. Solution", description: "Les solutions proposées", class: "Solution" },
|
||||
{ title: "5. Avantage", description: "Les avantages concurrentiels", class: "Avantage" },
|
||||
{ title: "6. Canaux", description: "Les canaux de distribution", class: "Canaux" },
|
||||
{ title: "7. Indicateurs", description: "Les indicateurs clés de performance", class: "Indicateurs" },
|
||||
{ title: "8. Coûts", description: "Les coûts associés", class: "Couts" },
|
||||
{ title: "9. Revenus", description: "Les sources de revenus", class: "Revenus" }
|
||||
{ projectId: 1, title: 1, title_text: "1. Problème", description: "3 problèmes essentiels à résoudre pour le client", class: "Probleme" },
|
||||
{ projectId: 1, title: 2, title_text: "2. Segments", description: "Les segments de clientèle visés", class: "Segments" },
|
||||
{ projectId: 1, title: 3, title_text: "3. Valeur", description: "La proposition de valeur", class: "Valeur" },
|
||||
{ projectId: 1, title: 4, title_text: "4. Solution", description: "Les solutions proposées", class: "Solution" },
|
||||
{ projectId: 1, title: 5, title_text: "5. Avantage", description: "Les avantages concurrentiels", class: "Avantage" },
|
||||
{ projectId: 1, title: 6, title_text: "6. Canaux", description: "Les canaux de distribution", class: "Canaux" },
|
||||
{ projectId: 1, title: 7, title_text: "7. Indicateurs", description: "Les indicateurs clés de performance", class: "Indicateurs" },
|
||||
{ projectId: 1, title: 8, title_text: "8. Coûts", description: "Les coûts associés", class: "Couts" },
|
||||
{ projectId: 1, title: 9, title_text: "9. Revenus", description: "Les sources de revenus", class: "Revenus" }
|
||||
]);
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -11,7 +11,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import HeaderCanvas from '../components/canvas/HeaderCanvas.vue';
|
||||
// @ts-ignore
|
||||
import HeaderCanvas from "../components/canvas/HeaderCanvas.vue";
|
||||
import LeanCanvas from '../components/canvas/LeanCanvas.vue';
|
||||
</script>
|
||||
|
@ -14,7 +14,7 @@ import ErrorModal from "@/components/errorModal.vue";
|
||||
.error-wrapper{
|
||||
position: absolute;
|
||||
left: 70%;
|
||||
//background-color: blue;
|
||||
/*background-color: blue;*/
|
||||
height: 100%;
|
||||
width: 30%;
|
||||
|
||||
|
Reference in New Issue
Block a user