diff --git a/angular.json b/angular.json index c1c4dfe..9f1698b 100644 --- a/angular.json +++ b/angular.json @@ -91,5 +91,8 @@ } } } + }, + "cli": { + "analytics": false } } diff --git a/package-lock.json b/package-lock.json index b2c9076..6f5be49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,11 @@ "@angular/platform-browser": "^17.0.1", "@angular/platform-browser-dynamic": "^17.0.1", "@angular/router": "^17.0.1", + "@ctrl/ngx-codemirror": "^7.0.0", "@emailjs/browser": "^3.11.0", + "@ngx-translate/core": "^15.0.0", + "@ngx-translate/http-loader": "^8.0.0", + "codemirror": "^5.65.16", "rxjs": "~7.8.1", "tslib": "^2.6.2", "zone.js": "~0.14.2" @@ -2197,6 +2201,20 @@ "node": ">=0.1.90" } }, + "node_modules/@ctrl/ngx-codemirror": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@ctrl/ngx-codemirror/-/ngx-codemirror-7.0.0.tgz", + "integrity": "sha512-qvIWtSTw/8fdXDnofBTX6LmTW9646HhawG2+Qyagf1vH40jCy0ZbHnkC20UYOVpUX+QCd1e/PQpkvWQ/1iGFzQ==", + "dependencies": { + "@types/codemirror": "^5.60.7", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/core": ">=16.0.0-0", + "@angular/forms": ">=16.0.0-0", + "codemirror": "^5.65.9" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -2788,6 +2806,33 @@ "webpack": "^5.54.0" } }, + "node_modules/@ngx-translate/core": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-15.0.0.tgz", + "integrity": "sha512-Am5uiuR0bOOxyoercDnAA3rJVizo4RRqJHo8N3RqJ+XfzVP/I845yEnMADykOHvM6HkVm4SZSnJBOiz0Anx5BA==", + "engines": { + "node": "^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0", + "@angular/core": ">=16.0.0", + "rxjs": "^6.5.5 || ^7.4.0" + } + }, + "node_modules/@ngx-translate/http-loader": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-8.0.0.tgz", + "integrity": "sha512-SFMsdUcmHF5OdZkL1CHEoSAwbP5EbAOPTLLboOCRRoOg21P4GJx+51jxGdJeGve6LSKLf4Pay7BkTwmE6vxYlg==", + "engines": { + "node": "^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0", + "@angular/core": ">=16.0.0", + "@ngx-translate/core": ">=15.0.0", + "rxjs": "^6.5.5 || ^7.4.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3158,6 +3203,14 @@ "@types/node": "*" } }, + "node_modules/@types/codemirror": { + "version": "5.60.15", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", + "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", + "dependencies": { + "@types/tern": "*" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -3215,8 +3268,7 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, "node_modules/@types/express": { "version": "4.17.21", @@ -3350,6 +3402,14 @@ "@types/node": "*" } }, + "node_modules/@types/tern": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", + "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/@types/ws": { "version": "8.5.9", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.9.tgz", @@ -4706,6 +4766,11 @@ "node": ">=6" } }, + "node_modules/codemirror": { + "version": "5.65.16", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", + "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==" + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", diff --git a/package.json b/package.json index c58c4fd..f8150a9 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,11 @@ "@angular/platform-browser": "^17.0.1", "@angular/platform-browser-dynamic": "^17.0.1", "@angular/router": "^17.0.1", + "@ctrl/ngx-codemirror": "^7.0.0", "@emailjs/browser": "^3.11.0", + "@ngx-translate/core": "^15.0.0", + "@ngx-translate/http-loader": "^8.0.0", + "codemirror": "^5.65.16", "rxjs": "~7.8.1", "tslib": "^2.6.2", "zone.js": "~0.14.2" diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 230837e..28e67fa 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,4 +1,5 @@ import { Component } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'app-root', @@ -6,5 +7,4 @@ import { Component } from '@angular/core'; styleUrls: ['./app.component.css'] }) export class AppComponent { - } \ No newline at end of file diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 2c5f5ad..1928cb6 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -12,7 +12,13 @@ import { DocumentationComponent } from './documentation/documentation.component' import { FormComponent } from './form/form.component'; import { ReactiveFormsModule } from '@angular/forms'; +import { FormsModule } from '@angular/forms'; +import { CodemirrorModule } from '@ctrl/ngx-codemirror'; +import { HttpClient, HttpClientModule } from '@angular/common/http'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +import { TranslationService } from './service/translation.service'; @NgModule({ declarations: [ @@ -28,9 +34,30 @@ import { ReactiveFormsModule } from '@angular/forms'; imports: [ BrowserModule, AppRoutingModule, - ReactiveFormsModule + ReactiveFormsModule, + FormsModule, + CodemirrorModule, + // Injection des HttpClient pour notre module de traduction + HttpClientModule, + // Initialisation du module de traduction + TranslateModule.forRoot({ + // Manière dont on charge les fichiers de traduction + loader: { + provide: TranslateLoader, + // On utiilise une fonction pour charger les fichiers de traduction + useFactory: (createTranslateLoader), + // deps permets de savoir ce dont on a besoin pour charger les fichiers de traduction + deps: [HttpClient] + }, + defaultLanguage: 'fr' + }) ], - providers: [], + providers: [TranslationService], bootstrap: [AppComponent] }) export class AppModule { } + +// On crée une fonction pour charger les fichiers de traduction +export function createTranslateLoader(http: HttpClient) { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); // On charge les fichiers de traduction depuis le dossier assets/i18n +} diff --git a/src/app/editor/editor.component.css b/src/app/editor/editor.component.css index 0f3be89..4c38e51 100644 --- a/src/app/editor/editor.component.css +++ b/src/app/editor/editor.component.css @@ -1,9 +1,4 @@ -.code_input { - padding: 2rem; -} - -.code_input .code_input_textarea { - background-color: #cccccc; - min-height: 80vh; - width: 100%; +.ngx-codemirror { + border: 1px solid #060202; + padding-top: 10px; } diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index 92d0eec..5c06bd3 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -1,13 +1,39 @@ -
- - +
+
+ +
+ +
+ + +
+ +
+ +
+ +
-

Loading: {{ loadingProgress }}%

+

Chargement: {{ loadingProgress }}%

diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index ed58f23..e7bef8f 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -1,6 +1,18 @@ import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; +// Exemple de code pour chaque langage +const defaults = { + markdown: + '# Sankasten\n\nProjet **SAE 3A** par _FRIZOT, MAZINGUE, OLLIER, FREVILLE ET PRADIER_ text\nGit [Sankasten WEB](https://codefirst.iut.uca.fr/git/sandkasten/sandkasten-web.git)', + 'text/typescript': `const component = { + name: "@exemple/Typescript", + author: "Sandkasten", + repo: "https://codefirst.iut.uca.fr/git/sandkasten/sandkasten-web.git" + }; + const hello: string = 'Bonjour ceci est un test de code en typescript';` +}; + @Component({ selector: 'app-editor', templateUrl: './editor.component.html', @@ -10,12 +22,38 @@ export class EditorComponent implements OnInit{ loadingProgress: number = 0; // Pour suivre la progression du chargement isLoaded: boolean = false; // Pour vérifier si le chargement est terminé + // Mode par défaut + mode: keyof typeof defaults = 'text/typescript'; + options = { + lineNumbers: true, + mode: this.mode, + }; + defaults = defaults; + constructor(private router: Router){} ngOnInit(): void { } + // Change le langage de l'éditeur + changeMode(): void { + this.options = { + ...this.options, + mode: this.mode, + }; + } + + // Affiche le contenu de l'éditeur + handleChange($event: Event): void { + console.log('ngModelChange', $event); + } + + // Efface le contenu de l'éditeur + clear(): void { + this.defaults[this.mode] = ''; + } + // Si click sur "Run", on redirige vers la page d'output onRunButtonClicked() { this.loadingProgress = 0; @@ -32,4 +70,5 @@ export class EditorComponent implements OnInit{ } }, 50); // Augmenter la valeur pour ralentir la progression du chargement si nécessaire } + } diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index 5b2ff2a..45db116 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -11,42 +11,41 @@ [routerLinkActiveOptions]="{ exact: true }" [src]="sandkasten_logo" alt="Logo-Sandkasten" />
Sandkasten
- +
@@ -54,7 +53,7 @@
-
Socials
+
{{ 'FooterPage.Social' | translate}}
diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index c49d0ea..7f03bbb 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -16,31 +16,40 @@ routerLink="" routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }" - >Accueil + >{{ 'HeaderPage.Home' | translate }} Editeur + >{{ 'HeaderPage.Editor' | translate }} Documentation + >{{ 'HeaderPage.Documentation' | translate }} Contact + >{{ 'HeaderPage.Contact' | translate }}
+ +

{{ 'HeaderPage.Language' | translate }} + + Language Flag +

+ { -// -// this.isPhonePortrait = false; -// -// if (result.matches) { -// this.isPhonePortrait = true; -// } -// -// }); -// -// } -// } + // Méthode pour changer la langue + onLanguageChange(event: any) { + this.translationService.onLanguageChange(event); + } + + // Méthode pour récupérer le drapeau de la langue courante + getFlagImageUrl(): string { + return this.translationService.getFlagImageUrl(); + } +} \ No newline at end of file diff --git a/src/app/landing-page/landing-page.component.html b/src/app/landing-page/landing-page.component.html index ee9677b..a5eb4ce 100644 --- a/src/app/landing-page/landing-page.component.html +++ b/src/app/landing-page/landing-page.component.html @@ -1,12 +1,11 @@
-

Bienvenue sur Sandkasten !

- Vous voici arriver sur le meilleur site bac à sable de test de code ! Nous vous permettons de tester tous vos programmes sur vos langages préférés. grâce à l’éditeur Monaco et à notre gestion personalisée de l’éxecution sur des conteneurs, votre code devient complétement innoffencif et vous pouvez donc vous amusez autant que vous le souhaitez ! +

{{ 'LandingPage.Welcome' | translate}}

+ {{ 'LandingPage.Description' | translate}}
-
diff --git a/src/app/service/translation.service.ts b/src/app/service/translation.service.ts new file mode 100644 index 0000000..b4e5fc0 --- /dev/null +++ b/src/app/service/translation.service.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; + +@Injectable({ + providedIn: 'root', +}) +export class TranslationService { + language: string = 'fr'; // Par défaut, français + + constructor(private translate: TranslateService) {} + + onLanguageChange(event: any) { + this.language = event.target.value; + this.translate.use(this.language); + console.log(this.language); + } + + getFlagImageUrl(): string { + return `../../assets/img/${this.language}_flag.jpg`; + } +} \ No newline at end of file diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json new file mode 100644 index 0000000..7071a31 --- /dev/null +++ b/src/assets/i18n/en.json @@ -0,0 +1,24 @@ +{ + "LandingPage": { + "Welcome" : "Welcome to Sandkasten", + "Description" : "You've arrived at the best code testing sandbox site! We let you test all your programs in your favorite languages. Thanks to the Code Mirror editor and our personalized management of execution on containers, your code becomes completely harmless, so you can have as much fun as you like!", + "Try" : "Try it now !" + }, + "HeaderPage": { + "Language" : "You can choose your language here :", + "Home" : "Home", + "Editor" : "Editor", + "Documentation" : "Documentation", + "Contact" : "Contact us" + }, + "FooterPage": { + "About" : "About Sandkasten", + "Contact" : "Contact us", + "Story" : "Our story", + "Legal" : "Legal mentions", + "Terms" : "Terms of use", + "Privacy" : "Privacy policy", + "Rights" : "©2023 Sandkasten, Inc. All rights reserved.", + "Social" : "Follow us on social networks :" + } +} \ No newline at end of file diff --git a/src/assets/i18n/fr.json b/src/assets/i18n/fr.json new file mode 100644 index 0000000..2bea94b --- /dev/null +++ b/src/assets/i18n/fr.json @@ -0,0 +1,24 @@ +{ + "LandingPage": { + "Welcome" : "Bienvenue sur Sandkasten", + "Description" : "Vous voici arrivé sur le meilleur site bac à sable de test de code ! Nous vous permettons de tester tous vos programmes sur vos langages préférés. Grâce à l’éditeur Code Mirror et à notre gestion personalisée de l’exécution sur des conteneurs, votre code devient complétement inoffensif et vous pouvez donc vous amusez autant que vous le souhaitez !", + "Try" : "Essayez maintenant !" + }, + "HeaderPage": { + "Language" : "Vous pouvez choisir votre langage ici :", + "Home" : "Accueil", + "Editor" : "Éditeur", + "Documentation" : "Documentation", + "Contact" : "Nous contacter" + }, + "FooterPage": { + "About" : "À propos de Sandkasten", + "Contact" : "Nous contacter", + "Story" : "Notre histoire", + "Legal" : "Mentions légales", + "Terms" : "Conditions d'utilisation", + "Privacy" : "Politique de confidentialité", + "Rights" : "©2023 Sandkasten, Inc. Tous droits réservés", + "Social" : "Suivez-nous sur les réseaux sociaux !" + } +} \ No newline at end of file diff --git a/src/assets/img/en_flag.jpg b/src/assets/img/en_flag.jpg new file mode 100644 index 0000000..0e07d92 Binary files /dev/null and b/src/assets/img/en_flag.jpg differ diff --git a/src/assets/img/fr_flag.jpg b/src/assets/img/fr_flag.jpg new file mode 100644 index 0000000..7446d82 Binary files /dev/null and b/src/assets/img/fr_flag.jpg differ diff --git a/src/main.ts b/src/main.ts index c58dc05..01f6524 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,9 @@ +import 'codemirror/mode/javascript/javascript'; +import 'codemirror/mode/markdown/markdown'; + import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; - platformBrowserDynamic().bootstrapModule(AppModule) .catch(err => console.error(err)); diff --git a/src/styles.css b/src/styles.css index f6b1d4c..f405c2f 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,25 +1,10 @@ +@import 'codemirror/lib/codemirror.css'; +@import 'codemirror/theme/material.css'; + * { - font-family: Roboto, Helvetica, sans-serif; + font-family: Roboto, Helvetica, sans-serif; } body { margin: 0; -} - -/*button {*/ -/* background-color: #1dd21d;*/ -/* border-radius: 10px;*/ -/* box-sizing: border-box;*/ -/* padding: 5px 10px;*/ -/* border: none;*/ -/* box-shadow: lightgray 3px 3px 7px;*/ -/* margin-right: 20px;*/ -/* outline: none;*/ -/* font-size: 20px;*/ -/* font-weight: 500;*/ - -/* &:active {*/ -/* transform: translate(1px, 1px);*/ -/* box-shadow: lightgray 0 0 5px;*/ -/* }*/ -/*}*/ +} \ No newline at end of file