diff --git a/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.css b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.css new file mode 100644 index 0000000..5392357 --- /dev/null +++ b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.css @@ -0,0 +1,191 @@ +.feedback-button { + background: #ecf3fa; + color: #083b7d; + padding: 8px; + border-radius: 8px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + transform: rotate(270deg); + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + + margin-right: -35px; + position: fixed; + right: 0; + top: 240px; + z-index: 100; + + &:hover { + background: #d9e8f6; + } + + i { + font-size: 16px; + } +} + +// Modal styles + .feedback-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + } + +.feedback-modal { + background: white; + border-radius: 8px; + width: 90%; + max-width: 500px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); + display: flex; + flex-direction: column; + max-height: 90vh; + overflow: hidden; +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 20px; + border-bottom: 1px solid #eee; + + h3 { + margin: 0; + font-size: 18px; + font-weight: 600; + color: #083b7d; + } + + .close-button { + background: none; + border: none; + cursor: pointer; + font-size: 20px; + color: #666; + padding: 4px; + + &:hover { + color: #333; + } + } +} + +.modal-body { + padding: 20px; + overflow-y: auto; + + .modal-description { + margin-bottom: 16px; + color: #555; + } + + textarea { + width: 100%; + padding: 12px; + border: 1px solid #ddd; + border-radius: 4px; + resize: vertical; + font-family: inherit; + font-size: 14px; + + &:focus { + outline: none; + border-color: #083b7d; + } + + &:disabled { + background-color: #f5f5f5; + cursor: not-allowed; + } + } + + .success-message, .error-message { + margin-top: 16px; + padding: 10px; + border-radius: 4px; + display: flex; + align-items: center; + gap: 8px; + + i { + font-size: 18px; + } + } + + .success-message { + background-color: #e6f7e6; + color: #2e7d32; + } + + .error-message { + background-color: #fdecea; + color: #d32f2f; + } +} + +.modal-footer { + padding: 16px 20px; + border-top: 1px solid #eee; + display: flex; + justify-content: flex-end; + gap: 12px; + + button { + padding: 8px 16px; + border-radius: 4px; + font-weight: 500; + cursor: pointer; + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + } + + .cancel-button { + background: none; + border: 1px solid #ddd; + color: #555; + + &:hover:not(:disabled) { + background-color: #f5f5f5; + } + } + + .submit-button { + background-color: #083b7d; + color: white; + border: none; + display: flex; + align-items: center; + gap: 8px; + + &:hover:not(:disabled) { + background-color: #062c5e; + } + } +} + +// Spinner animation + .spinning { + animation: spin 1s linear infinite; + } + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.html b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.html new file mode 100644 index 0000000..fedcd4d --- /dev/null +++ b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.html @@ -0,0 +1,67 @@ + + + +@if (isModalOpen) { +
+
+ + + + + +
+
+} diff --git a/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.scss b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.scss new file mode 100644 index 0000000..3eebdf1 --- /dev/null +++ b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.scss @@ -0,0 +1,192 @@ +.feedback-button { + background: #ecf3fa; + color: #083b7d; + padding: 8px; + border-radius: 8px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + transform: rotate(270deg); + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + + margin-right: -35px; + position: fixed; + right: 0; + top: 240px; + z-index: 100; + + &:hover { + background: #d9e8f6; + } + + i { + font-size: 16px; + } +} + +// Modal styles +.feedback-modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; + +} + +.feedback-modal { + background: white; + border-radius: 8px; + width: 90%; + max-width: 500px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); + display: flex; + flex-direction: column; + max-height: 90vh; + overflow: hidden; +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 20px; + border-bottom: 1px solid #eee; + + h3 { + margin: 0; + font-size: 18px; + font-weight: 600; + color: #083b7d; + } + + .close-button { + background: none; + border: none; + cursor: pointer; + font-size: 20px; + color: #666; + padding: 4px; + + &:hover { + color: #333; + } + } +} + +.modal-body { + padding: 20px; + overflow-y: auto; + + .modal-description { + margin-bottom: 16px; + color: #555; + } + + textarea { + width: 100%; + padding: 12px; + border: 1px solid #ddd; + border-radius: 4px; + resize: vertical; + font-family: inherit; + font-size: 14px; + + &:focus { + outline: none; + border-color: #083b7d; + } + + &:disabled { + background-color: #f5f5f5; + cursor: not-allowed; + } + } + + .success-message, .error-message { + margin-top: 16px; + padding: 10px; + border-radius: 4px; + display: flex; + align-items: center; + gap: 8px; + + i { + font-size: 18px; + } + } + + .success-message { + background-color: #e6f7e6; + color: #2e7d32; + } + + .error-message { + background-color: #fdecea; + color: #d32f2f; + } +} + +.modal-footer { + padding: 16px 20px; + border-top: 1px solid #eee; + display: flex; + justify-content: flex-end; + gap: 12px; + + button { + padding: 8px 16px; + border-radius: 4px; + font-weight: 500; + cursor: pointer; + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } + } + + .cancel-button { + background: none; + border: 1px solid #ddd; + color: #555; + + &:hover:not(:disabled) { + background-color: #f5f5f5; + } + } + + .submit-button { + background-color: #083b7d; + color: white; + border: none; + display: flex; + align-items: center; + gap: 8px; + + &:hover:not(:disabled) { + background-color: #062c5e; + } + } +} + +// Spinner animation +.spinning { + animation: spin 1s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.spec.ts b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.spec.ts new file mode 100644 index 0000000..6416212 --- /dev/null +++ b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { FeedbackButton } from './feedback-button'; + +describe('FeedbackButton', () => { + let component: FeedbackButton; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FeedbackButton] + }) + .compileComponents(); + + fixture = TestBed.createComponent(FeedbackButton); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.ts b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.ts new file mode 100644 index 0000000..3914445 --- /dev/null +++ b/my-workspace/projects/sae-lib/buttons/feedback-button/feedback-button.ts @@ -0,0 +1,88 @@ +import {Component} from '@angular/core'; +import {FormsModule} from '@angular/forms'; + +@Component({ + selector: 'sae-feedback-button', + imports: [ + FormsModule + ], + templateUrl: './feedback-button.html', + styleUrl: './feedback-button.css' +}) + +export class FeedbackButton { + isModalOpen: boolean = false; + feedbackText: string = ''; + isSubmitting: boolean = false; + submitSuccess: boolean = false; + submitError: boolean = false; + + // constructor( + // private store: Store, + // private apiService: ApiService + // ) { + // } + + toggleModal() { + this.isModalOpen = !this.isModalOpen; + + // Reset state when opening modal + if (this.isModalOpen) { + this.feedbackText = ''; + this.submitSuccess = false; + this.submitError = false; + } + + // Update app state to show/hide feedback panel + // this.store.dispatch({ + // type: ActionTypes.UPDATE_APP, + // payload: { + // displayFeedBackPanel: this.isModalOpen, + // feedBackInput: this.feedbackText + // } + // }); + } + + async submitFeedback() { + if (!this.feedbackText.trim()) { + return; // Don't submit empty feedback + } + + this.isSubmitting = true; + this.submitSuccess = false; + this.submitError = false; + + try { + // Update Redux state with feedback text + // this.store.dispatch({ + // type: ActionTypes.UPDATE_APP, + // payload: { + // feedBackInput: this.feedbackText + // } + // }); + // + // // Dispatch action to send feedback + // this.store.dispatch({ + // type: ActionTypes.SEND_USER_FEEDBACK, + // payload: { + // feedback: this.feedbackText + // } + // }); + // + // // Call API service directly + // await this.apiService.sendUserFeedback(this.feedbackText); + + this.submitSuccess = true; + + // Close modal after a short delay + setTimeout(() => { + this.toggleModal(); + }, 2000); + } catch (error) { + console.error('Error submitting feedback:', error); + this.submitError = true; + } finally { + this.isSubmitting = false; + } + } +} diff --git a/sae-csc/src/app/app.html b/sae-csc/src/app/app.html index af3fe92..64e2f33 100644 --- a/sae-csc/src/app/app.html +++ b/sae-csc/src/app/app.html @@ -3,11 +3,13 @@ CSC implémentation +

logo CSC

+ diff --git a/sae-csc/src/app/app.ts b/sae-csc/src/app/app.ts index 0ef8a71..4b84cfb 100644 --- a/sae-csc/src/app/app.ts +++ b/sae-csc/src/app/app.ts @@ -1,10 +1,12 @@ import { Component, signal } from '@angular/core'; import { RouterOutlet } from '@angular/router'; +import {TopNavigation} from './shared/navigation/top-navigation/top-navigation'; +import {FeedbackButton} from 'sae-lib/buttons/feedback-button/feedback-button'; // import {SaeLib} from '@sae-lib/src/public-api'; @Component({ selector: 'app-root', - imports: [RouterOutlet], + imports: [RouterOutlet, TopNavigation, FeedbackButton], templateUrl: './app.html', styleUrl: './app.scss' }) diff --git a/sae-csc/src/app/pages/main/main.html b/sae-csc/src/app/pages/main/main.html index fdab153..f906640 100644 --- a/sae-csc/src/app/pages/main/main.html +++ b/sae-csc/src/app/pages/main/main.html @@ -1,5 +1,4 @@
-

diff --git a/sae-csc/src/app/pages/main/main.ts b/sae-csc/src/app/pages/main/main.ts index bf43fe9..f44385e 100644 --- a/sae-csc/src/app/pages/main/main.ts +++ b/sae-csc/src/app/pages/main/main.ts @@ -8,7 +8,6 @@ import {BottomNavigation} from '../../shared/navigation/bottom-navigation/bottom @Component({ selector: 'app-main', imports: [ - TopNavigation, TranslateTexts, FiltersGroup, BottomNavigation diff --git a/sae-csc/src/app/redux/csc.types.ts b/sae-csc/src/app/redux/csc.types.ts new file mode 100644 index 0000000..93ae6d1 --- /dev/null +++ b/sae-csc/src/app/redux/csc.types.ts @@ -0,0 +1,9 @@ +export type CscCase = { + +}; +export type TechManual = { + +}; +export type filterListing = { + +}; diff --git a/sae-csc/src/app/redux/initialState.ts b/sae-csc/src/app/redux/initialState.ts index a8d8573..9b020c3 100644 --- a/sae-csc/src/app/redux/initialState.ts +++ b/sae-csc/src/app/redux/initialState.ts @@ -5,7 +5,7 @@ import {StateInterface} from './reducers'; export const initialState: StateInterface = { app: { backendAPIRoot: "", - demoMode: true, // selon l'environnement + demoMode: true, }, currentLang: "fr_FR", currentTheme: "light", diff --git a/sae-csc/src/styles/_variables-barrel.scss b/sae-csc/src/styles/_variables-barrel.scss index fdeca2d..e6c6bb4 100644 --- a/sae-csc/src/styles/_variables-barrel.scss +++ b/sae-csc/src/styles/_variables-barrel.scss @@ -1,2 +1,6 @@ // Ce fichier regroupe toutes les variables de sae-lib pour faciliter l'importation @forward 'sae-lib/src/styles/variables.scss'; + +.all-pages{ + padding: 50px 64px; +} diff --git a/sae-csc/src/styles/app/styles/pages/_admin.scss b/sae-csc/src/styles/app/styles/pages/_admin.scss new file mode 100644 index 0000000..e69de29 diff --git a/sae-csc/src/styles/app/styles/pages/_main.scss b/sae-csc/src/styles/app/styles/pages/_main.scss index d91b2d4..3cbb90b 100644 --- a/sae-csc/src/styles/app/styles/pages/_main.scss +++ b/sae-csc/src/styles/app/styles/pages/_main.scss @@ -2,7 +2,7 @@ #main_page { main { - padding: 50px 64px; + @extend .all-pages; .title { font-size: 20px; @@ -143,6 +143,8 @@ justify-content: flex-end; align-items: center; background: white; + left: 0; + z-index: 100; box-shadow: 0 -10px 20px 0 rgba(30, 31, 34, 0.05); diff --git a/sae-csc/src/styles/app/styles/pages/_similar-cases.scss b/sae-csc/src/styles/app/styles/pages/_similar-cases.scss new file mode 100644 index 0000000..c773949 --- /dev/null +++ b/sae-csc/src/styles/app/styles/pages/_similar-cases.scss @@ -0,0 +1,5 @@ + @use '../../../../styles/variables-barrel' as variables; + +.similar-cases{ + @extend .all-pages; +} diff --git a/sae-csc/src/styles/main.scss b/sae-csc/src/styles/main.scss index 494462d..1ab68fd 100644 --- a/sae-csc/src/styles/main.scss +++ b/sae-csc/src/styles/main.scss @@ -1,2 +1,4 @@ @use "app/styles/pages/main.scss"; +@use "app/styles/pages/similar-cases.scss"; +@use "app/styles/pages/admin.scss";