Compare commits
18 Commits
7fc06035c7
...
front_foun
Author | SHA1 | Date | |
---|---|---|---|
47be7d340b | |||
232d10b164 | |||
bc7ce888ad | |||
ed67a3734a | |||
95eb154556 | |||
19fef63b0e | |||
1fd95265ea | |||
3ef2d8a198 | |||
6b49bbbe57 | |||
4c15cab607 | |||
abfe92bc87 | |||
85b4fe6a4c | |||
f2448a029f | |||
cef4daef15 | |||
f5aba70017 | |||
27adc81ddc | |||
48f14e8a04 | |||
d4533ea725 |
@ -95,4 +95,22 @@ public class EntrepreneurApi {
|
||||
@RequestBody Project project, @AuthenticationPrincipal Jwt principal) {
|
||||
entrepreneurApiService.requestNewProject(project, principal.getClaimAsString("email"));
|
||||
}
|
||||
|
||||
/*
|
||||
* <p>Endpoint to check if project is has already been validated by an admin
|
||||
*/
|
||||
@GetMapping("/entrepreneur/projects/project-is-active")
|
||||
public Boolean checkIfProjectValidated(@AuthenticationPrincipal Jwt principal) {
|
||||
return entrepreneurApiService.checkIfEntrepreneurProjectActive(
|
||||
principal.getClaimAsString("email"));
|
||||
}
|
||||
|
||||
/*
|
||||
* <p>Endpoint to check if a user requested a project (used when project is pending)
|
||||
*/
|
||||
@GetMapping("/entrepreneur/projects/has-pending-request")
|
||||
public Boolean checkIfHasRequested(@AuthenticationPrincipal Jwt principal) {
|
||||
return entrepreneurApiService.entrepreneurHasPendingRequestedProject(
|
||||
principal.getClaimAsString("email"));
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
package enseirb.myinpulse.controller;
|
||||
|
||||
import enseirb.myinpulse.model.Administrator;
|
||||
import enseirb.myinpulse.model.Entrepreneur;
|
||||
import enseirb.myinpulse.service.AdminApiService;
|
||||
import enseirb.myinpulse.service.EntrepreneurApiService;
|
||||
import enseirb.myinpulse.service.UtilsService;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@ -16,15 +15,15 @@ import org.springframework.web.bind.annotation.*;
|
||||
public class UnauthApi {
|
||||
|
||||
private final EntrepreneurApiService entrepreneurApiService;
|
||||
private final AdminApiService adminApiService;
|
||||
private final UtilsService utilsService;
|
||||
|
||||
@Autowired
|
||||
UnauthApi(EntrepreneurApiService entrepreneurApiService, AdminApiService administratorService) {
|
||||
UnauthApi(EntrepreneurApiService entrepreneurApiService, UtilsService utilsService) {
|
||||
this.entrepreneurApiService = entrepreneurApiService;
|
||||
this.adminApiService = administratorService;
|
||||
this.utilsService = utilsService;
|
||||
}
|
||||
|
||||
@GetMapping("/unauth/finalize")
|
||||
@PostMapping("/unauth/finalize")
|
||||
public void createAccount(@AuthenticationPrincipal Jwt principal) {
|
||||
boolean sneeStatus;
|
||||
if (principal.getClaimAsString("sneeStatus") != null) {
|
||||
@ -50,21 +49,13 @@ public class UnauthApi {
|
||||
course,
|
||||
sneeStatus,
|
||||
true);
|
||||
|
||||
entrepreneurApiService.createAccount(e);
|
||||
}
|
||||
|
||||
/*
|
||||
* These bottom endpoints are meant for testing only
|
||||
* and should not py merged to main
|
||||
*
|
||||
*/
|
||||
@GetMapping("/unauth/getAllAdmins")
|
||||
public Iterable<Administrator> getEveryAdmin() {
|
||||
return this.adminApiService.getAllAdmins();
|
||||
}
|
||||
|
||||
@GetMapping("/unauth/getAllEntrepreneurs")
|
||||
public Iterable<Entrepreneur> getEveryEntrepreneur() {
|
||||
return this.entrepreneurApiService.getAllEntrepreneurs();
|
||||
@GetMapping("/unauth/check-if-not-pending")
|
||||
public Boolean checkAccountStatus(@AuthenticationPrincipal Jwt principal) {
|
||||
// Throws 404 if user not found
|
||||
return utilsService.checkEntrepreneurNotPending(principal.getClaimAsString("email"));
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package enseirb.myinpulse.service;
|
||||
|
||||
import static enseirb.myinpulse.model.ProjectDecisionValue.PENDING;
|
||||
import static enseirb.myinpulse.model.ProjectDecisionValue.ACTIVE;
|
||||
|
||||
import enseirb.myinpulse.model.Entrepreneur;
|
||||
import enseirb.myinpulse.model.Project;
|
||||
import enseirb.myinpulse.model.SectionCell;
|
||||
import enseirb.myinpulse.model.User;
|
||||
import enseirb.myinpulse.service.database.*;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@ -234,4 +236,49 @@ public class EntrepreneurApiService {
|
||||
public Iterable<Entrepreneur> getAllEntrepreneurs() {
|
||||
return entrepreneurService.getAllEntrepreneurs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an entrepreneur with the given email has a project that is ACTIVE.
|
||||
*
|
||||
* @param email The email of the entrepreneur.
|
||||
* @return true if the entrepreneur has an active project, false otherwise.
|
||||
*/
|
||||
public Boolean checkIfEntrepreneurProjectActive(String email) {
|
||||
User user = this.userService.getUserByEmail(email);
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
Long userId = user.getIdUser();
|
||||
|
||||
Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(userId);
|
||||
if (entrepreneur == null) {
|
||||
return false;
|
||||
}
|
||||
Project proposedProject = entrepreneur.getProjectProposed();
|
||||
return proposedProject != null && proposedProject.getProjectStatus() == ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an entrepreneur with the given email has proposed a project.
|
||||
*
|
||||
* @param email The email of the entrepreneur.
|
||||
* @return true if the entrepreneur has a proposed project, false otherwise.
|
||||
*/
|
||||
public Boolean entrepreneurHasPendingRequestedProject(String email) {
|
||||
User user = this.userService.getUserByEmail(email);
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
Long userId = user.getIdUser();
|
||||
|
||||
Entrepreneur entrepreneur = this.entrepreneurService.getEntrepreneurById(userId);
|
||||
if (entrepreneur == null) {
|
||||
return false;
|
||||
}
|
||||
Project proposedProject = entrepreneur.getProjectProposed();
|
||||
if (entrepreneur.getProjectProposed() == null) {
|
||||
return false;
|
||||
}
|
||||
return proposedProject.getProjectStatus() == PENDING;
|
||||
}
|
||||
}
|
||||
|
@ -72,4 +72,10 @@ public class UtilsService {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean checkEntrepreneurNotPending(String email) {
|
||||
// Throws 404 if user not found
|
||||
User user = userService.getUserByEmail(email);
|
||||
return !user.isPending();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -142,5 +142,56 @@ paths:
|
||||
description: Bad Request - Invalid input or ID mismatch.
|
||||
"401":
|
||||
description: Unauthorized or identity not found
|
||||
"403":
|
||||
description: Bad Token - Invalid Keycloack configuration.
|
||||
|
||||
|
||||
/entrepreneur/projects/project-is-active:
|
||||
get:
|
||||
summary: checks if the project associated with an entrepreneur is active
|
||||
description: returns a boolean if the project associated with an entrepreneur has an active status
|
||||
(i.e has been validated by an admin). The user should be routed to LeanCanvas. any other response code
|
||||
should be treated as false
|
||||
tags:
|
||||
- Entrepreneurs API
|
||||
security:
|
||||
- MyINPulse: [MyINPulse-entrepreneur]
|
||||
parameters:
|
||||
responses:
|
||||
"200":
|
||||
description: OK - got the value successfully any other response code should be treated as false.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: boolean
|
||||
"404":
|
||||
description: Bad Request - Invalid input or ID mismatch.
|
||||
"401":
|
||||
description: Unauthorized or identity not found
|
||||
"403":
|
||||
description: Bad Token - Invalid Keycloack configuration.
|
||||
|
||||
/entrepreneur/projects/has-pending-request:
|
||||
get:
|
||||
summary: checks if the user has a pending projectRequest
|
||||
description: returns a boolean if the project associated with an entrepreneur has a pending status
|
||||
(i.e has not yet been validated by an admin). The user should be routed to a page telling him that he should
|
||||
wait for admin validation. any other response code should be treated as false.
|
||||
tags:
|
||||
- Entrepreneurs API
|
||||
security:
|
||||
- MyINPulse: [MyINPulse-entrepreneur]
|
||||
parameters:
|
||||
responses:
|
||||
"200":
|
||||
description: OK - got the value successfully any other response code should be treated as false.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: boolean
|
||||
"404":
|
||||
description: Bad Request - Invalid input or ID mismatch.
|
||||
"401":
|
||||
description: Unauthorized or identity not found
|
||||
"403":
|
||||
description: Bad Token - Invalid Keycloack configuration.
|
@ -79,6 +79,10 @@ paths:
|
||||
$ref: "./unauthApi.yaml#/paths/~1unauth~1finalize"
|
||||
/unauth/request-join/{projectId}:
|
||||
$ref: "./unauthApi.yaml#/paths/~1unauth~1request-join~1{projectId}"
|
||||
/unauth/request-admin-role:
|
||||
$ref: "./unauthApi.yaml#/paths/~1unauth~1request-admin-role"
|
||||
/unauth/check-if-not-pending:
|
||||
$ref: "./unauthApi.yaml#/paths/~1unauth~1check-if-not-pending"
|
||||
|
||||
# _ ____ __ __ ___ _ _ _ ____ ___
|
||||
# / \ | _ \| \/ |_ _| \ | | / \ | _ \_ _|
|
||||
@ -148,4 +152,8 @@ paths:
|
||||
/entrepreneur/sectionCells:
|
||||
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1sectionCells"
|
||||
/entrepreneur/sectionCells/{sectionCellId}:
|
||||
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1sectionCells~1{sectionCellId}"
|
||||
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1sectionCells~1{sectionCellId}"
|
||||
/entrepreneur/projects/project-is-active:
|
||||
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects~1project-is-active"
|
||||
/entrepreneur/projects/has-pending-request:
|
||||
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1projects~1has-pending-request"
|
@ -53,7 +53,7 @@ paths:
|
||||
description: Bad Token - Invalid Keycloack configuration.
|
||||
/unauth/request-admin-role:
|
||||
post:
|
||||
summary: Request to join an existing project
|
||||
summary: Request to become an admin
|
||||
description: Submits a request for the authenticated user (keycloack authenticated) to become an admin. Their role is then changed to admin in server and Keycloak. This requires approval from a project admin.
|
||||
tags:
|
||||
- Unauth API
|
||||
@ -65,4 +65,26 @@ paths:
|
||||
"401":
|
||||
description: Unauthorized.
|
||||
"403":
|
||||
description: Bad Token - Invalid Keycloack configuration.
|
||||
description: Bad Token - Invalid Keycloack configuration.
|
||||
|
||||
/unauth/check-if-not-pending:
|
||||
get:
|
||||
summary: Returns a boolean of whether the user's account is not pending
|
||||
description: Returns a boolean with value `true` if the user's account is not pending and `false` if it is.
|
||||
tags:
|
||||
- Unauth API
|
||||
responses:
|
||||
"200":
|
||||
description: Accepted - Become admin request submitted and pending approval.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: boolean
|
||||
"400":
|
||||
description: Bad Request - Invalid project ID format or already member/request pending.
|
||||
"401":
|
||||
description: Unauthorized.
|
||||
"404":
|
||||
description: Bad Request - User not found in database.
|
||||
"403":
|
||||
description: Bad Token - Invalid Keycloack configuration.
|
||||
|
@ -1,9 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import { onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { jwtDecode } from "jwt-decode"; // i hope this doesn't break the code later
|
||||
import { store } from "../main.ts";
|
||||
import { callApi } from "@/services/api.ts";
|
||||
import { checkPending } from "@/services/Apis/Unauth";
|
||||
import Header from "@/components/HeaderComponent.vue";
|
||||
const router = useRouter();
|
||||
|
||||
@ -13,7 +13,7 @@ type TokenPayload = {
|
||||
};
|
||||
};
|
||||
|
||||
const customRequest = ref("");
|
||||
//const customRequest = ref("");
|
||||
|
||||
onMounted(() => {
|
||||
if (store.authenticated && store.user.token) {
|
||||
@ -23,26 +23,44 @@ onMounted(() => {
|
||||
|
||||
if (roles.includes("MyINPulse-admin")) {
|
||||
router.push("/admin");
|
||||
} else if (roles.includes("MyINPulse-entrepreneur")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (roles.includes("MyINPulse-entrepreneur")) {
|
||||
router.push("/canvas");
|
||||
return;
|
||||
}
|
||||
else{
|
||||
router.push("/JorCproject")
|
||||
}
|
||||
|
||||
checkPending(
|
||||
(response) => {
|
||||
const isValidated = response.data === true;
|
||||
if (
|
||||
isValidated &&
|
||||
roles.includes("MyINPulse-entrepreneur")
|
||||
) {
|
||||
router.push("/canvas");
|
||||
//router.push("/JorCproject");
|
||||
} else {
|
||||
router.push("/JorCproject");
|
||||
//router.push("/finalize");
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
if (error.response?.status === 403) {
|
||||
router.push("/finalize");
|
||||
} else {
|
||||
console.error(
|
||||
"Unexpected error during checkPending",
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (err) {
|
||||
console.error("Failed to decode token", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
/*
|
||||
const loading = ref(false);
|
||||
|
||||
const callApiWithLoading = async (path: string) => {
|
||||
loading.value = true;
|
||||
await callApi(path);
|
||||
loading.value = false;
|
||||
};
|
||||
*/
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -50,7 +68,7 @@ const callApiWithLoading = async (path: string) => {
|
||||
<error-wrapper></error-wrapper>
|
||||
<div class="auth-container">
|
||||
<div class="auth-card">
|
||||
<h1>Bienvenue</h1>
|
||||
<h1>Bienvenue à MyINPulse</h1>
|
||||
|
||||
<div
|
||||
class="status"
|
||||
@ -68,11 +86,12 @@ const callApiWithLoading = async (path: string) => {
|
||||
<div class="actions">
|
||||
<button @click="store.login">Login</button>
|
||||
<button @click="store.logout">Logout</button>
|
||||
<button @click="store.signup">Signup-admin</button>
|
||||
<!--<button @click="store.signup">Signup-admin</button>
|
||||
<button @click="store.signup">Signup-Entrepreneur</button>
|
||||
<button @click="store.refreshUserToken">Refresh Token</button>
|
||||
<button @click="store.refreshUserToken">Refresh Token</button>-->
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div v-if="store.authenticated" class="token-section">
|
||||
<p><strong>Access Token:</strong></p>
|
||||
<pre>{{ store.user.token }}</pre>
|
||||
@ -96,7 +115,7 @@ const callApiWithLoading = async (path: string) => {
|
||||
/>
|
||||
<button @click="callApi(customRequest)">Call</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -110,7 +110,7 @@ const props = defineProps<{
|
||||
isAdmin: boolean;
|
||||
}>();
|
||||
|
||||
const IS_MOCK_MODE = false;
|
||||
const IS_MOCK_MODE = true;
|
||||
const IS_ADMIN = props.isAdmin;
|
||||
|
||||
const expanded = ref(false);
|
||||
|
@ -40,6 +40,18 @@ const router = createRouter({
|
||||
name: "JorCproject",
|
||||
component: () => import("../views/JoinOrCreatProjectForEntrep.vue"),
|
||||
},
|
||||
|
||||
{
|
||||
path: "/finalize",
|
||||
name: "finalize",
|
||||
component: () => import("../views/FinalizeAccount.vue"),
|
||||
},
|
||||
|
||||
{
|
||||
path: "/pending-approval",
|
||||
name: "PendingApproval",
|
||||
component: () => import("@/views/PendingApproval.vue"),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
@ -123,10 +123,58 @@ function removeSectionCell(
|
||||
});
|
||||
}
|
||||
|
||||
// Checks if the entrepreneur has a pending project request
|
||||
function checkPendingProjectRequest(
|
||||
onSuccessHandler?: (response: AxiosResponse<boolean>) => void,
|
||||
onErrorHandler?: (error: AxiosError) => void
|
||||
): void {
|
||||
axiosInstance
|
||||
.get("/entrepreneur/projects/has-pending-request")
|
||||
.then((response) => {
|
||||
if (onSuccessHandler) {
|
||||
onSuccessHandler(response);
|
||||
} else {
|
||||
defaultApiSuccessHandler(response);
|
||||
}
|
||||
})
|
||||
.catch((error: AxiosError) => {
|
||||
if (onErrorHandler) {
|
||||
onErrorHandler(error);
|
||||
} else {
|
||||
defaultApiErrorHandler(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Checks if the entrepreneur has an active project
|
||||
function checkIfProjectIsActive(
|
||||
onSuccessHandler?: (response: AxiosResponse<boolean>) => void,
|
||||
onErrorHandler?: (error: AxiosError) => void
|
||||
): void {
|
||||
axiosInstance
|
||||
.get("/entrepreneur/projects/project-is-active")
|
||||
.then((response) => {
|
||||
if (onSuccessHandler) {
|
||||
onSuccessHandler(response);
|
||||
} else {
|
||||
defaultApiSuccessHandler(response);
|
||||
}
|
||||
})
|
||||
.catch((error: AxiosError) => {
|
||||
if (onErrorHandler) {
|
||||
onErrorHandler(error);
|
||||
} else {
|
||||
defaultApiErrorHandler(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export {
|
||||
getEntrepreneurProjectId,
|
||||
requestProjectCreation,
|
||||
addSectionCell,
|
||||
modifySectionCell,
|
||||
removeSectionCell,
|
||||
checkPendingProjectRequest,
|
||||
checkIfProjectIsActive,
|
||||
};
|
||||
|
@ -74,8 +74,30 @@ function getAllEntrepreneurs(
|
||||
});
|
||||
}
|
||||
|
||||
function checkPending(
|
||||
onSuccessHandler?: (response: AxiosResponse<boolean>) => void,
|
||||
onErrorHandler?: (error: AxiosError) => void
|
||||
): void {
|
||||
axiosInstance
|
||||
.get("/unauth/check-if-not-pending")
|
||||
.then((response) => {
|
||||
if (onSuccessHandler) {
|
||||
onSuccessHandler(response);
|
||||
} else {
|
||||
defaultApiSuccessHandler(response);
|
||||
}
|
||||
})
|
||||
.catch((error: AxiosError) => {
|
||||
if (onErrorHandler) {
|
||||
onErrorHandler(error);
|
||||
} else {
|
||||
defaultApiErrorHandler(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
export {
|
||||
finalizeAccount,
|
||||
getAllEntrepreneurs,
|
||||
checkPending,
|
||||
// requestJoinProject, // Not yet implemented [cite: 4]
|
||||
};
|
||||
|
@ -70,7 +70,6 @@ const fallbackProjects = [
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const createFirstAdmin = () => {
|
||||
createAdmin(
|
||||
(response) => {
|
||||
@ -85,7 +84,7 @@ const createFirstAdmin = () => {
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(createFirstAdmin)
|
||||
onMounted(createFirstAdmin);
|
||||
|
||||
const fetchProjects = () => {
|
||||
getAdminProjects(
|
||||
|
81
front/MyINPulse-front/src/views/FinalizeAccount.vue
Normal file
81
front/MyINPulse-front/src/views/FinalizeAccount.vue
Normal file
@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="finalize-page">
|
||||
<div class="loader-container">
|
||||
<button class="return-button" @click="store.logout">Logout</button>
|
||||
<div class="spinner"></div>
|
||||
<p>Finalisation du compte en cours...</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from "vue";
|
||||
//import { useRouter } from "vue-router";
|
||||
import { finalizeAccount } from "@/services/Apis/Unauth";
|
||||
import Header from "@/components/HeaderComponent.vue";
|
||||
import { store } from "@/main.ts";
|
||||
//const router = useRouter();
|
||||
|
||||
onMounted(() => {
|
||||
finalizeAccount(
|
||||
() => {
|
||||
console.log("finalize sended");
|
||||
},
|
||||
(error) => {
|
||||
console.error("Erreur lors de la finalisation :", error);
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.finalize-page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 80vh;
|
||||
background-color: #f9fbfd;
|
||||
}
|
||||
|
||||
.loader-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
color: #333;
|
||||
font-size: 1.1rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border: 5px solid #cfd8dc;
|
||||
border-top: 5px solid #3498db;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
.return-button {
|
||||
background-color: #009cde;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
border-radius: 5px;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s ease;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,10 +1,12 @@
|
||||
<template>
|
||||
<Header />
|
||||
<header class="header">
|
||||
<img
|
||||
src="@/components/icons/logo inpulse.png"
|
||||
alt="INPulse Logo"
|
||||
class="logo"
|
||||
/>
|
||||
<button class="return-button" @click="store.logout">Logout</button>
|
||||
</header>
|
||||
|
||||
<div class="choix-projet">
|
||||
@ -39,10 +41,18 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import Project from "@/ApiClasses/Project";
|
||||
import { requestProjectCreation } from "@/services/Apis/Entrepreneurs.ts";
|
||||
import Header from "../components/HeaderComponent.vue";
|
||||
import { store } from "@/main.ts";
|
||||
import {
|
||||
requestProjectCreation,
|
||||
checkIfProjectIsActive,
|
||||
checkPendingProjectRequest,
|
||||
} from "@/services/Apis/Entrepreneurs";
|
||||
|
||||
const router = useRouter();
|
||||
const choix = ref<string | null>(null);
|
||||
const nomProjet = ref("");
|
||||
|
||||
@ -56,21 +66,18 @@ const validerCreation = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Obtenir la date actuelle au format YYYY-MM-DD
|
||||
const today = new Date();
|
||||
const yyyy = today.getFullYear();
|
||||
const mm = String(today.getMonth() + 1).padStart(2, "0");
|
||||
const dd = String(today.getDate()).padStart(2, "0");
|
||||
const formattedDate = `${yyyy}-${mm}-${dd}`;
|
||||
|
||||
// Créer une instance de Project
|
||||
const nouveauProjet = new Project({
|
||||
projectName: nomProjet.value.trim(),
|
||||
creationDate: formattedDate,
|
||||
status: "PENDING",
|
||||
});
|
||||
|
||||
// Appeler l’API
|
||||
requestProjectCreation(
|
||||
nouveauProjet,
|
||||
(response) => {
|
||||
@ -83,6 +90,28 @@ const validerCreation = () => {
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
checkIfProjectIsActive(
|
||||
(response) => {
|
||||
if (response.data === true) {
|
||||
router.push("/canvas");
|
||||
}
|
||||
},
|
||||
() => {
|
||||
checkPendingProjectRequest(
|
||||
(response) => {
|
||||
if (response.data === true) {
|
||||
router.push("/pending-approval");
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
console.warn("No active or pending project:", error);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@ -140,4 +169,17 @@ input {
|
||||
.logo {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.return-button {
|
||||
background-color: #009cde;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
border-radius: 5px;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s ease;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
</style>
|
||||
|
41
front/MyINPulse-front/src/views/PendingApproval.vue
Normal file
41
front/MyINPulse-front/src/views/PendingApproval.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<Header />
|
||||
<div class="pending-container">
|
||||
<h1>Projet en attente de validation</h1>
|
||||
<p>
|
||||
Votre demande de création de projet a bien été reçue.<br />
|
||||
Un administrateur doit valider votre projet avant que vous puissiez
|
||||
continuer.
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Header from "@/components/HeaderComponent.vue";
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pending-container {
|
||||
max-width: 600px;
|
||||
margin: 100px auto;
|
||||
padding: 2rem;
|
||||
text-align: center;
|
||||
background-color: #fffdf8;
|
||||
border: 1px solid #ececec;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
|
||||
font-family: "Inter", sans-serif;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #f57c00;
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.1rem;
|
||||
color: #333;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user