Compare commits
19 Commits
7fc06035c7
...
main
Author | SHA1 | Date | |
---|---|---|---|
a35a423447 | |||
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) {
|
@RequestBody Project project, @AuthenticationPrincipal Jwt principal) {
|
||||||
entrepreneurApiService.requestNewProject(project, principal.getClaimAsString("email"));
|
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;
|
package enseirb.myinpulse.controller;
|
||||||
|
|
||||||
import enseirb.myinpulse.model.Administrator;
|
|
||||||
import enseirb.myinpulse.model.Entrepreneur;
|
import enseirb.myinpulse.model.Entrepreneur;
|
||||||
import enseirb.myinpulse.service.AdminApiService;
|
|
||||||
import enseirb.myinpulse.service.EntrepreneurApiService;
|
import enseirb.myinpulse.service.EntrepreneurApiService;
|
||||||
|
import enseirb.myinpulse.service.UtilsService;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
@ -16,15 +15,15 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
public class UnauthApi {
|
public class UnauthApi {
|
||||||
|
|
||||||
private final EntrepreneurApiService entrepreneurApiService;
|
private final EntrepreneurApiService entrepreneurApiService;
|
||||||
private final AdminApiService adminApiService;
|
private final UtilsService utilsService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
UnauthApi(EntrepreneurApiService entrepreneurApiService, AdminApiService administratorService) {
|
UnauthApi(EntrepreneurApiService entrepreneurApiService, UtilsService utilsService) {
|
||||||
this.entrepreneurApiService = entrepreneurApiService;
|
this.entrepreneurApiService = entrepreneurApiService;
|
||||||
this.adminApiService = administratorService;
|
this.utilsService = utilsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/unauth/finalize")
|
@PostMapping("/unauth/finalize")
|
||||||
public void createAccount(@AuthenticationPrincipal Jwt principal) {
|
public void createAccount(@AuthenticationPrincipal Jwt principal) {
|
||||||
boolean sneeStatus;
|
boolean sneeStatus;
|
||||||
if (principal.getClaimAsString("sneeStatus") != null) {
|
if (principal.getClaimAsString("sneeStatus") != null) {
|
||||||
@ -50,21 +49,13 @@ public class UnauthApi {
|
|||||||
course,
|
course,
|
||||||
sneeStatus,
|
sneeStatus,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
entrepreneurApiService.createAccount(e);
|
entrepreneurApiService.createAccount(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
@GetMapping("/unauth/check-if-not-pending")
|
||||||
* These bottom endpoints are meant for testing only
|
public Boolean checkAccountStatus(@AuthenticationPrincipal Jwt principal) {
|
||||||
* and should not py merged to main
|
// Throws 404 if user not found
|
||||||
*
|
return utilsService.checkEntrepreneurNotPending(principal.getClaimAsString("email"));
|
||||||
*/
|
|
||||||
@GetMapping("/unauth/getAllAdmins")
|
|
||||||
public Iterable<Administrator> getEveryAdmin() {
|
|
||||||
return this.adminApiService.getAllAdmins();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/unauth/getAllEntrepreneurs")
|
|
||||||
public Iterable<Entrepreneur> getEveryEntrepreneur() {
|
|
||||||
return this.entrepreneurApiService.getAllEntrepreneurs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package enseirb.myinpulse.service;
|
package enseirb.myinpulse.service;
|
||||||
|
|
||||||
import static enseirb.myinpulse.model.ProjectDecisionValue.PENDING;
|
import static enseirb.myinpulse.model.ProjectDecisionValue.PENDING;
|
||||||
|
import static enseirb.myinpulse.model.ProjectDecisionValue.ACTIVE;
|
||||||
|
|
||||||
import enseirb.myinpulse.model.Entrepreneur;
|
import enseirb.myinpulse.model.Entrepreneur;
|
||||||
import enseirb.myinpulse.model.Project;
|
import enseirb.myinpulse.model.Project;
|
||||||
import enseirb.myinpulse.model.SectionCell;
|
import enseirb.myinpulse.model.SectionCell;
|
||||||
|
import enseirb.myinpulse.model.User;
|
||||||
import enseirb.myinpulse.service.database.*;
|
import enseirb.myinpulse.service.database.*;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@ -234,4 +236,49 @@ public class EntrepreneurApiService {
|
|||||||
public Iterable<Entrepreneur> getAllEntrepreneurs() {
|
public Iterable<Entrepreneur> getAllEntrepreneurs() {
|
||||||
return entrepreneurService.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;
|
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
@ -144,3 +144,54 @@ paths:
|
|||||||
description: Unauthorized or identity not found
|
description: Unauthorized or identity not found
|
||||||
"403":
|
"403":
|
||||||
description: Bad Token - Invalid Keycloack configuration.
|
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"
|
$ref: "./unauthApi.yaml#/paths/~1unauth~1finalize"
|
||||||
/unauth/request-join/{projectId}:
|
/unauth/request-join/{projectId}:
|
||||||
$ref: "./unauthApi.yaml#/paths/~1unauth~1request-join~1{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"
|
||||||
|
|
||||||
# _ ____ __ __ ___ _ _ _ ____ ___
|
# _ ____ __ __ ___ _ _ _ ____ ___
|
||||||
# / \ | _ \| \/ |_ _| \ | | / \ | _ \_ _|
|
# / \ | _ \| \/ |_ _| \ | | / \ | _ \_ _|
|
||||||
@ -149,3 +153,7 @@ paths:
|
|||||||
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1sectionCells"
|
$ref: "./entrepreneurApi.yaml#/paths/~1entrepreneur~1sectionCells"
|
||||||
/entrepreneur/sectionCells/{sectionCellId}:
|
/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.
|
description: Bad Token - Invalid Keycloack configuration.
|
||||||
/unauth/request-admin-role:
|
/unauth/request-admin-role:
|
||||||
post:
|
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.
|
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:
|
tags:
|
||||||
- Unauth API
|
- Unauth API
|
||||||
@ -66,3 +66,25 @@ paths:
|
|||||||
description: Unauthorized.
|
description: Unauthorized.
|
||||||
"403":
|
"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>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted } from "vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { jwtDecode } from "jwt-decode"; // i hope this doesn't break the code later
|
import { jwtDecode } from "jwt-decode"; // i hope this doesn't break the code later
|
||||||
import { store } from "../main.ts";
|
import { store } from "../main.ts";
|
||||||
import { callApi } from "@/services/api.ts";
|
import { checkPending } from "@/services/Apis/Unauth";
|
||||||
import Header from "@/components/HeaderComponent.vue";
|
import Header from "@/components/HeaderComponent.vue";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ type TokenPayload = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const customRequest = ref("");
|
//const customRequest = ref("");
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (store.authenticated && store.user.token) {
|
if (store.authenticated && store.user.token) {
|
||||||
@ -23,26 +23,44 @@ onMounted(() => {
|
|||||||
|
|
||||||
if (roles.includes("MyINPulse-admin")) {
|
if (roles.includes("MyINPulse-admin")) {
|
||||||
router.push("/admin");
|
router.push("/admin");
|
||||||
} else if (roles.includes("MyINPulse-entrepreneur")) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roles.includes("MyINPulse-entrepreneur")) {
|
||||||
router.push("/canvas");
|
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) {
|
} catch (err) {
|
||||||
console.error("Failed to decode token", 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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -50,7 +68,7 @@ const callApiWithLoading = async (path: string) => {
|
|||||||
<error-wrapper></error-wrapper>
|
<error-wrapper></error-wrapper>
|
||||||
<div class="auth-container">
|
<div class="auth-container">
|
||||||
<div class="auth-card">
|
<div class="auth-card">
|
||||||
<h1>Bienvenue</h1>
|
<h1>Bienvenue à MyINPulse</h1>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="status"
|
class="status"
|
||||||
@ -68,11 +86,12 @@ const callApiWithLoading = async (path: string) => {
|
|||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button @click="store.login">Login</button>
|
<button @click="store.login">Login</button>
|
||||||
<button @click="store.logout">Logout</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.signup">Signup-Entrepreneur</button>
|
||||||
<button @click="store.refreshUserToken">Refresh Token</button>
|
<button @click="store.refreshUserToken">Refresh Token</button>-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
<div v-if="store.authenticated" class="token-section">
|
<div v-if="store.authenticated" class="token-section">
|
||||||
<p><strong>Access Token:</strong></p>
|
<p><strong>Access Token:</strong></p>
|
||||||
<pre>{{ store.user.token }}</pre>
|
<pre>{{ store.user.token }}</pre>
|
||||||
@ -96,7 +115,7 @@ const callApiWithLoading = async (path: string) => {
|
|||||||
/>
|
/>
|
||||||
<button @click="callApi(customRequest)">Call</button>
|
<button @click="callApi(customRequest)">Call</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -110,7 +110,7 @@ const props = defineProps<{
|
|||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const IS_MOCK_MODE = false;
|
const IS_MOCK_MODE = true;
|
||||||
const IS_ADMIN = props.isAdmin;
|
const IS_ADMIN = props.isAdmin;
|
||||||
|
|
||||||
const expanded = ref(false);
|
const expanded = ref(false);
|
||||||
|
@ -40,6 +40,18 @@ const router = createRouter({
|
|||||||
name: "JorCproject",
|
name: "JorCproject",
|
||||||
component: () => import("../views/JoinOrCreatProjectForEntrep.vue"),
|
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 {
|
export {
|
||||||
getEntrepreneurProjectId,
|
getEntrepreneurProjectId,
|
||||||
requestProjectCreation,
|
requestProjectCreation,
|
||||||
addSectionCell,
|
addSectionCell,
|
||||||
modifySectionCell,
|
modifySectionCell,
|
||||||
removeSectionCell,
|
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 {
|
export {
|
||||||
finalizeAccount,
|
finalizeAccount,
|
||||||
getAllEntrepreneurs,
|
getAllEntrepreneurs,
|
||||||
|
checkPending,
|
||||||
// requestJoinProject, // Not yet implemented [cite: 4]
|
// requestJoinProject, // Not yet implemented [cite: 4]
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,6 @@ const fallbackProjects = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
const createFirstAdmin = () => {
|
const createFirstAdmin = () => {
|
||||||
createAdmin(
|
createAdmin(
|
||||||
(response) => {
|
(response) => {
|
||||||
@ -85,7 +84,7 @@ const createFirstAdmin = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(createFirstAdmin)
|
onMounted(createFirstAdmin);
|
||||||
|
|
||||||
const fetchProjects = () => {
|
const fetchProjects = () => {
|
||||||
getAdminProjects(
|
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>
|
<template>
|
||||||
|
<Header />
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<img
|
<img
|
||||||
src="@/components/icons/logo inpulse.png"
|
src="@/components/icons/logo inpulse.png"
|
||||||
alt="INPulse Logo"
|
alt="INPulse Logo"
|
||||||
class="logo"
|
class="logo"
|
||||||
/>
|
/>
|
||||||
|
<button class="return-button" @click="store.logout">Logout</button>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="choix-projet">
|
<div class="choix-projet">
|
||||||
@ -39,10 +41,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
import Project from "@/ApiClasses/Project";
|
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 choix = ref<string | null>(null);
|
||||||
const nomProjet = ref("");
|
const nomProjet = ref("");
|
||||||
|
|
||||||
@ -56,21 +66,18 @@ const validerCreation = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Obtenir la date actuelle au format YYYY-MM-DD
|
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const yyyy = today.getFullYear();
|
const yyyy = today.getFullYear();
|
||||||
const mm = String(today.getMonth() + 1).padStart(2, "0");
|
const mm = String(today.getMonth() + 1).padStart(2, "0");
|
||||||
const dd = String(today.getDate()).padStart(2, "0");
|
const dd = String(today.getDate()).padStart(2, "0");
|
||||||
const formattedDate = `${yyyy}-${mm}-${dd}`;
|
const formattedDate = `${yyyy}-${mm}-${dd}`;
|
||||||
|
|
||||||
// Créer une instance de Project
|
|
||||||
const nouveauProjet = new Project({
|
const nouveauProjet = new Project({
|
||||||
projectName: nomProjet.value.trim(),
|
projectName: nomProjet.value.trim(),
|
||||||
creationDate: formattedDate,
|
creationDate: formattedDate,
|
||||||
status: "PENDING",
|
status: "PENDING",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Appeler l’API
|
|
||||||
requestProjectCreation(
|
requestProjectCreation(
|
||||||
nouveauProjet,
|
nouveauProjet,
|
||||||
(response) => {
|
(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>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -140,4 +169,17 @@ input {
|
|||||||
.logo {
|
.logo {
|
||||||
height: 50px;
|
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>
|
</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