| @ -0,0 +1 @@ | ||||
| /.vs/ | ||||
| @ -0,0 +1,2 @@ | ||||
| DO NOT USE THIS CODE OR LOOK AT IT IF YOU ARE NOT ALLOWED TO | ||||
| IF YOU DO YOU CAN USE OR TEACH THE KNOWLEAGE YOU ACQUEIRED. | ||||
| @ -0,0 +1,15 @@ | ||||
| # Skamcraft | ||||
| 
 | ||||
| ## Start  | ||||
| * Start with live server in VsCode to get full functionnality. | ||||
| * Start with php :  | ||||
| ``` bash | ||||
|     cd /.../Skamcraft | ||||
|     php -S 127.0.0.1:80 | ||||
| ``` | ||||
| 
 | ||||
| ## Norm | ||||
| * ``` ; ``` at the end of each line. | ||||
| * snack_case for functions and variables. | ||||
| * UpperCamelCase for Classes. | ||||
| * all in english. | ||||
| After Width: | Height: | Size: 3.5 KiB | 
| After Width: | Height: | Size: 3.0 KiB | 
| After Width: | Height: | Size: 3.8 KiB | 
| After Width: | Height: | Size: 287 KiB | 
| After Width: | Height: | Size: 969 KiB | 
| Before Width: | Height: | Size: 209 KiB After Width: | Height: | Size: 209 KiB | 
| After Width: | Height: | Size: 315 KiB | 
| After Width: | Height: | Size: 203 KiB | 
| After Width: | Height: | Size: 135 B | 
| After Width: | Height: | Size: 767 B | 
| After Width: | Height: | Size: 579 B | 
| After Width: | Height: | Size: 729 B | 
| After Width: | Height: | Size: 675 B | 
| After Width: | Height: | Size: 545 KiB | 
| @ -0,0 +1,15 @@ | ||||
| /* Copyright © 2023 Entreprise SkamKraft */ | ||||
| 
 | ||||
| 
 | ||||
| .ext-modal[open] { | ||||
|     animation: myFadeIn 2.0s ease normal; | ||||
| } | ||||
|    | ||||
| @keyframes myFadeIn{ | ||||
|     from { | ||||
|       bottom: 100%; | ||||
|     } | ||||
|     to { | ||||
|       bottom: 0%; | ||||
|     } | ||||
| } | ||||
| @ -1,165 +0,0 @@ | ||||
| /* Copyright © 2023 Entreprise SkamCraft */ | ||||
| 
 | ||||
| /* @font-face { | ||||
|   font-family: M42; | ||||
|   src: url(/fonts/m42.TTF); | ||||
| } */ | ||||
| 
 | ||||
| * { | ||||
|   font-family: "Montserrat", sans-serif; | ||||
|   font-size: 16px; | ||||
|   color: #ffffff; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   text-decoration: none; | ||||
|   list-style: none; | ||||
| } | ||||
| 
 | ||||
| body { | ||||
|   background-color: #212121; | ||||
| } | ||||
| 
 | ||||
| .logo { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   align-items: center; | ||||
| } | ||||
| 
 | ||||
| .logo img { | ||||
|   width: 80px; | ||||
|   padding: 20px; | ||||
| } | ||||
| 
 | ||||
| .logo h4 { | ||||
|   font-size: 30px; | ||||
| } | ||||
| 
 | ||||
| .form { | ||||
|   --input-focus: #a37b03; | ||||
|   --font-color: #323232; | ||||
|   --font-color-sub: #666666; | ||||
|   --bg-color: beige; | ||||
|   --main-color: black; | ||||
|   padding: 20px; | ||||
|   background: #eab308; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
|   text-align: center; | ||||
|   gap: 20px; | ||||
|   border-radius: 20px; | ||||
|   border: 2px solid var(--main-color); | ||||
|   box-shadow: 4px 4px var(--main-color); | ||||
|   width: 20%; | ||||
|   margin: auto; | ||||
|   margin-top: 10%; | ||||
| } | ||||
| 
 | ||||
| .title { | ||||
|   color: var(--font-color); | ||||
|   font-weight: 900; | ||||
|   font-size: 20px; | ||||
| } | ||||
| 
 | ||||
| .title span { | ||||
|   color: var(--font-color-sub); | ||||
|   font-weight: 600; | ||||
|   font-size: 17px; | ||||
| } | ||||
| 
 | ||||
| .input { | ||||
|   width: 250px; | ||||
|   height: 40px; | ||||
|   border-radius: 5px; | ||||
|   border: 2px solid var(--main-color); | ||||
|   background-color: var(--bg-color); | ||||
|   box-shadow: 4px 4px var(--main-color); | ||||
|   font-size: 15px; | ||||
|   font-weight: 600; | ||||
|   color: var(--font-color); | ||||
|   padding: 5px 10px; | ||||
|   outline: none; | ||||
| } | ||||
| 
 | ||||
| .input::placeholder { | ||||
|   color: var(--font-color-sub); | ||||
|   opacity: 0.8; | ||||
| } | ||||
| 
 | ||||
| .input:focus { | ||||
|   border: 2px solid var(--input-focus); | ||||
| } | ||||
| 
 | ||||
| .select * { | ||||
|   color: var(--main-color); | ||||
| } | ||||
| 
 | ||||
| .button-confirm { | ||||
|   width: 120px; | ||||
|   height: 40px; | ||||
|   border-radius: 5px; | ||||
|   border: 2px solid var(--main-color); | ||||
|   background-color: var(--bg-color); | ||||
|   box-shadow: 4px 4px var(--main-color); | ||||
|   font-size: 17px; | ||||
|   font-weight: 600; | ||||
|   color: var(--font-color); | ||||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .button-confirm:active { | ||||
|   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
| 
 | ||||
| .link-connection { | ||||
|   position: relative; | ||||
|   display: inline-block; | ||||
| } | ||||
| 
 | ||||
| .link-connection:hover { | ||||
|   cursor: pointer; | ||||
|   text-underline-offset: 2px; | ||||
|   text-decoration: underline; | ||||
|   transform: scale(1.1); | ||||
|   transition: 0.3s; | ||||
| } | ||||
| 
 | ||||
| .alert { | ||||
|   position: fixed; | ||||
|   left: 50%; | ||||
|   transform: translateX(-50%); | ||||
|   bottom: 10%; | ||||
|   border-radius: 0.5rem; | ||||
|   border-width: 0.25rem; | ||||
|   border-color: #ef4444; | ||||
|   background-color: #fee2e2; | ||||
|   padding: 1rem; | ||||
|   width: 300px; | ||||
|   max-width: 90%; | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| .alert-inner { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   gap: 0.5rem; | ||||
|   color: #ef4444; | ||||
| } | ||||
| 
 | ||||
| .icon { | ||||
|   height: 1.25rem; | ||||
|   width: 1.25rem; | ||||
|   fill: #d94848; | ||||
| } | ||||
| 
 | ||||
| .message { | ||||
|   color: #d94848; | ||||
|   font-weight: 500; | ||||
| } | ||||
| 
 | ||||
| .content { | ||||
|   margin-top: 0.5rem; | ||||
|   font-size: 0.875rem; | ||||
|   color: #d94848; | ||||
| } | ||||
| @ -1,112 +0,0 @@ | ||||
| /*Copyright © 2023 Entreprise SkamCraft */ | ||||
| 
 | ||||
| * { | ||||
|   font-family: "Inter", sans-serif; | ||||
|   box-sizing: border-box; | ||||
|   overflow: hidden; | ||||
|   background-color: #272727; | ||||
| } | ||||
| 
 | ||||
| body, | ||||
| html { | ||||
|   height: 100%; | ||||
|   display: flex; | ||||
|   flex-direction: column; | ||||
| } | ||||
| 
 | ||||
| /* Menu */ | ||||
| .menu { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   justify-content: space-between; | ||||
| } | ||||
| 
 | ||||
| .title-section { | ||||
|   color: white; | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
|   padding-left: 10px; | ||||
| } | ||||
| 
 | ||||
| .title-section img { | ||||
|   max-width: 80px; | ||||
|   max-height: 50px; | ||||
| } | ||||
| 
 | ||||
| .page-change-button { | ||||
|   padding-left: 10px; | ||||
| } | ||||
| 
 | ||||
| button { | ||||
|   margin: 2px; | ||||
|   color: black; | ||||
|   background-color: white; | ||||
|   border: 2px solid white; | ||||
|   border-radius: 10px; | ||||
| } | ||||
| 
 | ||||
| button:hover { | ||||
|   border-color: #eab308; | ||||
|   background-color: #eab308; | ||||
|   transition: all 1s; | ||||
| } | ||||
| 
 | ||||
| main { | ||||
| 
 | ||||
|   flex: 1; | ||||
|   overflow-y: scroll; | ||||
|   display: flex; | ||||
|   justify-content: left; | ||||
|   flex-wrap: wrap; | ||||
|   padding-left: 30px; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .spacer { | ||||
|   margin-bottom: 35px; | ||||
|   margin-left: 100px; | ||||
|   margin-right: 100px; | ||||
| } | ||||
| 
 | ||||
| #credits { | ||||
|   background-color: white; | ||||
|   border: 2px solid white; | ||||
|   border-radius: 10px; | ||||
|   color: black; | ||||
| } | ||||
| 
 | ||||
| /* Footer */ | ||||
| footer { | ||||
|   color: white; | ||||
| } | ||||
| 
 | ||||
| footer p { | ||||
|   display: flex; | ||||
|   justify-content: center; | ||||
|   margin-bottom: 0px; | ||||
| } | ||||
| 
 | ||||
| /* Modal */ | ||||
| .modal-content { | ||||
|   color: white; | ||||
| } | ||||
| 
 | ||||
| #exampleModal { | ||||
|   color: white; | ||||
|   background-color: rgba(255, 255, 255, 0.1) | ||||
| } | ||||
| 
 | ||||
| #modal-footer { | ||||
|   background-color: #272727; | ||||
| } | ||||
| 
 | ||||
| #status-onhold { | ||||
|   color: orange; | ||||
| } | ||||
| 
 | ||||
| #status-accepted{ | ||||
|   color: greenyellow; | ||||
| } | ||||
| #revenu { | ||||
|   color: white | ||||
| } | ||||
| @ -0,0 +1,195 @@ | ||||
| /* Copyright © 2023 Entreprise SkamKraft */ | ||||
| 
 | ||||
| :root { | ||||
|     --main-back-color: rgb(143, 143, 143); | ||||
|     --second-back-color: black; | ||||
| } | ||||
| 
 | ||||
| @font-face { | ||||
|     font-family: M42; | ||||
|     src: url("/assets/fonts/m42.TTF"); | ||||
| } | ||||
| 
 | ||||
| * { | ||||
|     box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| body { | ||||
|     background-image: url("/assets/img/background.jpg"); | ||||
|     font-family: 'M42'; | ||||
|     font-size: 7px; | ||||
|     margin: 0px; | ||||
|     padding: 0px; | ||||
| } | ||||
| 
 | ||||
| /* Main */ | ||||
| .container { | ||||
|     color: white; | ||||
|     background-color: rgba(0, 0, 0, 0.726); | ||||
|     display: flex; | ||||
|     margin: 10px; | ||||
|     width: fit-content; | ||||
|     margin: auto; | ||||
|     margin-top: 10px; margin-bottom: 30px; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     border: 4px solid rgba(68, 68, 68, 0.575); | ||||
| } | ||||
| 
 | ||||
| .max-container { | ||||
|     background-color: rgba(0, 0, 0, 0.726); | ||||
|     color: white; | ||||
|     display: flex; | ||||
|     margin: 10px; | ||||
|     width: 95%; | ||||
|     margin: auto; | ||||
|     margin-top: 10px; margin-bottom: 30px; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
|     border: 4px solid rgba(68, 68, 68, 0.575); | ||||
| } | ||||
| 
 | ||||
| .con-title { | ||||
|     font-size: 15px; | ||||
|     border-bottom: 2px solid black; | ||||
| } | ||||
| 
 | ||||
| .btn { | ||||
|     padding: 10px; | ||||
|     font-size: 8px; | ||||
|     font-family: 'M42'; | ||||
|     color: white; | ||||
|     border: none; | ||||
|     border-radius: 10px; | ||||
| } | ||||
| 
 | ||||
| .btn-val { | ||||
|     background-color: rgba(0, 0, 255, 0.637); | ||||
| } | ||||
| 
 | ||||
| .btn-cancel { | ||||
|     background-color: rgba(255, 0, 0, 0.699); | ||||
| } | ||||
| 
 | ||||
| /*footer*/ | ||||
| footer { | ||||
|     position: fixed; | ||||
|     width: 100%; | ||||
|     bottom: 0; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     background-color: var(--second-back-color); | ||||
|     color: white; | ||||
| } | ||||
| 
 | ||||
| /*nav bar*/ | ||||
| .nav-nav { | ||||
|     --nav-img-width: 100px; | ||||
|     background-color: var(--second-back-color); | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| .nav-nav .nav-brand { | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| .nav-nav .nav-brand img { | ||||
|     width: var(--nav-img-width); | ||||
| } | ||||
| 
 | ||||
| .nav-nav .nav-links { | ||||
|     --links-color: rgb(0,0,0); | ||||
|     --links-backcolor: rgb(255, 123, 71); | ||||
|     --links-border-color: rgb(255, 173, 118); | ||||
|     height: 70%; | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
| } | ||||
| 
 | ||||
| .nav-link { | ||||
|     margin-right: 10px; | ||||
|     background-color: var(--links-backcolor); | ||||
|     color: var(--links-color); | ||||
|     border: 4px solid var(--links-border-color);  | ||||
|     list-style: none; | ||||
|     display: flex; | ||||
|     justify-content: center; | ||||
|     align-items: center; | ||||
|     box-shadow: 3px 2px white; | ||||
| } | ||||
| 
 | ||||
| .stats { | ||||
|     color: white; | ||||
| } | ||||
| 
 | ||||
| /* General */ | ||||
| .smooth { | ||||
|     padding: 5px; | ||||
|     padding-left: 10px; | ||||
|     padding-right: 10px; | ||||
|     border-radius: 5px; | ||||
| } | ||||
| 
 | ||||
| .in-big { | ||||
|     font-family: 'M42'; | ||||
|     font-size: 6px; | ||||
|     padding: 5px; | ||||
|     width: 100%; | ||||
|     margin-bottom: 10px; | ||||
|     border-radius: 5px; | ||||
|     border: none; | ||||
| } | ||||
| 
 | ||||
| .errors p { | ||||
|     background-color: rgba(255, 56, 56, 0.733); | ||||
|     border: 3px solid rgb(255, 111, 111); | ||||
|     padding: 10px; | ||||
|     color: white; | ||||
|     border-radius: 5px; | ||||
|     text-align: center; | ||||
| } | ||||
| 
 | ||||
| /* Modal */ | ||||
| .ext-modal { | ||||
|     background-color: rgba(255, 255, 255, 0.767); | ||||
|     border-radius: 10px; | ||||
|     padding: 50px; | ||||
| } | ||||
| 
 | ||||
| .my-modal { | ||||
|     display: flex; | ||||
|     flex-direction: column; | ||||
|     align-items: center; | ||||
| } | ||||
| 
 | ||||
| .modal-title { | ||||
|     font-size: 15px; | ||||
|     margin-bottom: 40px; | ||||
| } | ||||
| 
 | ||||
| .show-token { | ||||
|     width: fit-content; | ||||
|     border: 2px solid black; | ||||
|     border-radius: 10px; | ||||
|     padding: 30px; | ||||
|     font-size: 5px; | ||||
|     white-space:pre-wrap; | ||||
|     word-break:break-word; | ||||
| } | ||||
| 
 | ||||
| .my-modal #timer { | ||||
|     text-align: center; | ||||
|     border: 1px solid black; | ||||
|     border-radius: 10px; | ||||
|     width: 10%; | ||||
|     padding: 5px; | ||||
|     margin-bottom: 10px; | ||||
| } | ||||
| 
 | ||||
| #canvas { | ||||
|     border-radius: 10px; | ||||
| } | ||||
| @ -0,0 +1,11 @@ | ||||
| /* Copyright © 2023 Entreprise SkamKraft */ | ||||
| 
 | ||||
| #block-content { | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
| } | ||||
| 
 | ||||
| .modal-disable::backdrop { | ||||
|     background-color: rgba(0, 0, 0, 0.493); | ||||
| } | ||||
| 
 | ||||
| After Width: | Height: | Size: 318 B | 
| @ -0,0 +1,16 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| <nav class="nav-nav"> | ||||
|   <div class="nav-brand"> | ||||
|     <img src="assets/logo/logoblancnotext.png" /> | ||||
|   </div> | ||||
|   <div class="stats"></div> | ||||
|   <ul class="nav-links"> | ||||
|     <li class="nav-link smooth" id="systems-link">Systems</li> | ||||
|     <li class="nav-link smooth" id="login-link">Log in</li> | ||||
|     <li class="nav-link smooth" id="reg-link">New Agent</li> | ||||
|   </ul> | ||||
| </nav> | ||||
| <main id="block-content"></main> | ||||
| <footer> | ||||
|   <p>Skamcraft Sarl</p> | ||||
| </footer> | ||||
| @ -0,0 +1,11 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| 
 | ||||
| <div class="container smooth">  | ||||
|     <p class="con-title">Login</p> | ||||
|     <input type="text" placeholder="Agent token" id="in-token" class="in-big"> | ||||
|     <div class="grp-btn"> | ||||
|         <button class="btn btn-val" id="val">Validate</button> | ||||
|         <button class="btn btn-cancel" id="cancel">Cancel</button> | ||||
|     </div> | ||||
|     <div class="errors"></div> | ||||
| </div> | ||||
| @ -0,0 +1,9 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| 
 | ||||
| <div class="my-modal"> | ||||
|     <p class="modal-title">Login success</p> | ||||
|     <div> | ||||
|         <button id="ok" class="btn btn-val">Continue</button> | ||||
|         <button id="forget_login" class="btn btn-cancel">Forget agent</button> | ||||
|     </div> | ||||
| </div> | ||||
| @ -0,0 +1,12 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| 
 | ||||
| <div class="container smooth">  | ||||
|     <p class="con-title">New Agent</p> | ||||
|     <input type="text" placeholder="Name" id="in-name" class="in-big"> | ||||
|     <input type="text" placeholder="Faction" id="in-faction" class="in-big"> | ||||
|     <div class="grp-btn"> | ||||
|         <button class="btn btn-val" id="val">Validate</button> | ||||
|         <button class="btn btn-cancel" id="cancel">Cancel</button> | ||||
|     </div> | ||||
|     <div class="errors"></div> | ||||
| </div> | ||||
| @ -0,0 +1,10 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| 
 | ||||
| <div class="my-modal"> | ||||
|     <p class="modal-title">Login success</p> | ||||
|     <p class="show-token"></p> | ||||
|     <div> | ||||
|         <button id="ok" class="btn btn-val">Continue</button> | ||||
|         <button id="forget_reg" class="btn btn-cancel">Forget agent</button> | ||||
|     </div> | ||||
| </div> | ||||
| @ -0,0 +1,5 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| <div class="container smooth">  | ||||
|     <p class="con-title">Bienvenue sur SkamCraft</p> | ||||
|     <p class="con-content">Application client pour l'API Space Tarders.</p> | ||||
| </div> | ||||
| @ -0,0 +1,13 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <title>Ship</title> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div class="ships"> | ||||
|      | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
| @ -0,0 +1,5 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| <div class="container smooth"> | ||||
|   <p class="con-title">Bienvenue sur SkamCraft</p> | ||||
|   <p class="con-content">Application client pour l'API Space Tarders.</p> | ||||
| </div> | ||||
| @ -0,0 +1,5 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| <div class="max-container smooth">  | ||||
|     <p class="con-title" id="sys-name"></p> | ||||
|     <canvas id="canvas"></canvas> | ||||
| </div> | ||||
| @ -0,0 +1,5 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| <div class="max-container smooth">  | ||||
|     <p class="con-title">Systems</p> | ||||
|     <canvas id="canvas"></canvas> | ||||
| </div> | ||||
| @ -1,68 +1,15 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| <html lang="fr" class="html-index"> | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Inter:wght@500&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <link | ||||
|       href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" | ||||
|       rel="stylesheet" | ||||
|       integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" | ||||
|       crossorigin="anonymous" | ||||
|     /> | ||||
|     <script | ||||
|       src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" | ||||
|       integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" | ||||
|       crossorigin="anonymous" | ||||
|     ></script> | ||||
|     <script | ||||
|       src="https://code.jquery.com/jquery-3.7.1.min.js" | ||||
|       integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" | ||||
|       crossorigin="anonymous" | ||||
|     ></script> | ||||
|     <script type="module" src="js/main.js" defer></script> | ||||
|     <link rel="stylesheet" href="/css/global.css" /> | ||||
|     <link rel="icon" href="img/logo.png" /> | ||||
|     <title>SkamCraft</title> | ||||
|     <title></title> | ||||
|     <link rel="stylesheet" href="css/style.css"> | ||||
|     <link rel="stylesheet" href="css/ui.css"> | ||||
|     <link rel="stylesheet" href="css/animation.css"> | ||||
|     <script src="js/lib/fabric.js"></script> | ||||
|     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>     | ||||
|     <script type="module" src="js/index.js" defer></script> | ||||
|   </head> | ||||
| 
 | ||||
|   <body> | ||||
|     <header id="header"> | ||||
|       <div class="menu"> | ||||
|         <div class="title-section"> | ||||
|           <img src="img/Skamkraft.png" alt="Logo AppleTech.svg" /> | ||||
|           <p>SkamCraft</p> | ||||
|           <div class="page-change-button"> | ||||
|             <button id="btn-contract">Mes contracts</button> | ||||
|             <button id="btn-faction">Ma faction</button> | ||||
|             <button id="btn-ship">Mes vaisseaux</button> | ||||
|             <button id="btn-system">Systeme</button> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="title-section"> | ||||
|           <p id="credits">N/A Credtis</p> | ||||
|           <button id="btn-logout">Se deconnecter</button> | ||||
|         </div> | ||||
|       </div> | ||||
|       <hr /> | ||||
|     </header> | ||||
| 
 | ||||
|     <main> | ||||
|       <canvas id="canvas"></canvas> | ||||
|       <div id="ships"></div> | ||||
|     </main> | ||||
| 
 | ||||
|     <footer id="footer"> | ||||
|       <hr /> | ||||
|       <p>SkamKraft © 2023</p> | ||||
|     </footer> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
| @ -1,170 +0,0 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| const spacetradersApiUrl = "https://api.spacetraders.io/v2/"; | ||||
| 
 | ||||
| const REQUEST = async (url, method, headers, data) => { | ||||
|   try { | ||||
|     const response = await $.ajax(url, { | ||||
|       method, | ||||
|       headers, | ||||
|       data, | ||||
|     }); | ||||
| 
 | ||||
|     return response.data; | ||||
|   } catch (error) { | ||||
|     console.log(error); | ||||
|     return error; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| export default { | ||||
|   Agent: { | ||||
|     create: (symbol, faction) => { | ||||
|       const url = `${spacetradersApiUrl}register`; | ||||
|       const headers = { "Content-Type": "application/json" }; | ||||
|       const data = JSON.stringify({ symbol, faction }); | ||||
| 
 | ||||
|       return REQUEST(url, "POST", headers, data); | ||||
|     }, | ||||
| 
 | ||||
|     get: (token) => { | ||||
|       const url = `${spacetradersApiUrl}my/agent`; | ||||
|       const headers = { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
| 
 | ||||
|     getPublic: (symbol) => { | ||||
|       const url = `${spacetradersApiUrl}agents/${symbol}`; | ||||
|       const headers = { Accept: "application/json" }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
| 
 | ||||
|     list: (limit, page) => { | ||||
|       const url = `${spacetradersApiUrl}agents`; | ||||
|       const headers = { Accept: "application/json" }; | ||||
|       const data = { limit, page }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers, data); | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   Faction: { | ||||
|     list: (limit, page) => { | ||||
|       const url = `${spacetradersApiUrl}factions`; | ||||
|       const headers = { Accept: "application/json" }; | ||||
|       const data = { limit, page }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers, data); | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   System: { | ||||
|     list: (limit, page) => { | ||||
|       const url = `${spacetradersApiUrl}systems/`; | ||||
|       const headers = { Accept: "application/json" }; | ||||
|       const data = { limit, page }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers, data); | ||||
|     }, | ||||
| 
 | ||||
|     get: (symbol) => { | ||||
|       const url = `${spacetradersApiUrl}systems/${symbol}`; | ||||
|       const headers = { Accept: "application/json" }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   Waypoint: { | ||||
|     list: (limit, page, systemSymbol) => { | ||||
|       const url = `${spacetradersApiUrl}systems/${systemSymbol}/waypoints`; | ||||
|       const headers = { Accept: "application/json" }; | ||||
|       const data = { limit, page }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers, data); | ||||
|     }, | ||||
| 
 | ||||
|     get: (systemSymbol, waypointSymbol, token) => { | ||||
|       const url = `${spacetradersApiUrl}systems/${systemSymbol}/waypoints/${waypointSymbol}/market`; | ||||
|       const headers = { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   Ships: { | ||||
|     list: (token) => { | ||||
|       const url = `${spacetradersApiUrl}my/ships`; | ||||
|       const headers = { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
| 
 | ||||
|     get: (token, symbol) => { | ||||
|       const url = `${spacetradersApiUrl}my/ships/${symbol}`; | ||||
|       const headers = { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
| 
 | ||||
|     getPosition: (token, symbol) => { | ||||
|       const url = `${spacetradersApiUrl}my/ships/${symbol}/nav`; | ||||
|       const headers = { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
| 
 | ||||
|     travel: (token, shipSymbol, waypointSymbol) => { | ||||
|       const url = `${spacetradersApiUrl}my/ships/${shipSymbol}/navigate`; | ||||
|       const headers = { | ||||
|         "Content-Type": "application/json", | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
|       const data = JSON.stringify({ waypointSymbol }); | ||||
| 
 | ||||
|       return REQUEST(url, "POST", headers, data); | ||||
|     }, | ||||
|   }, | ||||
| 
 | ||||
|   Contract: { | ||||
|     list: (token) => { | ||||
|       const url = `${spacetradersApiUrl}my/contracts/`; | ||||
|       const headers = { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
| 
 | ||||
|     get: async (contratId, token) => { | ||||
|       const url = `${spacetradersApiUrl}my/contracts/${contratId}`; | ||||
|       const headers = { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }; | ||||
| 
 | ||||
|       return REQUEST(url, "GET", headers); | ||||
|     }, | ||||
|   }, | ||||
| }; | ||||
| @ -1,83 +0,0 @@ | ||||
| // Copyright © 2023 Entreprise SkamCraft
 | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| import SpaceTraders from "./api.js"; | ||||
| 
 | ||||
| const $inputToken = $("#input-token"); | ||||
| const $inputSymbol = $("#input-symbol"); | ||||
| const $inputFaction = $("#input-faction"); | ||||
| const $alert = document.querySelector("#box-alert"); | ||||
| const $error = $("#error-message"); | ||||
| 
 | ||||
| const showError = (message) => { | ||||
|   $alert.removeAttribute("hidden"); | ||||
|   $error.text(message); | ||||
| }; | ||||
| 
 | ||||
| const redirectToIndex = () => { | ||||
|   window.location.href = "/index.html"; | ||||
| }; | ||||
| 
 | ||||
| export default { | ||||
|   login: async () => { | ||||
|     const token = $inputToken.val(); | ||||
| 
 | ||||
|     if (!token) { | ||||
|       showError("Token manquant"); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       await SpaceTraders.Agent.get(token); | ||||
|       localStorage.setItem("token", token); | ||||
|       redirectToIndex(); | ||||
|     } catch { | ||||
|       showError("Token invalide"); | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   register: async () => { | ||||
|     const symbol = $inputSymbol.val(); | ||||
| 
 | ||||
|     if (!symbol) { | ||||
|       showError("Symbol manquant"); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     const faction = $inputFaction.val(); | ||||
| 
 | ||||
|     console.log(faction); | ||||
| 
 | ||||
|     if (!faction) { | ||||
|       showError("Faction manquante"); | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       const agent = await SpaceTraders.Agent.create(symbol, faction); | ||||
| 
 | ||||
|       if (agent.token !== undefined) { | ||||
|         localStorage.setItem("token", agent.token); | ||||
|         redirectToIndex(); | ||||
|       } else { | ||||
|         showError("Symbol ou faction invalide"); | ||||
|       } | ||||
|     } catch { | ||||
|       showError("Erreur lors de l'inscription"); | ||||
|     } | ||||
|   }, | ||||
| 
 | ||||
|   isLogin: async () => { | ||||
|     const token = localStorage.getItem("token"); | ||||
| 
 | ||||
|     if (!token) return false; | ||||
| 
 | ||||
|     try { | ||||
|       await SpaceTraders.Agent.get(token); | ||||
|       return true; | ||||
|     } catch { | ||||
|       return false; | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
| @ -0,0 +1,9 @@ | ||||
| import menu_mod from "./menu_mod.js"; | ||||
| 
 | ||||
| export default function home(temp_engine) { | ||||
|     temp_engine.after_render(menu_mod); | ||||
|     temp_engine.render("templates/home.html"); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1,57 @@ | ||||
| import { Modal } from "../skama_code/ui/modal.js"; | ||||
| import { Auth } from "../skama_code/auth/auth.js"; | ||||
| import { My } from "../skama_code/api/agent.js"; | ||||
| import home from "./home.js"; | ||||
| import menu_mod from "./menu_mod.js"; | ||||
| 
 | ||||
| export default function login(temp_engine) { | ||||
|   let auth = new Auth(true); | ||||
|   let modal = new Modal("login-modal", temp_engine); | ||||
| 
 | ||||
|   function render_login() { | ||||
|     temp_engine.render(`templates/auth/login.html`); | ||||
|   } | ||||
| 
 | ||||
|   modal.add_class("ext-modal"); | ||||
|   temp_engine.after_render((temp_engine) => { | ||||
|     modal.load("templates/auth/login_modal.html"); | ||||
|     menu_mod(temp_engine); | ||||
|     temp_engine.add_event("#ok", "click", () => { | ||||
|       home(temp_engine); | ||||
|     }); | ||||
| 
 | ||||
|     temp_engine.add_event("#forget_login", "click", () => { | ||||
|       My.agent = null; | ||||
|       auth.unload_token(); | ||||
|       modal.close(); | ||||
|       render_login(); | ||||
|     }); | ||||
| 
 | ||||
|     temp_engine.add_event("#val", "click", () => { | ||||
|       let token = $("#in-token").val(); | ||||
|       auth.login(token); | ||||
|     }); | ||||
| 
 | ||||
|     temp_engine.add_event("#cancel", "click", () => { | ||||
|       $("#in-token").val(""); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   render_login(); | ||||
| 
 | ||||
|   auth | ||||
|     .done((agent) => { | ||||
|       modal.show(); | ||||
|       My.agent = agent; | ||||
|     }) | ||||
|     .fail((errs) => { | ||||
|       $(".errors").html(""); | ||||
|       errs.forEach((err) => { | ||||
|         $(".errors").append(` | ||||
|                 <p>${err}</p> | ||||
|             `);
 | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|   auth.relog(); | ||||
| } | ||||
| @ -0,0 +1,49 @@ | ||||
| import { My } from "../skama_code/api/agent.js"; | ||||
| import login from "./login.js"; | ||||
| import reg from "./reg.js"; | ||||
| import home from "./home.js"; | ||||
| import { systems } from "./systems.js"; | ||||
| import Ship from "./ships.js"; | ||||
| 
 | ||||
| function init_menu(temp_engine) { | ||||
|   temp_engine.add_event("#reg-link", "click", () => { | ||||
|     reg(temp_engine); | ||||
|   }); | ||||
|   temp_engine.add_event("#login-link", "click", () => { | ||||
|     login(temp_engine); | ||||
|   }); | ||||
|   temp_engine.add_event("#systems-link", "click", () => { | ||||
|     systems(temp_engine); | ||||
|   }); | ||||
|   temp_engine.add_event(".nav-brand", "click", () => { | ||||
|     home(temp_engine); | ||||
|   }); | ||||
|   temp_engine.add_event("#ships-link", "click", () => { | ||||
|     Ship(temp_engine); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| function loged_links() { | ||||
|   $(".nav-links").prepend(` | ||||
|         <li class="nav-link smooth" id="contracts-link">Contracts</li> | ||||
|         <li class="nav-link smooth" id="ships-link">Ships</li> | ||||
|     `);
 | ||||
| } | ||||
| 
 | ||||
| function show_stats() { | ||||
|   $(".stats").html(` | ||||
|         <p>Agent name : ${My.agent.name}</p> | ||||
|         <p>Credits : ${My.agent.credits}</p> | ||||
|         <p>Ships : ${My.agent.ships_cpt}</p> | ||||
|         <p>Faction : ${My.agent.faction}</p> | ||||
|         <p>HQ : ${My.agent.hq}</p> | ||||
|     `);
 | ||||
| } | ||||
| 
 | ||||
| export default function menu_mod(temp_engine) { | ||||
|   init_menu(temp_engine); | ||||
|   if (My.agent) { | ||||
|     show_stats(); | ||||
|     loged_links(); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,64 @@ | ||||
| import { Modal } from "../skama_code/ui/modal.js"; | ||||
| import { Auth } from "../skama_code/auth/auth.js"; | ||||
| import { My } from "../skama_code/api/agent.js"; | ||||
| import home from "./home.js"; | ||||
| import menu_mod from "./menu_mod.js"; | ||||
| 
 | ||||
| export default function reg(temp_engine) { | ||||
|     let active = false; | ||||
|     let auth = new Auth(true); | ||||
|     let modal = new Modal("reg-modal", temp_engine); | ||||
| 
 | ||||
|     function render_reg() { | ||||
|         temp_engine.render(`templates/auth/reg.html`); | ||||
|         modal.load("templates/auth/reg_modal.html") | ||||
|     } | ||||
| 
 | ||||
|     modal.add_class("ext-modal"); | ||||
|     temp_engine.after_render(menu_mod); | ||||
| 
 | ||||
|     render_reg(); | ||||
| 
 | ||||
|     temp_engine.add_event("#ok", "click", () => { | ||||
|         home(temp_engine); | ||||
|     }); | ||||
| 
 | ||||
|     temp_engine.add_event("#forget_reg", "click", () => { | ||||
|         My.agent = null; | ||||
|         auth.unload_token(); | ||||
|         modal.close(); | ||||
|         render_reg(); | ||||
|     }); | ||||
| 
 | ||||
|     temp_engine.add_event("#val", "click", () => { | ||||
|         if (!active) { | ||||
|             active = true; | ||||
|             let name = $("#in-name").val(); | ||||
|             let faction = $("#in-faction").val(); | ||||
|             auth.register({ | ||||
|                 name: name, | ||||
|                 faction: faction | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     temp_engine.add_event("#cancel", "click", () => { | ||||
|         $("#in-name").val(""); | ||||
|         $("#in-faction").val(""); | ||||
|     }); | ||||
| 
 | ||||
|     auth.done((agent) => { | ||||
|         $(".show-token").text(agent.token); | ||||
|         modal.show(); | ||||
|         My.agent = agent; | ||||
|         active = false; | ||||
|     }).fail((errs) => { | ||||
|         $(".errors").html(""); | ||||
|         errs.forEach(err => { | ||||
|             $(".errors").append(` | ||||
|                 <p>${err}</p> | ||||
|             `);
 | ||||
|         }); | ||||
|         active = false; | ||||
|     }); | ||||
| } | ||||
| @ -0,0 +1,38 @@ | ||||
| import menu_mod from "./menu_mod.js"; | ||||
| import { Modal } from "../skama_code/ui/modal.js"; | ||||
| import { Ship } from "../skama_code/api/ship.js"; | ||||
| 
 | ||||
| export default (temp_engine) => { | ||||
|   let modal = new Modal("ship-modal", temp_engine); | ||||
| 
 | ||||
|   temp_engine.after_render((temp_engine) => { | ||||
|     menu_mod(temp_engine); | ||||
|     modal.load("templates/ship/ship_modal.html"); | ||||
| 
 | ||||
|     Ship.list((ship) => { | ||||
|       ship.data.forEach(data => { | ||||
|           console.log(data) | ||||
|           $(".ships").html( | ||||
|           ` | ||||
|             <div> | ||||
|               <h5>${data.symbol}</h5> | ||||
|                 <p>fuel capacity: ${data.fuel.capacity}</p> | ||||
|               <button id="FT">FICHE Technique<button> | ||||
|             </div> | ||||
|           ` | ||||
|           ) | ||||
|       }); | ||||
|     }); | ||||
| 
 | ||||
|     temp_engine.add_event("#btn-close", "click", () => { | ||||
|       modal.close(); | ||||
|     }); | ||||
|     temp_engine.add_event("#FT", "click", () => { | ||||
|       modal.show(); | ||||
|     }); | ||||
| 
 | ||||
|     
 | ||||
|   }); | ||||
| 
 | ||||
|   temp_engine.render("templates/ship/ship.html"); | ||||
| }; | ||||
| @ -0,0 +1,100 @@ | ||||
| import { SystemBuilder } from "../skama_code/api/system.js"; | ||||
| import { Position } from "../skama_code/commun/position.js"; | ||||
| import menu_mod from "./menu_mod.js" | ||||
| 
 | ||||
| let canvas; 
 | ||||
| let last_target; | ||||
| 
 | ||||
| let offset = { | ||||
|     x: 2, | ||||
|     y: 2 | ||||
| }; | ||||
| let max = 100; | ||||
| let w = (window.innerWidth/10)*9; | ||||
| let h = (window.innerHeight/4)*3; | ||||
| 
 | ||||
| function animate() { | ||||
|     canvas.renderAll(); | ||||
|     setTimeout(animate, 1000); | ||||
| } | ||||
| 
 | ||||
| function draw_planet(planet) { | ||||
|     let shadow = new fabric.Shadow({ | ||||
|         color: "white", | ||||
|         blur: 5, | ||||
|         offsetX: 0, | ||||
|         offsetY: 0, | ||||
|     }); | ||||
| 
 | ||||
|     fabric.Image.fromURL('/assets/planets/planetproto.png', function(img_planet) { | ||||
|         //FABRICJS
 | ||||
|         img_planet.set({ | ||||
|             selectable: false, | ||||
|             shadow: shadow, | ||||
|             left: planet.position.x/offset.x + w/2, | ||||
|             top: planet.position.y/offset.y+ h/2, | ||||
|             name: planet.name, | ||||
|             type: planet.type | ||||
|         }); | ||||
|         canvas.add(img_planet); | ||||
|       }); | ||||
| } | ||||
| 
 | ||||
| function offsetOrbit(planet) { | ||||
|     if (planet.orbits) { | ||||
|         console.log("Orbits"); | ||||
|         let x = Math.floor(Math.random() * max - Math.random() * max); | ||||
|         let y =  Math.floor(Math.random() * max - Math.random() * max); | ||||
|         planet.position.move(new Position(x, y)); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export default function system(system, temp_engine) { | ||||
|     temp_engine.after_render((temp_engine) => { | ||||
|         $("#sys-name").text(system); | ||||
|         menu_mod(temp_engine); | ||||
|         canvas = new fabric.Canvas("canvas",{ | ||||
|             width: w, | ||||
|             height: h, | ||||
|             backgroundColor:"rgb(7, 18, 41)", | ||||
|             renderOnAddRemove: false, | ||||
|             hoverCursor :'pointer' | ||||
|         }); | ||||
|         SystemBuilder.get(system, (system) => { | ||||
|             system.list_all((planets) => { | ||||
|                 planets.forEach(planet => { | ||||
|                     offsetOrbit(planet); | ||||
|                     draw_planet(planet); | ||||
|                 }); | ||||
|                 animate(); | ||||
|             }, (err) => { | ||||
|                 console.log(err); | ||||
|             }); | ||||
|         }); | ||||
|         canvas.on('mouse:up', (e) => { | ||||
|             if(e.target.shadow.color == "red"){ | ||||
|                 e.target.shadow.color = "white" | ||||
|             } | ||||
|             else{ | ||||
|                 e.target.shadow.color = "red" | ||||
|             } | ||||
|             if (last_target) last_target.shadow.color = "white"; | ||||
|             last_target = e.target; | ||||
|             canvas.renderAll(); | ||||
|         }); | ||||
|         $(window).on("resize", () => { | ||||
|             canvas.setWidth((window.innerWidth/10)*9); | ||||
|             canvas.setHeight((window.innerHeight/4)*3); | ||||
|             canvas.renderAll(); | ||||
|         }); | ||||
|         canvas.on("mouse:wheel", (opt) => { | ||||
|             let scale = 1.1; | ||||
|             if (opt.e.deltaY < 0) { | ||||
|                 canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), canvas.getZoom() * scale); | ||||
|             } else if (opt.e.deltaY > 0) { | ||||
|                 canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), canvas.getZoom() / scale); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|     temp_engine.render("templates/systems/system.html"); | ||||
| } | ||||
| @ -0,0 +1,80 @@ | ||||
| import { SystemBuilder } from "../skama_code/api/system.js"; | ||||
| import menu_mod from "./menu_mod.js" | ||||
| import system from "./system.js" | ||||
| 
 | ||||
| let canvas; 
 | ||||
| let last_target; | ||||
| 
 | ||||
| let offset = { | ||||
|     x: 2, | ||||
|     y: 2 | ||||
| }; | ||||
| let max = 100; | ||||
| let w = (window.innerWidth/10)*9; | ||||
| let h = (window.innerHeight/4)*3; | ||||
| 
 | ||||
| function animate() { | ||||
|     canvas.renderAll(); | ||||
|     setTimeout(animate, 1000); | ||||
| } | ||||
| 
 | ||||
| function draw_system(system) { | ||||
|     let shadow = new fabric.Shadow({ | ||||
|         color: "white", | ||||
|         blur: 5, | ||||
|         offsetX: 0, | ||||
|         offsetY: 0, | ||||
|     }); | ||||
| 
 | ||||
|     fabric.Image.fromURL('/assets/systems/galaxie1.png', function(img_planet) { | ||||
| 
 | ||||
|         img_planet.set({ | ||||
|             selectable: false, | ||||
|             scaleX: 0.05, | ||||
|             scaleY: 0.05, | ||||
|             shadow: shadow, | ||||
|             left: system.position.x/offset.x + w/2, | ||||
|             top: system.position.y/offset.y+ h/2, | ||||
|             name: system.name, | ||||
|             type: system.type | ||||
|         }); | ||||
|         canvas.add(img_planet); | ||||
|       }); | ||||
| } | ||||
| 
 | ||||
| export function systems(temp_engine) { | ||||
|     temp_engine.after_render((temp_engine) => { | ||||
|         menu_mod(temp_engine); | ||||
|         canvas = new fabric.Canvas("canvas",{ | ||||
|             width: w, | ||||
|             height: h, | ||||
|             backgroundColor:"rgb(7, 18, 41)", | ||||
|             renderOnAddRemove: false, | ||||
|             hoverCursor :'pointer' | ||||
|         }); | ||||
|         SystemBuilder.list_all((systems) => { | ||||
|                 systems.forEach(system => { | ||||
|                     draw_system(system); | ||||
|                 }); | ||||
|                 animate(); | ||||
|             }); | ||||
|         canvas.on('mouse:up', (e) => { | ||||
|             if (e.target) system(e.target.name, temp_engine); | ||||
|         }); | ||||
|         $(window).on("resize", () => { | ||||
|             canvas.setWidth((window.innerWidth/10)*9); | ||||
|             canvas.setHeight((window.innerHeight/4)*3); | ||||
|             canvas.renderAll(); | ||||
|         }); | ||||
|         canvas.on("mouse:wheel", (opt) => { | ||||
|             console.log(opt.e.clientX); | ||||
|             let scale = 1.1; | ||||
|             if (opt.e.deltaY < 0) { | ||||
|                 canvas.zoomToPoint(new fabric.Point(opt.e.clientX / canvas.getZoom(), opt.e.clienY / canvas.getZoom()), canvas.getZoom() * scale); | ||||
|             } else if (opt.e.deltaY > 0) { | ||||
|                 canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), canvas.getZoom() / scale); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|     temp_engine.render("templates/systems/systems.html"); | ||||
| } | ||||
| @ -0,0 +1,9 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| import { TemplateEngine } from "./skama_code/ui/templeting_engine.js"; | ||||
| import home from "./controllers/home.js"; | ||||
| 
 | ||||
| let temp_engine = new TemplateEngine("html"); | ||||
| home(temp_engine); | ||||
| 
 | ||||
| 
 | ||||
| @ -1,130 +0,0 @@ | ||||
| // Copyright © 2023 Entreprise SkamCraft
 | ||||
| "use strict"; | ||||
| 
 | ||||
| import AUTH from "./auth.js"; | ||||
| import SpaceTraders from "./api.js"; | ||||
| 
 | ||||
| $(document).ready(async function () { | ||||
|   //Auth
 | ||||
|   if (document.URL.includes("login.html")) { | ||||
|     $("#btn-login").on("click", () => { | ||||
|       AUTH.login(); | ||||
|     }); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (document.URL.includes("register.html")) { | ||||
|     const factions = await SpaceTraders.Faction.list(10, 1); | ||||
|     factions.forEach((faction) => { | ||||
|       const option = `<option>${faction.symbol}</option>`; | ||||
|       $("#group-faction").append(option); | ||||
|     }); | ||||
| 
 | ||||
|     $("#btn-register").on("click", () => { | ||||
|       AUTH.register(); | ||||
|     }); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   if (!(await AUTH.isLogin())) window.location.href = "login.html"; | ||||
| 
 | ||||
|   agent(); | ||||
| 
 | ||||
|   //Buttons
 | ||||
|   $("#btn-contract").on("click", () => { | ||||
|     contract(); | ||||
|   }); | ||||
|   $("#btn-faction").on("click", () => {}); | ||||
|   $("#btn-ship").on("click", () => { | ||||
|     ship(); | ||||
|   }); | ||||
|   $("#btn-system").on("click", () => {}); | ||||
|   $("#btn-logout").on("click", () => { | ||||
|     logout(); | ||||
|   }); | ||||
| }); | ||||
| 
 | ||||
| function loadPage(page) { | ||||
|   $("main").load(`templates/${page}.html`); | ||||
| } | ||||
| 
 | ||||
| function logout() { | ||||
|   localStorage.removeItem("token"); | ||||
|   window.location.href = "login.html"; | ||||
| } | ||||
| 
 | ||||
| async function agent() { | ||||
|   let token = localStorage.getItem("token"); | ||||
|   let agent = await SpaceTraders.Agent.get(token); | ||||
| 
 | ||||
|   $("#credits").text(agent.credits.toLocaleString() + " $"); | ||||
| } | ||||
| 
 | ||||
| async function contract() { | ||||
|   const token = localStorage.getItem("token"); | ||||
|   const contracts = await SpaceTraders.Contract.list(token); | ||||
| 
 | ||||
|   $("main").empty(); | ||||
| 
 | ||||
|   contracts.forEach((contract) => { | ||||
|     let card = `<div class="card">
 | ||||
|       <div class="card-title"> | ||||
|         <h1>${contract.id}</h1> | ||||
|       </div> | ||||
|     </div>;`; | ||||
|     $("main").append(card); | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| async function ship() { | ||||
|   const token = localStorage.getItem("token"); | ||||
|   const ships = await SpaceTraders.Ships.list(token); | ||||
|   console.log(ships) | ||||
|   $("main").empty(); | ||||
|   ships.forEach((ship) => { | ||||
|     let img = "/img/Skamkraft.png"; | ||||
|     const card = `                            
 | ||||
|     <div class="card spacer" style="width: 20rem;"> | ||||
|       <img src="${img}" class="card-img-top" alt=""> | ||||
|         <div class="card-body"> | ||||
|           <h5 style="color:white" class="card-title">${ship.symbol}</h5> | ||||
|           <p style="color:white" class="card-text">Location : ${ship.nav.waypointSymbol}</p> | ||||
|           <p style="color:white" id="status" class="card-text">Status : ${ship.nav.status}</p> | ||||
|           <button id="btn-infos" type="button" data-ships-id="${ship.symbol}" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">Infos</button>                       | ||||
|         </div> | ||||
|     </div> | ||||
|   `;
 | ||||
|     $("main").append(card); | ||||
| 
 | ||||
|     $("#btn-infos").on("click", async function () { | ||||
|       const token = localStorage.getItem("token"); | ||||
|       const ships = await SpaceTraders.Ships.get(token,$(this).attr('data-ships-id')); | ||||
|     console.log("info") | ||||
|       const modal = ` | ||||
|       <div class="modal fade" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> | ||||
|         <div class="modal-dialog"> | ||||
|           <div class="modal-content"> | ||||
|             <div class="modal-header"> | ||||
|               <h1 class="modal-title fs-5">${ships.symbol}</h1> | ||||
|               <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> | ||||
|             </div> | ||||
|             <div class="modal-body"> | ||||
|               fuel current ammount : ${ships.fuel.current} <br> | ||||
|               fuel capacity : ${ships.fuel.capacity} <br> | ||||
|               crew current ammount : ${ships.crew.current} <br> | ||||
|               crew capacity : ${ships.crew.capacity} <br> | ||||
|               crew moral : ${ships.crew.morale}/100 <br> | ||||
|               frame : ${ships.frame.description} <br> | ||||
|               reactor : ${ships.reactor.description} <br> | ||||
|               engine : ${ships.engine.description} 
 | ||||
|             </div> | ||||
|             <div class="modal-footer"> | ||||
|               <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div>` | ||||
|       $("main").append(modal); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| @ -0,0 +1,122 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| import { SpaceTraders } from "./config.js" | ||||
| 
 | ||||
| export class My { | ||||
|   static agent = null; | ||||
| } | ||||
| 
 | ||||
| export class Agent { | ||||
|   constructor(agent, token = "") { | ||||
|     this.token = token; | ||||
|     this.name = agent.symbol; | ||||
|     this.credits = agent.credits; | ||||
|     this.faction = agent.startingFaction; | ||||
|     this.hq = agent.headquarters; | ||||
|     this.ships_cpt = agent.shipCount;   
 | ||||
|   } | ||||
| 
 | ||||
|   get_agent_system() { | ||||
|     let metaSystem = this.hq.split("-"); | ||||
|     return metaSystem[0] + "-" + metaSystem[1]; 
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export class AgentBuilder { | ||||
|   static create(symbol, faction, callback, error_handler) { | ||||
|       const url = `${SpaceTraders.host}/register`; | ||||
|       $.ajax({ | ||||
|         url: url, | ||||
|         method: "POST", | ||||
|         headers: { "Content-Type": "application/json" }, | ||||
|         processData: false, | ||||
|         data: `{\n  "faction": "${faction}",\n  "symbol": "${symbol}"}`, | ||||
|         success: (reponse) => { | ||||
|           let agent = new Agent(reponse.data.agent, reponse.data.token) | ||||
|           callback(agent); | ||||
|         }, | ||||
|         error: (err) => { | ||||
|           error_handler(["Name already took."]) | ||||
|         } | ||||
|       }); | ||||
|   } | ||||
| 
 | ||||
|   static get(token, callback, error_handler){ | ||||
|     const url = `${SpaceTraders.host}/my/agent`; | ||||
|     $.ajax({ | ||||
|         url: url, | ||||
|         method: "GET", | ||||
|         headers: { | ||||
|           Accept: "application/json", | ||||
|           Authorization: `Bearer ${token}`, | ||||
|         }, | ||||
|         success: (reponse) => { | ||||
|           let agent = new Agent(reponse.data, token); | ||||
|           callback(agent); | ||||
|         }, | ||||
|         error: (err) => { | ||||
|           error_handler(["Token invalide."]); | ||||
|         } | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   static get_public(symbol, callback) { | ||||
|     const url = `${SpaceTraders.host}/agents/${symbol}`; | ||||
|     $.ajax({ | ||||
|       url: url, | ||||
|       method: "GET", | ||||
|       headers: { | ||||
|         Accept: "application/json" 
 | ||||
|       }, | ||||
|       success: (reponse) => { | ||||
|         let agent = new Agent(reponse.data); | ||||
|         callback(agent); | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   static list(limit, page, callback, agents = []) { | ||||
|     const url = `${SpaceTraders.host}/agents`; | ||||
|     const data = { limit, page }; | ||||
|     $.ajax({ | ||||
|       url: url, | ||||
|       method: "GET", | ||||
|       headers: { | ||||
|         Accept: "application/json" 
 | ||||
|       }, | ||||
|       data: data, | ||||
|       success: (reponse) => { | ||||
|         reponse.data.forEach(agent => { | ||||
|           agents.push(new Agent(agent)); | ||||
|         }); | ||||
|         callback(agents, reponse.meta); | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   static list_all(callback, end = false) { | ||||
|     this.list(20, 1, (agents, meta) => { | ||||
|       let maxPage = meta.total / 20; | ||||
|       this.#r_listing(2, maxPage, agents, callback, end); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   static #r_listing(page, maxPage, agents, callback, end) { | ||||
|     if (page < maxPage) { | ||||
|       this.list(20, page++,() => { | ||||
|         setTimeout(() => { | ||||
|           if (!end) { | ||||
|             callback(agents); | ||||
|             agents = []; | ||||
|           } | ||||
|           this.#r_listing(page++, maxPage, agents, callback, end); 
 | ||||
|         }, 1000); | ||||
|       }, agents); | ||||
|     } else { | ||||
|       callback(agents); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1,7 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| export const SpaceTraders = { | ||||
|         host: "https://api.spacetraders.io/v2", | ||||
|         limit_max: 20, | ||||
| } | ||||
| @ -0,0 +1,71 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| import { SpaceTraders } from "./config.js"; | ||||
| import { Position } from "../commun/position.js"; | ||||
| 
 | ||||
| class Market { | ||||
|     constructor(market) { | ||||
|         this.symbol = market.symbol; | ||||
|         this.exports = market.exports; | ||||
|         this.imports = market.imports; | ||||
|         this.exchange = market.exchange; | ||||
|         this.transctions = market.transctions; | ||||
|         this.trade_goods = market.tradeGoods; | ||||
|     } | ||||
| 
 | ||||
|     has_export(market_export) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     list_exports(callback) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     has_import(market_import) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     list_import(callback) { | ||||
|         
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class Planet { | ||||
|     constructor(waypoint) { | ||||
|         this.name = waypoint.symbol; | ||||
|         this.type = waypoint.type; | ||||
|         this.system = waypoint.systemSymbol; | ||||
|         this.position = new Position(waypoint.x, waypoint.y); | ||||
|         this.moons = waypoint.orbitals; | ||||
|         this.orbits = waypoint.orbits; | ||||
|         this.faction = waypoint.faction; | ||||
|         this.traits = waypoint.traits; | ||||
|         this.dangers = waypoint.modifiers; | ||||
|         this.discovery = waypoint.char; | ||||
|         this.is_under_construction = waypoint.isUnderConstruction; | ||||
|     } | ||||
| 
 | ||||
|     get_market(callback, error_handler) { | ||||
|         const url = `${SpaceTraders.host}/systems/${this.system}/waypoints/${this.name}/market`; | ||||
|         $.ajax({ | ||||
|             url: url, | ||||
|             method: "GET", | ||||
|             success: (reponse) => { | ||||
|                 let market = new Market(reponse.data); | ||||
|                 callback(market); | ||||
|             }, | ||||
|             error: (err) => { | ||||
|                 error_handler("Market not found"); | ||||
|             } | ||||
|         });  
 | ||||
|     } | ||||
| 
 | ||||
|     is_type(type) { | ||||
|         return this.type === type ? true : false; | ||||
|     } | ||||
| 
 | ||||
|     is_discovered() { | ||||
|         return this.discovery.length > 0 ? true : false; | ||||
|     }    
 | ||||
| } | ||||
| @ -0,0 +1,67 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| "use strict"; | ||||
| import { SpaceTraders } from "./config.js"; | ||||
| import { My } from "./agent.js"; | ||||
| 
 | ||||
| export class Ship { | ||||
|   constructor(data) { | ||||
|     this.name = data.symbol; | ||||
|     this.AgentName = data.registration; | ||||
|     this.Nav = data.nav; | ||||
|     this.crew = data.crew; | ||||
|     this.engine = data.engine; | ||||
|     this.fuel = data.fuel; | ||||
|   } | ||||
| 
 | ||||
|   static list(callback) { | ||||
|     const url = `${SpaceTraders.host}/my/ships`; | ||||
|     $.ajax({ | ||||
|       url: url, | ||||
|       method: "GET", | ||||
|       headers: { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${My.agent.token}`, | ||||
|       }, | ||||
|       success: (response) => { | ||||
|         callback(response); | ||||
|       }, | ||||
|       error: (err) => { | ||||
|         error_handler(["Token invalide."]); | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
|   static get(callback) { | ||||
|     const url = `${SpaceTraders.host}/my/ships/${this.name}`; | ||||
|     $.ajax({ | ||||
|       url: url, | ||||
|       method: "GET", | ||||
|       headers: { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }, | ||||
|       success: (response) => { | ||||
|         callback(response); | ||||
|       }, | ||||
|       error: (err) => { | ||||
|         error_handler(["Token invalide."]); | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
|   static getPosition(callback) { | ||||
|     const url = `${SpaceTraders.host}/my/ships/${this.name}/nav`; | ||||
|     $.ajax({ | ||||
|       url: url, | ||||
|       method: "GET", | ||||
|       headers: { | ||||
|         Accept: "application/json", | ||||
|         Authorization: `Bearer ${token}`, | ||||
|       }, | ||||
|       success: (response) => { | ||||
|         callback(response); | ||||
|       }, | ||||
|       error: (err) => { | ||||
|         error_handler(["Token invalide."]); | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,135 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| import { SpaceTraders } from "./config.js"; | ||||
| import { Position } from "../commun/position.js"; | ||||
| import { Planet } from "./planet.js"; | ||||
| 
 | ||||
| export class System { | ||||
|     constructor(data) { | ||||
|         this.name = data.symbol; | ||||
|         this.sector = data.sectorSymbol; | ||||
|         this.type = data.type; | ||||
|         this.position = new Position(data.x, data.y); | ||||
|         this.factions = data.factions; | ||||
|     } | ||||
| 
 | ||||
|     get(name, callback, error_handler) { | ||||
|         const url = `${SpaceTraders.host}/systems/${this.name}/waypoints/${name}`; | ||||
|         $.ajax({ | ||||
|             url: url, | ||||
|             method: "GET", | ||||
|             success: (reponse) => { | ||||
|                 let planet = new Planet(reponse.data); | ||||
|                 callback(planet); | ||||
|             }, | ||||
|             error: (err) => { | ||||
|                 error_handler("Planet not found"); | ||||
|             } | ||||
|         }); | ||||
|     } 
 | ||||
| 
 | ||||
|     list(limit, page, callback, planets = []) { | ||||
|         const url = `${SpaceTraders.host}/systems/${this.name}/waypoints` | ||||
|         $.ajax({ | ||||
|             url: url, | ||||
|             method: "GET", | ||||
|             data: { | ||||
|                 limit: limit, | ||||
|                 page: page | ||||
|             }, | ||||
|             success: (reponse) => { | ||||
|                 reponse.data.forEach(planet => { | ||||
|                     planets.push(new Planet(planet)); | ||||
|                 }); | ||||
|                 callback(planets, reponse.meta); | ||||
|             } 
 | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     list_all(callback, end = false) { | ||||
|         this.list(20, 1, (planets, meta) => { | ||||
|             let maxPage = meta.total / 20; | ||||
|             this.#r_listing(2, maxPage, planets, callback, end); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     #r_listing(page, maxPage, planets, callback, end) { | ||||
|         if (page < maxPage) { | ||||
|             this.list(20, page++, () => { | ||||
|                 setTimeout(() => { | ||||
|                     if (!end) { | ||||
|                         callback(planets); | ||||
|                         planets = []; | ||||
|                     } | ||||
|                     this.#r_listing(page++, maxPage, planets, callback, end); 
 | ||||
|                 }, 1000); | ||||
|             }, planets); | ||||
|         } else { | ||||
|             callback(planets); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export class SystemBuilder { | ||||
|     static parse_system_name(name) { | ||||
|         return name.split("-").slice(-1, 2).join("-"); | ||||
|     } | ||||
| 
 | ||||
|     static get(name, callback, error_handler) { | ||||
|         const url = `${SpaceTraders.host}/systems/${name}/`; | ||||
|         $.ajax({ | ||||
|             url: url, | ||||
|             method: "GET", | ||||
|             success: (reponse) => { | ||||
|                 let system = new System(reponse.data); | ||||
|                 callback(system); | ||||
|             }, | ||||
|             error: (err) => { | ||||
|                 error_handler("System not found"); | ||||
|             } | ||||
|         }); | ||||
|     } 
 | ||||
| 
 | ||||
|     static list(limit, page, callback, systems = []) { | ||||
|         const url = `${SpaceTraders.host}/systems/` | ||||
|         $.ajax({ | ||||
|             url: url, | ||||
|             method: "GET", | ||||
|             data: { | ||||
|                 limit: limit, | ||||
|                 page: page | ||||
|             }, | ||||
|             success: (reponse) => { | ||||
|                 reponse.data.forEach(system => { | ||||
|                     systems.push(new System(system)); | ||||
|                 }); | ||||
|                 callback(systems, reponse.meta); | ||||
|             } 
 | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     static list_all(callback, end = false) { | ||||
|         this.list(20, 1, (systems, meta) => { | ||||
|             let maxPage = meta.total / 20; | ||||
|             this.#r_listing(2, maxPage, systems, callback, end); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     static #r_listing(page, maxPage, systems, callback, end) { | ||||
|         if (page < maxPage) { | ||||
|             this.list(20, page++, () => { | ||||
|                 setTimeout(() => { | ||||
|                     if (!end) { | ||||
|                         console.log(systems); | ||||
|                         callback(systems); | ||||
|                         systems = []; | ||||
|                     } | ||||
|                     this.#r_listing(page++, maxPage, systems, callback, end); 
 | ||||
|                 }, 1000); | ||||
|             }, systems); | ||||
|         } else { | ||||
|             callback(systems); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,89 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| import { AgentBuilder } from '../api/agent.js' | ||||
| import Strategie from '../commun/strategie.js'; | ||||
| 
 | ||||
| let strategies = { | ||||
|     register: [ | ||||
|         { | ||||
|             name: "name", | ||||
|             validations: [ | ||||
|                 "required", | ||||
|                 "max_length|14" | ||||
|             ] | ||||
|         }, | ||||
|         { | ||||
|             name: "faction", | ||||
|             validations: [ | ||||
|                 "required" | ||||
|             ] | ||||
|         } | ||||
|     ], | ||||
|     login: [ | ||||
|         { | ||||
|             name: "token", | ||||
|             validations: [ | ||||
|                 "required" | ||||
|             ] | ||||
|         } | ||||
|     ] | ||||
| } | ||||
| 
 | ||||
| export class Auth { | ||||
|     constructor(store = false) { | ||||
|         this.store = store; | ||||
|         this.validated = () => {}; | ||||
|         this.error_handler = () => {}; | ||||
|         this.strategies = strategies; | ||||
|     } | ||||
| 
 | ||||
|     done(validated) { | ||||
|         this.validated = validated; | ||||
|         return this; | ||||
|     } | ||||
|     
 | ||||
|     fail(error_handler) { | ||||
|         this.error_handler = error_handler; | ||||
|         return this; | ||||
|     } | ||||
| 
 | ||||
|     login(token) { | ||||
|         let validateur = new Strategie(this.strategies.login); | ||||
|         validateur.validate("token", token); | ||||
|         if (validateur.errors.length > 0) this.error_handler(validateur.errors); | ||||
|         else { | ||||
|             if (this.store) localStorage.setItem("token", token); | ||||
|             AgentBuilder.get(token, this.validated, this.error_handler); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     relog() { | ||||
|         if(this.#is_login()) { | ||||
|             AgentBuilder.get(localStorage.getItem("token"), this.validated, this.error_handler); 
 | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     register(new_agent) { | ||||
|         let validateur = new Strategie(this.strategies.register); | ||||
|         validateur.validate("name", new_agent.name); | ||||
|         validateur.validate("faction", new_agent.faction); | ||||
|         if (validateur.errors.length > 0) this.error_handler(validateur.errors); | ||||
|         else {            
 | ||||
|             AgentBuilder.create(new_agent.name, new_agent.faction, (agent) => { | ||||
|                 if (this.store) localStorage.setItem("token", agent.token); | ||||
|                 this.validated(agent); | ||||
|             }, this.error_handler); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     unload_token() { | ||||
|         if(this.#is_login()) localStorage.removeItem("token"); | ||||
|     } | ||||
| 
 | ||||
|     #is_login() { | ||||
|         if (localStorage.getItem("token")) return true | ||||
|         return false | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,18 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| export class Position { | ||||
|     constructor(x, y) { | ||||
|         this.x = x; | ||||
|         this.y = y; | ||||
|     } | ||||
| 
 | ||||
|     get_canvas_pos(w, h) { | ||||
|         return new Position(x - w/2, y - h/2) | ||||
|     } | ||||
| 
 | ||||
|     move(position) { | ||||
|         this.x += position.x; | ||||
|         this.y += position.y; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| export default class Strategie { | ||||
|     constructor(strategie) { | ||||
|         this.strategie = strategie; | ||||
|         this.errors = []; | ||||
|     } | ||||
| 
 | ||||
|     validate(name, input) { | ||||
|         this.strategie.forEach(input_strat => { | ||||
|             if(input_strat.name === name) input_strat.validations.forEach((validation) => { | ||||
|                 let args = validation.split("|"); | ||||
|                 switch (args[0]) { | ||||
|                     case "required": 
 | ||||
|                         this.#test(Strategie.#required(input), `${name} is required.`); | ||||
|                         break; | ||||
|                     case "max_length": | ||||
|                         this.#test(Strategie.#max_length(input, parseInt(args[1])), `${name} must have a max lenght of ${args[1]}.`); | ||||
|                         break; | ||||
|                     case "min_length": | ||||
|                         this.#test(Strategie.#min_length(input, parseInt(args[1])), `${name} must have a min lenght of ${args[1]}`); | ||||
|                         break; | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     #test(test, error) { | ||||
|         if(!test) this.errors.push(error); 
 | ||||
|     } | ||||
| 
 | ||||
|     static #valide_email(input) { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     static #min_length(input, length) { | ||||
|         if(input.length < length) return false; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     static #max_length(input, length) { | ||||
|         if(input.length > length) return false; | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     static #required(input) { | ||||
|         if (input === undefined || input === null || input === "") return false; | ||||
|         return true; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,59 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| export class Timer { | ||||
|     constructor(time, step, unit = "s") { | ||||
|         this.passed_time = 0; | ||||
|         this.time = time; | ||||
|         this.step = step; | ||||
|         this.continue = true; | ||||
|         switch (unit) { | ||||
|             case "ms": 
 | ||||
|                 this.unit = 1; | ||||
|                 break;  
 | ||||
|             case "s": 
 | ||||
|                 this.unit = 1000; | ||||
|                 break; | ||||
|             case "m": 
 | ||||
|                 this.unit = 60000; | ||||
|                 break; | ||||
|             case "h": 
 | ||||
|                 this.unit = 3600000; | ||||
|                 break; | ||||
|             default: | ||||
|                 this.unit = 1; | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|     on(action, callback) { | ||||
|         switch(action) { | ||||
|             case "end": | ||||
|                 this.end_callback = callback; | ||||
|                 break; | ||||
|             case "step": | ||||
|                 this.step_callback = callback; | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
|     start() { | ||||
|         this.continue = true; | ||||
|         this.#time_step(); | ||||
|     } | ||||
| 
 | ||||
|     stop() { | ||||
|         this.continue = false; | ||||
|         this.passed_time = 0; | ||||
|     } | ||||
| 
 | ||||
|     #time_step() { | ||||
|         if (this.passed_time < this.time && this.continue) { | ||||
|             if (this.step_callback) this.step_callback(this.passed_time); | ||||
|             this.passed_time += this.step; | ||||
|             setTimeout(() => { 
 | ||||
|                 this.#time_step() 
 | ||||
|             }, this.step*this.unit);           
 | ||||
|         } else { | ||||
|             if (this.end_callback) this.end_callback(this.time); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,39 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| export class Modal { | ||||
|     constructor(name, template_engine, tag = "#block-content") { | ||||
|         this.name = name; | ||||
|         this.template_engine = template_engine; | ||||
|         this.tag = tag; | ||||
|         this.modal_class = ""; | ||||
|     } | ||||
| 
 | ||||
|     load(template) { | ||||
|         this.template_engine.get_template((reponse) => { | ||||
|             $(this.tag).prepend(` | ||||
|                 <dialog id="${this.name}" class="${this.modal_class} modal-disable"> | ||||
|                     ${reponse} | ||||
|                 </dialog> | ||||
|             `);
 | ||||
|         }, template); | ||||
|     } | ||||
| 
 | ||||
|     on_close(callback) { | ||||
|         document.querySelector(`#${this.name}`).addEventListener("close", callback); | ||||
|     } | ||||
| 
 | ||||
|     add_class(modal_class) { | ||||
|         let modal; | ||||
|         if(modal = $(`#${this.name}`)) modal.addClass(modal_class); | ||||
|         this.modal_class = `${this.modal_class} ${modal_class}`; | ||||
|     } | ||||
| 
 | ||||
|     show() { | ||||
|         document.querySelector(`#${this.name}`).showModal(); 
 | ||||
|     } | ||||
| 
 | ||||
|     close() { | ||||
|         document.querySelector(`#${this.name}`).close(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| "use strict"; | ||||
| export class TemplateEngine { | ||||
|   constructor(path) { | ||||
|     this.templatePath = path; | ||||
|   } | ||||
| 
 | ||||
|   render(template) { | ||||
|     this.get_template((reponse) => { | ||||
|       $("body").html(reponse); | ||||
|       this.get_template((reponse) => { | ||||
|         $("#block-content").html(reponse); | ||||
|         if (this.after_render_callback) | ||||
|           this.#flush_events().after_render_callback(this); | ||||
|       }, template); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   frag_load(tag, template) { | ||||
|     this.get_template((reponse) => { | ||||
|       $(tag).html(reponse); | ||||
|     }, template); | ||||
|   } | ||||
| 
 | ||||
|   get_template(callback, template = "") { | ||||
|     let url = | ||||
|       template === "" | ||||
|         ? `${this.templatePath}/template.html` | ||||
|         : `${this.templatePath}/${template}`; | ||||
|     $.ajax(url, { | ||||
|       method: "GET", | ||||
|       success: callback, | ||||
|       error: (err) => { | ||||
|         console.log(err); | ||||
|       }, | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   add_event(tag, action, callback) { | ||||
|     $("body").on(action, tag, callback); | ||||
|   } | ||||
| 
 | ||||
|   #flush_events() { | ||||
|     $("body").unbind(); | ||||
|     return this; | ||||
|   } | ||||
| 
 | ||||
|   after_render(callback) { | ||||
|     this.after_render_callback = callback; | ||||
|   } | ||||
| } | ||||
| @ -0,0 +1,105 @@ | ||||
| // Copyright © 2023 Entreprise SkamKraft
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| import { Timer } from "../skama_code/ui/timer.js"; | ||||
| import { Modal } from "../skama_code/ui/modal.js"; | ||||
| import { TemplateEngine } from "../skama_code/ui/templeting_engine.js"; | ||||
| import { Initialzer } from "../skama_code/commun/initialzer.js "; | ||||
| import { AgentBuilder } from "../skama_code/api/agent.js"; | ||||
| import { Auth } from "../skama_code/auth/auth.js"; | ||||
| import { PlanetBuilder } from "../skama_code/api/planet.js"; | ||||
| 
 | ||||
| let temp_path = "html"; | ||||
| let token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGlmaWVyIjoiSEFSRElDSyIsInZlcnNpb24iOiJ2Mi4xLjQiLCJyZXNldF9kYXRlIjoiMjAyMy0xMi0wMiIsImlhdCI6MTcwMjY2Mjc2Mywic3ViIjoiYWdlbnQtdG9rZW4ifQ.PrvaOz3W79acq6RoxryMW53PRRz824_AM0VGLwfXCOsGCOCAIY-rn6-bZTOnLAtp4xPSDqEk4c38oWYAWW59p0iMDDLpur6ONnjT0RjjsQS9zr5BByfBpP36CT23IZSSzk3XxGrFolHJAyU3K1liYfNbsPuNTXlkHGNHq6yMqH4ZQUPFsXEsCkg9cUynkdLw3C39SvWhtJ89oblj_8tQp2k8dxhZemepuXtiI51eFMpv8A0WRAi7pVYo_ajJujY9QDLYn_m5hDZWTlQMIstjPaDl99p2IMweIMO2Q2G-0lKiWQ4sl6VW5tuVrz1HLYU6kyMjFQWNn6kFDE7LWMTrfw"; | ||||
| 
 | ||||
| let tests = { | ||||
|     timer: function() { | ||||
|         let timer = new Timer(1, 0.1666, "m"); | ||||
|         timer.on("step", (time) => { | ||||
|             console.log(time); | ||||
|         }) | ||||
|         timer.on("end", () => { | ||||
|             console.log("pattes fini"); | ||||
|         }); | ||||
|         timer.start(); | ||||
|     }, | ||||
|     render_template: function() { | ||||
|         let UI = new TemplateEngine(temp_path); | ||||
|         let initer = new Initialzer(UI); | ||||
| 
 | ||||
|         UI.render("templates/home.html"); | ||||
|         UI.frag_load("#test", "templates/login.html"); | ||||
| 
 | ||||
|         $(document).ready(() => { | ||||
|             initer.init_menu_link("#contracts-link", "contracts.html"); | ||||
|             initer.init_menu_link("#ships-link", "ships.html"); | ||||
|             initer.init_menu_link("#systems-link", "systems.html"); | ||||
|             initer.init_menu_link("#signup-link", "register.html"); | ||||
|             initer.init_menu_link("#signin-link", "login.html"); | ||||
|             initer.init_menu_link(".nav-brand", "home.html"); | ||||
|         }); | ||||
|     }, | ||||
|     authentication: function() { | ||||
|         let auth = new Auth(true); | ||||
|         auth.done((agent) => { | ||||
|             console.log(agent); | ||||
|         }).fail((errs) => { | ||||
|             errs.forEach(err => { | ||||
|                 console.log(err); | ||||
|             }); | ||||
|         }); | ||||
|         auth.login(token); | ||||
|         auth.relog(); | ||||
| 
 | ||||
|         //auth.register({
 | ||||
|         //    symbol: "lkdsjfsjdlfjlk",
 | ||||
|         //    faction: "COSMIC"
 | ||||
|         //});
 | ||||
|     }, | ||||
|     modal: function() { | ||||
| 
 | ||||
|         let template_engine = new TemplateEngine(temp_path); | ||||
|         
 | ||||
|         let timer = new Timer(60, 1, "s"); | ||||
|         timer.on("step", (time) => { | ||||
|             $("#timer").html(` | ||||
|                 <p>${time}</p> | ||||
|             `);
 | ||||
|         }); | ||||
|         template_engine.render("templates/login.html"); | ||||
| 
 | ||||
|         let modal = new Modal("test-modal", template_engine); | ||||
|         modal.add_class("ext-modal") | ||||
| 
 | ||||
|         modal.load("templates/test_modal.html"); | ||||
| 
 | ||||
|         template_engine.add_event("#valid", "click", () => { | ||||
|             modal.show(); | ||||
|             timer.start(); | ||||
|         }); | ||||
| 
 | ||||
|         template_engine.add_event("#ok", "click", () => { | ||||
|             modal.close(); | ||||
|             timer.stop(); | ||||
|         }); | ||||
|     }, | ||||
|     get_planet: function() { | ||||
|         PlanetBuilder.get("X1-TT23-FF1E", (planet) => { | ||||
|             console.log(planet); | ||||
|         }, (err) => { | ||||
|             console.log(err); | ||||
|         }); | ||||
|     }, | ||||
|     get_all_planets: function() { | ||||
|         PlanetBuilder.list_all("X1-AG10", (planets) => { | ||||
|             console.log(planets); | ||||
|         }); | ||||
|     }, | ||||
|     get_all_agents: function() { | ||||
|         AgentBuilder.list_all((agents) => { | ||||
|             console.log(agents); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export default tests; | ||||
| @ -1,65 +0,0 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <title>Skamkraft</title> | ||||
|     <link rel="icon" type="image/png" href="/img/Skamkraft.png" /> | ||||
| 
 | ||||
|     <link rel="stylesheet" href="/css/auth.css" /> | ||||
| 
 | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;500&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <script | ||||
|       src="https://code.jquery.com/jquery-3.7.1.min.js" | ||||
|       integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" | ||||
|       crossorigin="anonymous" | ||||
|     ></script> | ||||
|     <script type="module" src="js/main.js" defer></script> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div class="logo"> | ||||
|       <img src="/img/Skamkraft.png" /> | ||||
|       <h4>Skamkraft</h4> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="form" aria-setsize="19"> | ||||
|       <div class="title"> | ||||
|         Bienvenue sur Skamkraft,<br /><span | ||||
|           >Entrez votre token pour continuer</span | ||||
|         > | ||||
|       </div> | ||||
|       <input id="input-token" class="input" placeholder="Token" type="text" /> | ||||
|       <button id="btn-login" class="button-confirm">Continuer →</button> | ||||
|       <div class="link-connection"> | ||||
|         <a class="animation-underline" href="register.html">Sign Up</a> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div id="box-alert" class="alert" hidden> | ||||
|       <div class="alert-inner"> | ||||
|         <svg | ||||
|           xmlns="http://www.w3.org/2000/svg" | ||||
|           viewBox="0 0 24 24" | ||||
|           class="icon" | ||||
|         > | ||||
|           <path | ||||
|             fill-rule="evenodd" | ||||
|             d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" | ||||
|             clip-rule="evenodd" | ||||
|           ></path> | ||||
|         </svg> | ||||
| 
 | ||||
|         <strong class="message"> Quelque chose s'est mal passé</strong> | ||||
|       </div> | ||||
| 
 | ||||
|       <p id="error-message" class="content"></p> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
| @ -1,68 +0,0 @@ | ||||
| <!-- Copyright © 2023 Entreprise SkamKraft --> | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|   <head> | ||||
|     <meta charset="UTF-8" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
|     <title>Skamkraft</title> | ||||
|     <link rel="icon" type="image/png" href="/img/Skamkraft.png" /> | ||||
| 
 | ||||
|     <link rel="stylesheet" href="/css/auth.css" /> | ||||
| 
 | ||||
|     <link rel="preconnect" href="https://fonts.googleapis.com" /> | ||||
|     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | ||||
|     <link | ||||
|       href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;500&display=swap" | ||||
|       rel="stylesheet" | ||||
|     /> | ||||
|     <script | ||||
|       src="https://code.jquery.com/jquery-3.7.1.min.js" | ||||
|       integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" | ||||
|       crossorigin="anonymous" | ||||
|     ></script> | ||||
|     <script type="module" src="js/main.js" defer></script> | ||||
|   </head> | ||||
|   <body> | ||||
|     <div class="logo"> | ||||
|       <img src="/img/Skamkraft.png" /> | ||||
|       <h4>Skamkraft</h4> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="form" aria-setsize="19"> | ||||
|       <div class="title"> | ||||
|         Bienvenue sur Skamkraft,<br /> | ||||
|         <span>Entrez votre symbol pour continuer</span> | ||||
|       </div> | ||||
|       <input id="input-symbol" class="input" placeholder="Symbol" type="text" /> | ||||
|       <select id="input-faction" class="input select"> | ||||
|         <option value="" disabled selected>Faction</option> | ||||
|         <optgroup id="group-faction" label="---------"></optgroup> | ||||
|       </select> | ||||
|       <button id="btn-register" class="button-confirm">Continuer →</button> | ||||
|       <div class="link-connection"> | ||||
|         <a class="animation-underline" href="login.html">Login</a> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|     <div id="box-alert" class="alert" hidden> | ||||
|       <div class="alert-inner"> | ||||
|         <svg | ||||
|           xmlns="http://www.w3.org/2000/svg" | ||||
|           viewBox="0 0 24 24" | ||||
|           class="icon" | ||||
|         > | ||||
|           <path | ||||
|             fill-rule="evenodd" | ||||
|             d="M9.401 3.003c1.155-2 4.043-2 5.197 0l7.355 12.748c1.154 2-.29 4.5-2.599 4.5H4.645c-2.309 0-3.752-2.5-2.598-4.5L9.4 3.003zM12 8.25a.75.75 0 01.75.75v3.75a.75.75 0 01-1.5 0V9a.75.75 0 01.75-.75zm0 8.25a.75.75 0 100-1.5.75.75 0 000 1.5z" | ||||
|             clip-rule="evenodd" | ||||
|           ></path> | ||||
|         </svg> | ||||
| 
 | ||||
|         <strong class="message"> Quelque chose s'est mal passé</strong> | ||||
|       </div> | ||||
| 
 | ||||
|       <p id="error-message" class="content"></p> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
| @ -1 +0,0 @@ | ||||
| <div class="contrats"></div> | ||||
| @ -1 +0,0 @@ | ||||
| <div id="faction" class="page-faction"></div> | ||||
| @ -1,3 +0,0 @@ | ||||
| lister les vaisseaux de depart | ||||
| comment on peut les deplacer | ||||
| token : eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGlmaWVyIjoiREFOSUVMIiwidmVyc2lvbiI6InYyLjEuNCIsInJlc2V0X2RhdGUiOiIyMDIzLTEyLTAyIiwiaWF0IjoxNzAyMDM4NTcwLCJzdWIiOiJhZ2VudC10b2tlbiJ9.cSeOMFA6by3J3mElGL1xKg0p--C7Dcir6VARIs27QmHqTy2hM-pkJosADSLuo-bXHhXSESLlCcmSzS3BIa4T4v6HI0PH4QFpVNjHBSg7-lt1Hjhm4KkRUnmXdBEAeAXq18cbd6xScfRq0rpRNFzJZg5dRit3fjBZ3MSdmlRVroUs4hJaeSu0HLxD3GGRxXRFtvvHgMuFu6vqE1rq0PxTYQksuhu-GGpheCcIuQHNNIGnd0E2z-xzRAJYrRBjdctMDMv_u-RUeM4A6OwAFEczMYM3yDkZJP4qpVKAtriRUxJVkRsqHFLfEzWx7VikwLijN72gbhVzoIJzKh75-1kcyg | ||||