├── .gitignore ├── README.md ├── client ├── client.js ├── config.js └── html │ ├── assets │ ├── css │ │ ├── materialize.css │ │ └── style.css │ ├── fonts │ │ ├── handwritten │ │ │ └── Handwritten.woff │ │ ├── justsignature │ │ │ └── JustSignature.woff │ │ └── roboto │ │ │ ├── Roboto-Bold.woff │ │ │ ├── Roboto-Bold.woff2 │ │ │ ├── Roboto-Light.woff │ │ │ ├── Roboto-Light.woff2 │ │ │ ├── Roboto-Medium.woff │ │ │ ├── Roboto-Medium.woff2 │ │ │ ├── Roboto-Regular.woff │ │ │ ├── Roboto-Regular.woff2 │ │ │ ├── Roboto-Thin.woff │ │ │ └── Roboto-Thin.woff2 │ ├── images │ │ ├── blurr-blue.png │ │ ├── blurr-dark.png │ │ ├── blurr.png │ │ ├── computer_frame.png │ │ ├── icons-system.png │ │ ├── icons.png │ │ ├── login_cardealer.jpg │ │ ├── login_hospital.jpg │ │ ├── login_police.jpg │ │ ├── logo_default.png │ │ ├── logo_hospital.png │ │ ├── logo_police.png │ │ ├── police.jpg │ │ └── windows.png │ ├── js │ │ ├── clicks.js │ │ ├── howler.js │ │ ├── init.js │ │ ├── jquery-ui.js │ │ ├── jquery.js │ │ └── materialize.js │ └── sounds │ │ ├── ding.ogg │ │ ├── error.ogg │ │ ├── notify.ogg │ │ ├── signin.ogg │ │ ├── signout.ogg │ │ ├── turnoff.ogg │ │ ├── turnon.ogg │ │ └── untitled.ogg │ ├── index.html │ └── programs │ ├── account │ ├── account.css │ ├── account.html │ └── account.js │ ├── bossactions │ ├── bossactions.css │ ├── bossactions.html │ └── bossactions.js │ ├── calcylator │ ├── calcylator.css │ ├── calcylator.html │ └── calcylator.js │ ├── cardealer │ ├── cardealer.css │ ├── cardealer.html │ └── cardealer.js │ ├── controlpanel │ ├── controlpanel.css │ ├── controlpanel.html │ └── controlpanel.js │ ├── folder │ ├── folder.css │ ├── folder.html │ └── folder.js │ ├── forum │ ├── forum.css │ ├── forum.html │ ├── forum.js │ ├── important.png │ ├── info.png │ └── news.png │ ├── groups │ ├── groups.css │ ├── groups.html │ └── groups.js │ ├── jobcenter │ ├── jobcenter.css │ ├── jobcenter.html │ └── jobcenter.js │ ├── mail │ ├── mail.css │ ├── mail.html │ ├── mail.jpg │ └── mail.js │ ├── medicalrecords │ ├── medicalrecords.css │ ├── medicalrecords.html │ └── medicalrecords.js │ ├── programConfig.js │ ├── settings │ ├── settings.css │ ├── settings.html │ └── settings.js │ ├── template │ ├── template.css │ ├── template.html │ └── template.js │ ├── terminal │ ├── terminal.css │ ├── terminal.html │ └── terminal.js │ └── twitter │ ├── twitter.css │ ├── twitter.html │ └── twitter.js ├── fxmanifest.lua ├── jsfour_computer.sql └── server └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.psd -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Put on hold since I'm no longer making scripts for FiveM. I haven't touched this script for almost a year now. That's why I will archive this repo. 2 | 3 | # jsfour-computer 4 | 5 | A usable computer in-game. You can easily add your own programs by following the guide down below. To be able to do this you need to have some knowledge in html, javascript and css. **I will not** help you add programs. 6 | 7 | There are a couple of small built-in programs to show examples of what you can do: 8 | * Medical records 9 | * A basic forum for the players current job 10 | * Admin panel to add/delete/modify users 11 | * Twitter: 12 | * A really basic replica of Twitter that lets you tweet. 13 | * Car dealer: 14 | * Shows pictures of vehicles, vehicles can be blacklisted in the programs javascript 15 | * Employees 16 | * Boss actions for the logged in users job. Only available if you have ESX installed. 17 | * Job center 18 | * Shows available jobs. 19 | * Command prompt 20 | * Calcylator 21 | * Folders 22 | * Mail 23 | 24 | A more indepth guide of each program can be found here. 25 | 26 | Due to the lack of time I can't add any more programs. I have however created a list of the programs that I wanted to add to give you some ideas. These programs may be added in another update. 27 | 28 | ### LICENSE 29 | Please don't sell or reupload this resource. 30 | Feel free to make forks and post any updates in the original forum thread. **Do not** create your own thread since it's not a new release. 31 | 32 | ### PREVIEW 33 | [![jsfour-computer preview](https://img.youtube.com/vi/SpRQO5UtZSA/0.jpg)](https://www.youtube.com/watch?v=SpRQO5UtZSA) 34 | 35 | ### INSTALLATION 36 | * Run the SQL file. 37 | * Add `start jsfour-computer` to your server.cfg. 38 | 39 | ##### INFO 40 | * The SQL file will create an admin user, the username and the password is set to `admin`. It's recommended to change this in the user settings inside the computer.. 41 | * The passwords are **not** encrypted, please tell your users to use a simple password, their name or something in case of a leak. 42 | 43 | ### DEFAULT LOCATIONS 44 | ![](https://i.imgur.com/lMWzohx.png) 45 | 46 | *You'll have to add the physical computer to some of the locations by yourself. I'm not including them in this resource since most of the servers have their own versions of every location.* 47 | 48 | ### ADD PROGRAMS 49 | I **won't** provide any personal support regarding adding more programs. Feel free to create a pull request if you want to share a program with others. 50 | 51 | There are currently 4 groups added; `admin, user, all, null`. Null means you don't have to login to be able to use the program. Examples can be found in the programConfig.js file. 52 | 53 | ##### PROGRAMCONFIG.JS 54 | ```javascript 55 | 'programName': { // the name needs to be the same as the html file you added in the programs folder 56 | 'title': 'Employees', // Title of the program that will be displayed in the top left corner of the program. 57 | 'icons': { 58 | start: true, // Adds a start icon if set to true 59 | desktop: false, // Adds a desktop icon if set to true 60 | taskbar: true // Adds a taskbar icon if set to true 61 | }, 62 | 'options': { 63 | allowMinimize: true, // Allowed to minimize the program if set to true 64 | allowResize: true, // Allowed to resize the program if set to true (toggle fullscreen) 65 | allowRefresh: true // Allowed to refresh the program if set to true (calls the programs refresh functon refreshprogramName() if you've created it in the programs js file) 66 | }, 67 | 'access': { 68 | group: 'all', // A string of allowed group, set to 'all' to allow all groups. If set to 'null' it won't read the job down below since null means that the user doesn't have to log in 69 | job: ['police', 'ambulance'] // An array of allowed jobs, set to ['all'] to allow all jobs 70 | }, 71 | 'onStart': { // If onStart doesn't exist it will start the program in fullscreen 72 | fullscreen: true, // Starts the program in fullscreen if set to true 73 | width: '100px', // Sets the programs width, will only work if fullscreen is set to false 74 | height: '100px', // Sets the programs height, will only work if fullscreen is set to false 75 | top: '100px', // Sets the programs start location (offset from top), can't be combined with bottom 76 | bottom: '100px', // Sets the programs start location (offset from bottom), can't be combined with top 77 | right: '100px', // Sets the programs start location (offset from right), can't be combined with left 78 | left: '100px', // Sets the programs start location (offset from left), can't be combined with right 79 | iconDroppable: true // Makes the program icon droppable, it will accept other program icons 80 | }, 81 | 'ESX': true, // If set to true this program requires ESX. If you don't have it installed you won't see this program. Added this to be able to make the script standalone. You won't need this in your program 82 | 'tablet': true // Makes the program accessable on the tablet if set to true. It generates 2 copies of the html file so remember to use class instead of id on elements 83 | } 84 | ``` 85 | 86 | ##### HOW TO 87 | 1. Create a folder inside the html/programs folder without any spaces. (There's a template folder that you can use as a base). 88 | 2. Create a html file inside the folder with the exact same name as the folder. You can currently add files with any of the following extension (.html, .js, .css, .png, .jpg, .gif, .json) in the folder. If you want to include other files this needs to be added in the __resource.lua 89 | 3. Add the program to the programConfig.js file. The name needs to be the exact same as the folder you've just created. 90 | 4. Icons can be added to the icons.png file. PSD file can be found here. 91 | 5. If your program requires data from the database you'll need to specify the SQL query in the server.js. It will then be available when using fetch(). Examples of the fetch function can be found in different programs. 92 | 93 | **Tip:** There's a devMode function that you can run in init.js to make it easier for you to create programs in your browser. 94 | 95 | Remember that you can't access the servers callbacks. You'll have to create the design in the browser and then implement the backend. It's also important that you disable the CORS policy since it may block the programs loading in. 96 | 97 | -------------------------------------------------------------------------------- /client/client.js: -------------------------------------------------------------------------------- 1 | let wait = false; 2 | let esxEnabled = false; 3 | let ESX = false; 4 | let callbacks = {}; 5 | let helpTextShown = false; 6 | 7 | // Register client events 8 | RegisterNetEvent('jsfour-computer:toNUI'); 9 | RegisterNetEvent('jsfour-computer:callback'); 10 | 11 | // Register NUI callbacks 12 | RegisterNuiCallbackType('jsfour-computer:emitNet'); 13 | RegisterNuiCallbackType('jsfour-computer:esx'); 14 | RegisterNuiCallbackType('jsfour-computer:close'); 15 | RegisterNuiCallbackType('jsfour-computer:tempData'); 16 | 17 | // Answer from the server 18 | onNet('jsfour-computer:callback', ( result, id ) => { 19 | callbacks[id](result); 20 | delete callbacks[id]; 21 | }); 22 | 23 | // Server callback 24 | function serverCallback( name, data, cb ) { 25 | let id = Object.keys( callbacks ).length++; 26 | callbacks[id] = cb; 27 | data['CallbackID'] = id; 28 | emitNet(name, data); 29 | } 30 | 31 | /* 32 | Loop through every NUI callback name in the config and register them. 33 | I'm doing this since they're all doing the same thing and because I want the callback system to work properly 34 | */ 35 | for ( let i = 0; i < NUICallbacks.length; i++ ) { 36 | setTimeout(() => { 37 | let name = NUICallbacks[i]; 38 | 39 | RegisterNuiCallbackType(name); 40 | RegisterNetEvent(name); 41 | 42 | on(`__cfx_nui:${ name }`, ( data, cb ) => { 43 | data['clientEvent'] = name; 44 | 45 | serverCallback('jsfour-computer:query', data, ( callback ) => { 46 | cb(callback); 47 | }); 48 | }); 49 | }, i * 200 ); 50 | } 51 | 52 | // Triggered when a player sends data to another player 53 | onNet('jsfour-computer:toNUI', ( data ) => { 54 | SendNuiMessage(JSON.stringify({ 55 | action: 'toNUI', 56 | data: data, 57 | })); 58 | }); 59 | 60 | // Get the ESX status from the server 61 | setTimeout(() => { 62 | serverCallback('jsfour-computer:esxStatus', {}, ( status ) => { 63 | esxEnabled = status; 64 | 65 | SendNuiMessage(JSON.stringify({ 66 | action: 'esxStatus', 67 | status: esxEnabled 68 | })); 69 | }); 70 | }, 2000); 71 | 72 | // Check distance between the player and the locations 73 | function checkDistance( pos ) { 74 | let location = false; 75 | let pedCoords = GetEntityCoords(GetPlayerPed(-1)); 76 | 77 | if ( !pos ) { 78 | Object.keys( locations ).forEach( ( key ) => { 79 | let distance = GetDistanceBetweenCoords(pedCoords[0], pedCoords[1], pedCoords[2], locations[key].coords.x, locations[key].coords.y, locations[key].coords.z, true) 80 | 81 | if ( distance < locations[key].marker.drawDistance ) { 82 | location = { 83 | distance: distance, 84 | key: key, 85 | } 86 | } 87 | }); 88 | } else { 89 | let distance = GetDistanceBetweenCoords(pedCoords[0], pedCoords[1], pedCoords[2], locations[pos].coords.x, locations[pos].coords.y, locations[pos].coords.z, true) 90 | 91 | location = { 92 | distance: distance, 93 | key: pos 94 | } 95 | } 96 | 97 | return location; 98 | } 99 | 100 | // Remove NUI focus on start (incase of a resource restart) 101 | setImmediate(() => { 102 | SetNuiFocus(false, false); 103 | }); 104 | 105 | // A function to display the marker text in the left corner. If you have your own notification system this is where you could add it 106 | function ShowHelp() { 107 | SetTextComponentFormat('STRING') 108 | AddTextComponentString(markerHelpText) 109 | DisplayHelpTextFromStringLabel(0, 0, 1, -1) 110 | } 111 | 112 | // Keypress event and display marker if enabled in the config. Also loads in ESX if it's installed 113 | setTick(() => { 114 | if ( esxEnabled ) { 115 | while ( !ESX ) { 116 | emit('esx:getSharedObject', ( obj ) => { 117 | ESX = obj; 118 | }); 119 | } 120 | } 121 | 122 | if ( displayMarkers ) { 123 | if ( !wait ) { 124 | if ( checkDistance() ) { 125 | let location = locations[checkDistance().key]; 126 | 127 | if ( markerHelpText && !helpTextShown ) { 128 | ShowHelp(); 129 | helpTextShown = true; 130 | } 131 | 132 | DrawMarker(location.marker.type, location.coords.x, location.coords.y, location.coords.z, 0.0, 0.0, 0.0, 0, 0.0, 0.0, location.marker.size.x, location.marker.size.y, location.marker.size.z, location.marker.color.r, location.marker.color.g, location.marker.color.b, 100, location.marker.animate, true, 2, false, false, false, false); 133 | } else { 134 | wait = true; 135 | helpTextShown = false; 136 | 137 | setTimeout(() => { 138 | wait = false; 139 | }, 1000); 140 | } 141 | } 142 | } 143 | 144 | if ( IsControlJustReleased(0, key) ) { 145 | if ( checkDistance() ) { 146 | SetNuiFocus(true, true); 147 | 148 | let key = checkDistance().key; 149 | let location = locations[key]; 150 | 151 | SendNuiMessage(JSON.stringify({ 152 | action: 'open', 153 | device: 'computer', 154 | location: key, 155 | loginLogo: location.loginLogo, 156 | loginBackground: location.loginBackground, 157 | excludePrograms: location.excludePrograms, 158 | desktopBackground: location.desktopBackground, 159 | overrideBackground: location.overrideBackground, 160 | job: location.job, 161 | login: location.login, 162 | run: location.run 163 | })); 164 | } 165 | } 166 | }); 167 | 168 | // A command that opens the computer if the player is near a location, if enabled in the config 169 | if ( commands.computer.enable ) { 170 | RegisterCommand(commands.computer.name, (source, args) => { 171 | if ( checkDistance() || commands.computer.disableDistance ) { 172 | if ( args[0] ) { 173 | SetNuiFocus(true, true); 174 | 175 | let key = args[0]; 176 | let location = locations[key]; 177 | 178 | SendNuiMessage(JSON.stringify({ 179 | action: 'open', 180 | device: 'computer', 181 | location: key, 182 | loginLogo: location.loginLogo, 183 | loginBackground: location.loginBackground, 184 | excludePrograms: location.excludePrograms, 185 | desktopBackground: location.desktopBackground, 186 | overrideBackground: location.overrideBackground, 187 | job: location.job, 188 | login: location.login, 189 | run: location.run 190 | })); 191 | } else { 192 | console.error(`Command missing arguments, usage: /${ commands.computer.name } location`); 193 | } 194 | } 195 | }); 196 | } 197 | 198 | // Run a query < called from NUI 199 | on('__cfx_nui:jsfour-computer:query', ( data, cb ) => { 200 | serverCallback('jsfour-computer:query', data, ( callback ) => { 201 | cb(callback); 202 | }); 203 | }); 204 | 205 | // emitNet < called from NUI 206 | on('__cfx_nui:jsfour-computer:emitNet', ( data ) => { 207 | emitNet('jsfour-computer:emitNet', data); 208 | cb(true); 209 | }); 210 | 211 | // Get temporaryly saved data on the server < called from NUI 212 | on('__cfx_nui:jsfour-computer:tempData', ( data, cb ) => { 213 | serverCallback('jsfour-computer:tempData', data, ( callback ) => { 214 | cb(callback); 215 | }); 216 | }); 217 | 218 | // Remove NUI focus < called from NUI 219 | on('__cfx_nui:jsfour-computer:close', ( data, cb ) => { 220 | SetNuiFocus(false, false); 221 | cb(true); 222 | 223 | // Save icon slots if they have been changed 224 | if ( data ) { 225 | emitNet('jsfour-computer:query', data); 226 | } 227 | }); 228 | 229 | // ESX functions required by some ESX programs, will only work if ESX has been installed 230 | on('__cfx_nui:jsfour-computer:esx', ( data, cb ) => { 231 | switch ( data.function ) { 232 | case 'society': 233 | switch ( data.event ) { 234 | case 'getMoney': 235 | ESX.TriggerServerCallback('esx_society:getSocietyMoney', ( money ) => { 236 | cb( money ); 237 | }, data.job); 238 | break; 239 | case 'withdraw': 240 | emitNet('esx_society:withdrawMoney', data.job, data.amount); 241 | cb(true); 242 | break; 243 | case 'deposit': 244 | emitNet('esx_society:depositMoney', data.job, data.amount); 245 | cb(true); 246 | break; 247 | case 'getEmployees': 248 | ESX.TriggerServerCallback('esx_society:getEmployees', ( employees ) => { 249 | cb( employees ); 250 | }, data.job); 251 | break; 252 | case 'getJob': 253 | ESX.TriggerServerCallback('esx_society:getJob', ( job ) => { 254 | cb( job.grades ); 255 | }, data.job); 256 | break; 257 | case 'setSalary': 258 | ESX.TriggerServerCallback('esx_society:setJobSalary', function() { 259 | cb(true); 260 | }, data.job, data.grade, data.amount); 261 | break; 262 | case 'fire': 263 | ESX.TriggerServerCallback('esx_society:setJob', function() { 264 | cb(true); 265 | }, data.identifier, 'unemployed', 0, 'fire'); 266 | break; 267 | case 'changeGrade': 268 | ESX.TriggerServerCallback('esx_society:setJob', function() { 269 | cb(true); 270 | }, data.identifier, data.job, data.grade, 'promote'); 271 | break; 272 | } 273 | break; 274 | } 275 | }); 276 | -------------------------------------------------------------------------------- /client/config.js: -------------------------------------------------------------------------------- 1 | // Button to open the computer, controls can be found at the FiveM docs. 2 | const key = 38; 3 | 4 | // Display the markers? 5 | const displayMarkers = true; 6 | 7 | // The text to display for each marker, can be set to false to disable it. (This won't be displayed if the displayMarkers variable is set to false) 8 | const markerHelpText = 'Press ~g~~h~E~h~~s~ to use the computer'; 9 | 10 | // Locations of the computers, more locations can be added. 11 | // To add more backgrounds simply place your image in the html/asset/images folder. 12 | // You don't have to add it to the __resource.lua, it reads all .gif, .jpg and .png files. 13 | const locations = { 14 | 'hospital': { 15 | coords: { x: 308.0204162597656, y: -595.9227294921875, z: 43.496363830566406 }, // Coords of the marker 16 | marker: { 17 | drawDistance: 2, // Player distance before the marker is visible 18 | type: 0, // Marker type 19 | size: { x: 0.3, y: 0.3, z: 0.2 }, // Marker size 20 | color: { r: 26, g: 55, b: 186 }, // Marker color 21 | animate: false, // Makes the marker move up and down 22 | }, 23 | loginLogo: 'assets/images/logo_hospital.png', // Computer login logo image path 24 | loginBackground: 'assets/images/login_hospital.jpg', // Computer login background image path 25 | desktopBackground: 'assets/images/windows.png', // Computer desktop background image path 26 | excludePrograms: [ 'jobcenter', 'cardealer', 'folder', 'twitter' ], // Array of program names to exclude on the location 27 | overrideBackground: true, // Overrides the user background with the one specified above 28 | job: 'ambulance', // The user needs to have the specified job to be able to login to the computer 29 | login: true, // Required to login? (Useful if you just want to display something in a store etc.. without asking the user to login) 30 | run: false // You can specify a program to run on start, see the cardealer marker down below 31 | }, 32 | 'policestation': { 33 | coords: { x: 442.0035607910156, y: -979.3918676757812, z: 30.689603805541992 }, 34 | marker: { 35 | drawDistance: 1.5, 36 | type: 0, 37 | size: { x: 0.3, y: 0.3, z: 0.2 }, 38 | color: { r: 28, g: 252, b: 3 }, 39 | animate: false, 40 | }, 41 | loginLogo: 'assets/images/logo_police.png', 42 | loginBackground: 'assets/images/login_police.jpg', 43 | desktopBackground: 'assets/images/police.jpg', 44 | excludePrograms: [ 'jobcenter', 'cardealer', 'folder', 'twitter' ], 45 | overrideBackground: true, 46 | job: 'police', 47 | login: true, 48 | run: false 49 | }, 50 | 'cardealer': { 51 | coords: { x: -56.209499359131, y: -1096.6896972656, z: 25.422355651855 }, 52 | marker: { 53 | drawDistance: 5, 54 | type: 27, 55 | size: { x: 2.0, y: 2.0, z: 1.0 }, 56 | color: { r: 26, g: 55, b: 186 }, 57 | animate: false 58 | }, 59 | desktopBackground: 'assets/images/login_cardealer.jpg', 60 | login: false, 61 | run: 'cardealer' 62 | }, 63 | } 64 | 65 | // A command that lets a player open the computer or tablet, disabled by default. 66 | // # disableDistance: 67 | // # if set to true the player can open the computer everywhere. If set to false the player needs to be standing next to one of the positions above ^ 68 | const commands = { 69 | 'computer': { 70 | enable: true, // Command enabled? 71 | disableDistance: true, 72 | name: 'computer' // Name of the command /computer [location] 73 | } 74 | } 75 | 76 | const NUICallbacks = [ 77 | 'jsfour-computer:login', 78 | 'jsfour-computer:medicalrecordsFetchAll', 79 | 'jsfour-computer:medicalrecordsFetchUser', 80 | 'jsfour-computer:medicalrecordsSearch', 81 | 'jsfour-computer:medicalrecordsDelete', 82 | 'jsfour-computer:medicalrecordsAdd', 83 | 'jsfour-computer:fetchMail', 84 | 'jsfour-computer:fetchUserEmails', 85 | 'jsfour-computer:sendMail', 86 | 'jsfour-computer:updateMailRead', 87 | 'jsfour-computer:updateMailFolder', 88 | 'jsfour-computer:deleteMail', 89 | 'jsfour-computer:fetchEmail', 90 | 'jsfour-computer:registerMail', 91 | 'jsfour-computer:fetchAllJobAds', 92 | 'jsfour-computer:addJobAd', 93 | 'jsfour-computer:deleteJobAd', 94 | 'jsfour-computer:updateJobAd', 95 | 'jsfour-computer:fetchAllUsers', 96 | 'jsfour-computer:fetchUsersByJob', 97 | 'jsfour-computer:updateUser', 98 | 'jsfour-computer:addUser', 99 | 'jsfour-computer:updateForumAvatar', 100 | 'jsfour-computer:fetchID', 101 | 'jsfour-computer:updateEmail', 102 | 'jsfour-computer:deleteUser', 103 | 'jsfour-computer:deleteEmail', 104 | 'jsfour-computer:fetchForumPosts', 105 | 'jsfour-computer:addForumPost', 106 | 'jsfour-computer:deleteForumPost', 107 | 'jsfour-computer:getSocieties', 108 | 'jsfour-computer:updateForumAvatar', 109 | ]; -------------------------------------------------------------------------------- /client/html/assets/fonts/handwritten/Handwritten.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/handwritten/Handwritten.woff -------------------------------------------------------------------------------- /client/html/assets/fonts/justsignature/JustSignature.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/justsignature/JustSignature.woff -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Bold.woff -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Light.woff -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Light.woff2 -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Medium.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Medium.woff -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Regular.woff -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Thin.woff -------------------------------------------------------------------------------- /client/html/assets/fonts/roboto/Roboto-Thin.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/fonts/roboto/Roboto-Thin.woff2 -------------------------------------------------------------------------------- /client/html/assets/images/blurr-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/blurr-blue.png -------------------------------------------------------------------------------- /client/html/assets/images/blurr-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/blurr-dark.png -------------------------------------------------------------------------------- /client/html/assets/images/blurr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/blurr.png -------------------------------------------------------------------------------- /client/html/assets/images/computer_frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/computer_frame.png -------------------------------------------------------------------------------- /client/html/assets/images/icons-system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/icons-system.png -------------------------------------------------------------------------------- /client/html/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/icons.png -------------------------------------------------------------------------------- /client/html/assets/images/login_cardealer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/login_cardealer.jpg -------------------------------------------------------------------------------- /client/html/assets/images/login_hospital.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/login_hospital.jpg -------------------------------------------------------------------------------- /client/html/assets/images/login_police.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/login_police.jpg -------------------------------------------------------------------------------- /client/html/assets/images/logo_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/logo_default.png -------------------------------------------------------------------------------- /client/html/assets/images/logo_hospital.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/logo_hospital.png -------------------------------------------------------------------------------- /client/html/assets/images/logo_police.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/logo_police.png -------------------------------------------------------------------------------- /client/html/assets/images/police.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/police.jpg -------------------------------------------------------------------------------- /client/html/assets/images/windows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/images/windows.png -------------------------------------------------------------------------------- /client/html/assets/js/clicks.js: -------------------------------------------------------------------------------- 1 | let program; 2 | 3 | // Hides the windows-start and the volume-control 4 | function hideWindow( window ) { 5 | let windows = window.replace(/\n/g, '').replace(/\s/g, '').split(','); 6 | 7 | for ( i in windows ) { 8 | if ( windows[i] === 'windows-start' || windows[i] === 'volume-control' || windows[i] === 'calendar' || windows[i] === 'network-window' || windows[i] === 'wifi-window' ) { 9 | $( `#${windows[i]}` ).animate({ 10 | height: '0', 11 | }, 200, () => { 12 | $( `#${windows[i]}` ).hide(); 13 | }); 14 | } else if ( windows[i] === 'notifications' ) { 15 | $('#notifications').animate({ 16 | width: '0', 17 | }, 100, () => { 18 | $('#notifications').hide(); 19 | }); 20 | } else { 21 | $( '#windows-start' ).animate({ 22 | height: '0', 23 | }, 200, () => { 24 | $( '#windows-start' ).hide(); 25 | }); 26 | 27 | $( '#network-window' ).animate({ 28 | height: '0', 29 | }, 200, () => { 30 | $( '#network-window' ).hide(); 31 | }); 32 | 33 | $( '#wifi-window' ).animate({ 34 | height: '0', 35 | }, 200, () => { 36 | $( '#wifi-window' ).hide(); 37 | }); 38 | 39 | $( '#volume-control' ).animate({ 40 | height: '0', 41 | }, 200, () => { 42 | $( '#volume-control' ).hide(); 43 | }); 44 | 45 | $( '#calendar' ).animate({ 46 | height: '0', 47 | }, 200, () => { 48 | $( '#calendar' ).hide(); 49 | }); 50 | 51 | $('#notifications').animate({ 52 | width: '0', 53 | }, 100, () => { 54 | $('#notifications').hide(); 55 | }); 56 | } 57 | } 58 | } 59 | 60 | // Desktop click 61 | $('#desktop').click(() => { 62 | hideWindow( 'all' ); 63 | $(`.small-active`).removeClass('small-active'); 64 | }); 65 | 66 | // Program window clicked 67 | $('body').on('click', '.program-wrapper', function () { 68 | $('.program-wrapper').removeClass('program-active'); 69 | $(this).addClass('program-active'); 70 | $(`.small-active`).removeClass('small-active'); 71 | $(`.icon-${$(this).attr('program')}-small`).addClass('small-active small-program-icon'); 72 | }); 73 | 74 | // Change the volume 75 | $('body').on('input', '#volume-range', function() { 76 | volume = $(this).val(); 77 | $('#volume-percentage').text(volume); 78 | 79 | Howler.volume(volume / 100); 80 | }); 81 | 82 | // Start a program 83 | function startProgram( program ) { 84 | hideWindow( 'all' ); 85 | 86 | if ( !$(`.icon-${program}-small`).hasClass('small-active') ) { 87 | $(`.program-${program}`).closest('.program-wrapper').show(); 88 | 89 | $('.program-wrapper').removeClass('program-active'); 90 | $(`.program-${program}`).closest('.program-wrapper').addClass('program-active'); 91 | 92 | $(`.small-active`).removeClass('small-active'); 93 | 94 | if ( $(`.icon-${program}-small`).length === 0 ) { 95 | $('#taskbar-icons').append(`
`); 96 | $(`.icon-${program}-small`).addClass('small-active small-border'); 97 | } else { 98 | $(`.icon-${program}-small`).addClass('small-active small-border'); 99 | } 100 | } 101 | } 102 | 103 | function cInterval() { 104 | $('#calendar-time').text( getTime( true ) ); 105 | } 106 | 107 | // .click, requires the attr "action" 108 | $('body').on('click', '.click', function () { 109 | switch ( $(this).attr('action') ) { 110 | case 'settings': 111 | startProgram('settings'); 112 | break; 113 | case 'wifi-window': 114 | hideWindow( 'volume-control, notifications, calendar' ); 115 | 116 | $('#wifi-window').show().animate({ 117 | height: $('#wifi-window').height() ? 0 : 250 118 | }, 200); 119 | break; 120 | case 'network-window': 121 | hideWindow( 'volume-control, notifications, calendar' ); 122 | 123 | $('#network-window').show().animate({ 124 | height: $('#network-window').height() ? 0 : 115 125 | }, 200); 126 | break; 127 | case 'calendar': 128 | // Show calendar 129 | hideWindow( 'volume-control, notifications, network-window' ); 130 | 131 | calendarOpen = calendarOpen ? false : true; 132 | 133 | if ( calendarOpen ) { 134 | calendarInterval = setInterval(cInterval, 1000); 135 | } else { 136 | clearInterval(calendarInterval); 137 | } 138 | 139 | $('#calendar').show().animate({ 140 | height: $('#calendar').height() ? 0 : 350 141 | }, 200); 142 | break; 143 | case 'volume': 144 | // Show volume control 145 | hideWindow( 'calendar, notifications, network-window' ); 146 | 147 | $('#volume-control').show().animate({ 148 | height: $('#volume-control').height() ? 0 : 45 149 | }, 200); 150 | break; 151 | case 'volume-mute': 152 | // Mute the volume 153 | let volumeIcon = $(this).text() === 'volume_up' ? 'volume_off' : 'volume_up'; 154 | $(this).text( volumeIcon ); 155 | $('#volume-icon').text( volumeIcon ); 156 | 157 | volume = 0; 158 | Howler.volume(volume); 159 | break; 160 | case 'notifications': 161 | // Show notificaitons 162 | hideWindow( 'volume-control, calendar, network-window' ); 163 | 164 | $('#notification').animate({ 165 | width: 0 166 | }, 200); 167 | 168 | $(this).css({ backgroundPosition: '0px 0px' }); 169 | 170 | $('#notifications').show().animate({ 171 | width: $('#notifications').width() ? 0 : 220 172 | }, 200); 173 | break; 174 | case 'notification': 175 | // Remove notification 176 | if ( $( this ).attr('subprogram') ) { 177 | startProgram( $( this ).attr('subprogram') ); 178 | } 179 | $( this ).remove(); 180 | break; 181 | case 'notification-close': 182 | $('#notification').animate({ 183 | width: 0 184 | }, 200); 185 | break; 186 | case 'windows-start': 187 | // Show windows start menu 188 | $('#windows-start').show().animate({ 189 | height: $('#windows-start').height() ? 0 : 230 190 | }, 200); 191 | break; 192 | case 'windows-minimize-all': 193 | // Taskbar minimize, hides all programs 194 | hideWindow( 'all' ); 195 | $(`.small-active`).removeClass('small-active'); 196 | 197 | for (let i = 0; i < $('#desktop .program-wrapper').length; i++) { 198 | prog = $('#desktop .program-wrapper').eq(i).attr('program'); 199 | $(`#desktop .program-${prog}`).closest('.program-wrapper').hide(); 200 | } 201 | break; 202 | case 'start-program': 203 | // Start a program 204 | startProgram( $( this ).attr('program') ); 205 | 206 | if ( $( this ).attr('subprogram') ) { 207 | $('#notification').animate({ 208 | width: 0 209 | }, 200); 210 | } 211 | break; 212 | case 'program-close': 213 | // Close a program 214 | program = $(this).attr('program'); 215 | 216 | let e = $(`#desktop .program-${program}`).closest('.program-wrapper'); 217 | 218 | if ( programs[program].icons ) { 219 | if ( !programs[program].icons.taskbar ) { 220 | $(`.icon-${program}-small`).closest('.click').remove(); 221 | } 222 | } else { 223 | $(`.icon-${program}-small`).closest('.click').remove(); 224 | } 225 | 226 | setTimeout(() => { 227 | $(`.small-active`).removeClass('small-active small-border'); 228 | }, 1); 229 | 230 | 231 | e.hide(); 232 | break; 233 | case 'program-minimize': 234 | // Minimize a program 235 | $(`#desktop .program-${$(this).attr('program')}`).closest('.program-wrapper').hide(); 236 | break; 237 | case 'program-fullscreen': 238 | // Toggle fullscreen of a program 239 | let elem = $(`#desktop .program-${$(this).attr('program')}`).closest('.program-wrapper'); 240 | 241 | if ( elem.find('.container').width() >= 700 ) { 242 | elem.find('.container').css('width', '85%'); 243 | } else { 244 | elem.find('.container').css('width', '70%'); 245 | } 246 | 247 | elem.css({ 248 | 'top': 0, 249 | 'left': 0, 250 | 'width': elem.width() === 1012 ? '810px' : '100%', 251 | 'height': elem.height() === 518 ? '410px' : '94%' 252 | }); 253 | break; 254 | case 'program-refresh': 255 | // Refresh a program, calls the program refresh function refreshprogram() where program is the program name 256 | window[`refresh${$(this).attr('program')}`](); 257 | break; 258 | case 'signout': 259 | // Sign out the user 260 | signout(); 261 | break; 262 | case 'off': 263 | // Trun off computer 264 | off(); 265 | break; 266 | case 'computer-register': 267 | $('#computer-login-form').fadeToggle('fast', () => { 268 | $('#computer-register-form').fadeToggle(); 269 | }); 270 | break; 271 | case 'computer-loading-back': 272 | $('#computer-register-form').fadeOut('fast', () => { 273 | $('#computer-login-form').fadeIn(); 274 | }); 275 | break; 276 | case 'tablet-program': 277 | $(`.program-tablet-${ $(this).attr('program') }`).show(); 278 | break; 279 | } 280 | }); -------------------------------------------------------------------------------- /client/html/assets/sounds/ding.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/ding.ogg -------------------------------------------------------------------------------- /client/html/assets/sounds/error.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/error.ogg -------------------------------------------------------------------------------- /client/html/assets/sounds/notify.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/notify.ogg -------------------------------------------------------------------------------- /client/html/assets/sounds/signin.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/signin.ogg -------------------------------------------------------------------------------- /client/html/assets/sounds/signout.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/signout.ogg -------------------------------------------------------------------------------- /client/html/assets/sounds/turnoff.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/turnoff.ogg -------------------------------------------------------------------------------- /client/html/assets/sounds/turnon.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/turnon.ogg -------------------------------------------------------------------------------- /client/html/assets/sounds/untitled.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/assets/sounds/untitled.ogg -------------------------------------------------------------------------------- /client/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |

18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Logo 36 |
37 | person_add 38 | 39 | lock 40 | 41 | 42 |
43 |
44 |
45 |
46 | 47 | 48 | 49 | 50 | 51 |
52 | 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | 65 | close 66 |

67 |
68 |
69 |
70 |

Notifications

71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |

83 | keyboard_arrow_up 84 | keyboard_arrow_down 85 |
86 |
    87 |

    88 |
89 |
90 |
91 |
92 |

Are you sure?

93 |

yes

94 |
95 |
96 | 114 |
115 |
116 | volume_up 117 |

118 | 119 |

120 |

50

121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |

Ethernet 2

130 |

Connected

131 |
132 |
133 |
134 | Network & Internet settings 135 | Change settings, such as making a connection metered. 136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |

TG16702-5G

145 |

Connected

146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |

TG16702-5G

154 |

Connected

155 |
156 |
157 |
158 |
159 | exit_to_app 160 | 161 |
162 | volume_up 163 |
164 |

165 |

166 |
167 |
168 |
169 |
170 |

Append to taskbar

171 |
172 |
173 |
174 |
175 |
176 |
177 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /client/html/programs/account/account.css: -------------------------------------------------------------------------------- 1 | .program-account-header { 2 | background: rgb(26, 21, 73); 3 | color: #ffffff; 4 | } 5 | 6 | .program-account { 7 | height: 100%; 8 | width: 100%; 9 | color: #ffffff; 10 | background: rgb(46, 41, 105); 11 | } 12 | 13 | .icon-account { 14 | background-position: -120px 0; 15 | } 16 | 17 | .icon-account:hover { 18 | background-position: -120px -60px; 19 | } 20 | 21 | .icon-account:active { 22 | background-position: -120px -120px; 23 | } 24 | 25 | .icon-account-small { 26 | background-position: -132px -193px; 27 | } 28 | 29 | .program-account h6 { 30 | margin-bottom: 30px; 31 | } 32 | 33 | .program-account .input-field input { 34 | color: #ffffff; 35 | border-bottom: 1px solid #ffffff; 36 | } 37 | 38 | .program-account .input-field label { 39 | color: #ffffff; 40 | } 41 | 42 | .program-account .input-field input[type=text]:focus + label, 43 | .program-account .input-field input[type=password]:focus + label, 44 | .program-account textarea:focus + label { 45 | color: #ffffff !important; 46 | } 47 | 48 | .program-account input[type=text]:disabled + label { 49 | color: #ffffff !important; 50 | } 51 | 52 | .program-account input[type=text]:disabled { 53 | color: #ffffff !important; 54 | border-bottom: 1px solid #9c9c9c !important; 55 | } 56 | 57 | .program-account .input-field input[type=text]:focus, 58 | .program-account .input-field input[type=password]:focus { 59 | border-bottom: 1px solid #ffffff !important; 60 | box-shadow: 0 1px 0 0 #ffffff !important; 61 | } 62 | 63 | .program-account .input-field input[type=text].invalid, 64 | .program-account .input-field input[type=password].invalid { 65 | border-bottom: 1px solid red; 66 | box-shadow: 0 1px 0 0 red; 67 | } 68 | 69 | .program-account .input-field input[type=text].valid, 70 | .program-account .input-field input[type=password].valid { 71 | border-bottom: 1px solid green; 72 | box-shadow: 0 1px 0 0 green; 73 | } 74 | 75 | .program-account button { 76 | background: #ffffff; 77 | color: #000000; 78 | margin-bottom: 40px; 79 | } 80 | 81 | .program-account button:hover { 82 | background: #ffffff; 83 | } 84 | 85 | .program-account button:focus { 86 | background: #ffffff; 87 | } 88 | 89 | .program-account .input-field .helper-text { 90 | position: absolute; 91 | width: 100%; 92 | } -------------------------------------------------------------------------------- /client/html/programs/account/account.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
Update your account
6 |
7 |
8 |
9 | 10 | 11 | 12 |
13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 | 23 | 24 |
25 |
26 | 27 | 28 |
29 |
30 | 31 | 32 |
33 |
34 | 35 | 36 |
37 |
38 | 39 | 40 |
41 |
42 |
43 |
44 | 45 | 46 | 47 |
48 |
49 | 50 | 51 |
52 |
53 | 54 |
55 |
56 |
57 |
58 |
59 | 60 | -------------------------------------------------------------------------------- /client/html/programs/account/account.js: -------------------------------------------------------------------------------- 1 | Object.keys(loggedInUser).forEach( ( k ) => { 2 | if ( k != 'password' ) { 3 | $(`#account-${k}`).val(loggedInUser[k]); 4 | } 5 | }); 6 | 7 | $('#account-username').attr('identifier', loggedInUser.id); 8 | 9 | if ( loggedInUser.group === 'admin' ) { 10 | $('#account-job').attr('disabled', false); 11 | $('#account-group').attr('disabled', false); 12 | } 13 | 14 | M.updateTextFields(); 15 | 16 | $('#account-form').submit( () => { 17 | $('.helper-text').attr('data-error', ''); 18 | $('.invalid').removeClass('invalid'); 19 | $('.valid').removeClass('valid'); 20 | 21 | let inputs = $('#account-form').find('input'); 22 | let rows = {}; 23 | let same = 0; 24 | let update = true; 25 | 26 | for ( let i = 0; i < inputs.length; i++ ) { 27 | if ( inputs.eq(i).val() ) { 28 | if ( $('#account-new-password0').val() || $('#account-new-password1').val() ) { 29 | if ( $('#account-new-password0').val() === $('#account-new-password1').val() ) { 30 | rows[`@${inputs.eq(i).attr('id').split('-')[1]}`] = inputs.eq(i).val().toLowerCase(); 31 | } else { 32 | $('#account-new-password0').addClass('invalid'); 33 | $('#account-new-password1').addClass('invalid'); 34 | 35 | $('#account-new-password-helper').attr('data-error', `The passwords doesn't match`); 36 | } 37 | } else { 38 | rows[`@new`] = inputs.eq(1).val(); 39 | rows[`@${inputs.eq(i).attr('id').split('-')[1]}`] = inputs.eq(i).val().toLowerCase(); 40 | } 41 | } 42 | } 43 | 44 | Object.keys(rows).forEach( ( k ) => { 45 | let row = k.substr(1); 46 | 47 | if ( row != 'new' ) { 48 | if ( loggedInUser[row] === rows[k] ) { 49 | same++; 50 | } 51 | } 52 | }); 53 | 54 | if ( same === inputs.length ) { 55 | if ( !$('#account-new-password0').val() || !$('#account-new-password1').val() ) { 56 | update = false; 57 | 58 | $('.program-account input').addClass('invalid'); 59 | $('#account-username-helper').attr('data-error', `You haven't updated any fields..`); 60 | } 61 | } else { 62 | if ( $('#account-new-password0').val() ) { 63 | loggedInUser['password'] = $('#account-new-password0').val().toLowerCase(); 64 | } 65 | 66 | $('#computer-content').css('background', `url(${ $('#account-desktop').val() }) no-repeat`); 67 | $('#computer-content').css('background-size', `cover`); 68 | 69 | Object.keys(rows).forEach( ( k ) => { 70 | let row = k.substr(1); 71 | 72 | if ( row != 'new' && row != 'password' ) { 73 | loggedInUser[row] = rows[k]; 74 | } 75 | }); 76 | } 77 | 78 | if ( update ) { 79 | rows['@id'] = $('#account-username').attr('identifier'); 80 | 81 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:updateUser`, { 82 | method: 'POST', 83 | body: JSON.stringify({ 84 | type: 'updateUser', 85 | data: rows 86 | }) 87 | }) 88 | .then( response => response.text() ) 89 | .then( text => { 90 | if ( text != 'false' ) { 91 | $('#account-form input').addClass('valid'); 92 | 93 | if ( $('#account-avatar').val() != loggedInUser.avatar ) { 94 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:updateForumAvatar`, { 95 | method: 'POST', 96 | body: JSON.stringify({ 97 | type: 'updateForumAvatar', 98 | data: { 99 | '@avatar': $('#account-avatar').val(), 100 | '@username': $('#account-username').val() 101 | } 102 | }) 103 | }); 104 | } 105 | } else { 106 | inputs.eq(1).addClass('invalid'); 107 | $('#account-username-helper').attr('data-error', `Wrong password`); 108 | } 109 | }); 110 | } 111 | 112 | return false; 113 | }); 114 | 115 | $('.nospace').keydown(( e ) => { if ( e.which === 32) return false; }); -------------------------------------------------------------------------------- /client/html/programs/bossactions/bossactions.css: -------------------------------------------------------------------------------- 1 | .program-bossactions-header { 2 | background: #4039a0; 3 | color: #ffffff; 4 | } 5 | 6 | .program-bossactions { 7 | height: 100%; 8 | width: 100%; 9 | color: #000000; 10 | background: #fdfdff; 11 | } 12 | 13 | .icon-bossactions { 14 | background-position: -420px 0; 15 | } 16 | 17 | .icon-bossactions:hover { 18 | background-position: -420px -60px; 19 | } 20 | 21 | .icon-bossactions:active { 22 | background-position: -420px -120px; 23 | } 24 | 25 | .icon-bossactions-small { 26 | background-position: -432px -193px; 27 | } 28 | 29 | .bossactions-menu-square { 30 | margin: 20px 0 20px 0; 31 | position: relative; 32 | height: 100px; 33 | color: #ffffff; 34 | text-align: center; 35 | background: linear-gradient(45deg, #303f9f, #7b1fa2) !important; 36 | text-transform: uppercase; 37 | font-size: 16px; 38 | line-height: 10px; 39 | } 40 | 41 | .bossactions-menu-square:hover { 42 | background: linear-gradient(45deg, #7b1fa2, #303f9f) !important; 43 | } 44 | 45 | .bossactions-menu-square:active { 46 | background: linear-gradient(45deg, #681a8a, #273488) !important; 47 | } 48 | 49 | .bossactions-menu-square:nth-child(even) { 50 | background: #011cb3; 51 | } 52 | 53 | .bossactions-menu-square p:nth-child(odd){ 54 | font-weight: bold; 55 | font-size: 20px; 56 | padding-top: 40px; 57 | 58 | } 59 | 60 | .bossactions-menu-square p:nth-child(even){ 61 | padding-top: 10px; 62 | font-family: 'Muli', sans-serif; 63 | } 64 | 65 | #bossactions-employees td p { 66 | text-transform: uppercase; 67 | font-size: 14px; 68 | display: inline-block; 69 | color: #ffffff; 70 | padding: 4px 8px 4px 8px; 71 | } 72 | 73 | .ba-promote { 74 | background: #3ca832; 75 | } 76 | 77 | .ba-demote { 78 | background: #a87132; 79 | } 80 | 81 | .ba-fire { 82 | background: #cf2626; 83 | } 84 | 85 | #bossactions-page-salary, 86 | #bossactions-page-bank { 87 | display: none; 88 | } 89 | 90 | #bossactions-salary input { 91 | margin-top: 10px; 92 | padding-left: 10px !important; 93 | height: 30px !important; 94 | width: 108px !important; 95 | border: 1px solid black !important; 96 | box-sizing: border-box; 97 | } 98 | 99 | #bossactions-salary input:focus { 100 | box-shadow: none !important; 101 | } 102 | 103 | #bossactions-salary button { 104 | float: right; 105 | } -------------------------------------------------------------------------------- /client/html/programs/bossactions/bossactions.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 |

Employees

8 |

9 |
10 |
11 |
12 |
13 |

change

14 |

Salary

15 |
16 |
17 |
18 |
19 |

Bank

20 |

21 |
22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 |
NameGrade
34 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
GradeSalary
45 |
46 |
47 |
48 | 49 | 50 | 51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | 59 | 60 | -------------------------------------------------------------------------------- /client/html/programs/bossactions/bossactions.js: -------------------------------------------------------------------------------- 1 | let _baPage = '#bossactions-page-employees'; 2 | let grades = 0; 3 | 4 | function getEmployees() { 5 | $('#bossactions-employees tbody').html(''); 6 | 7 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:esx`, { 8 | method: 'POST', 9 | body: JSON.stringify({ 10 | 'function': 'society', 11 | 'event': 'getEmployees', 12 | 'job': loggedInUser.job 13 | }) 14 | }) 15 | .then( response => response.json() ) 16 | .then( data => { 17 | $('#employees-count').text( Object.keys( data ).length ); 18 | 19 | Object.keys( data ).forEach(( k ) => { 20 | let promote = parseInt(data[k].job.grade) + 1; 21 | let demote = parseInt(data[k].job.grade) - 1; 22 | let div = ` 23 | ${ data[k].name } 24 | ${ data[k].job.grade_label } 25 | 26 |

Promote

27 |

Demote

28 |

Fire

29 | 30 | `; 31 | 32 | $('#bossactions-employees tbody').append( div ); 33 | }); 34 | }); 35 | } 36 | 37 | function getSalary() { 38 | $('#bossactions-salary tbody').html(''); 39 | 40 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:esx`, { 41 | method: 'POST', 42 | body: JSON.stringify({ 43 | 'function': 'society', 44 | 'event': 'getJob', 45 | 'job': loggedInUser.job 46 | }) 47 | }) 48 | .then( response => response.json() ) 49 | .then( data => { 50 | grades = Object.keys( data ).length; 51 | 52 | Object.keys( data ).forEach(( k ) => { 53 | let div = ` 54 | ${ data[k].label } 55 | 56 | 57 | `; 58 | 59 | $('#bossactions-salary tbody').append( div ); 60 | }); 61 | }); 62 | } 63 | 64 | function getMoney() { 65 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:esx`, { 66 | method: 'POST', 67 | body: JSON.stringify({ 68 | 'function': 'society', 69 | 'event': 'getMoney', 70 | 'job': loggedInUser.job 71 | }) 72 | }) 73 | .then( response => response.text() ) 74 | .then( data => { 75 | $('#ba-money').text( data ); 76 | }); 77 | } 78 | 79 | function refreshbossactions() { 80 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:getSocieties`, { 81 | method: 'POST', 82 | body: JSON.stringify({ 83 | type: 'getSocieties' 84 | }) 85 | }) 86 | .then( response => response.json() ) 87 | .then( data => { 88 | if ( data.length > 0 ) { 89 | Object.keys( data ).forEach(( k ) => { 90 | if ( data[k].name === `society_${ loggedInUser.job }` ) { 91 | getEmployees(); 92 | getSalary(); 93 | getMoney(); 94 | } 95 | }); 96 | } 97 | }); 98 | } 99 | 100 | function baUpdate( grade ) { 101 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:esx`, { 102 | method: 'POST', 103 | body: JSON.stringify({ 104 | 'function': 'society', 105 | 'event': 'setSalary', 106 | 'job': loggedInUser.job, 107 | 'grade': grade, 108 | 'amount': $('body').find( `.ba-amount-${ grade }` ).val() 109 | }) 110 | }); 111 | } 112 | 113 | function baFire( identifier ) { 114 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:esx`, { 115 | method: 'POST', 116 | body: JSON.stringify({ 117 | 'function': 'society', 118 | 'event': 'fire', 119 | 'identifier': identifier 120 | }) 121 | }); 122 | } 123 | 124 | function baChangeGrade( identifier, grade ) { 125 | if ( grade < grades && grade > 0 ) { 126 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:esx`, { 127 | method: 'POST', 128 | body: JSON.stringify({ 129 | 'function': 'society', 130 | 'event': 'changeGrade', 131 | 'identifier': identifier, 132 | 'job': loggedInUser.job, 133 | 'grade': grade 134 | }) 135 | }) 136 | .then(() => { 137 | refreshbossactions(); 138 | }); 139 | } 140 | } 141 | 142 | $('#bossactions-bank button').click( function () { 143 | let amount = parseInt($('#ba-amount').val()); 144 | 145 | if ( amount && amount > 0 ) { 146 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:esx`, { 147 | method: 'POST', 148 | body: JSON.stringify({ 149 | 'function': 'society', 150 | 'event': $( this ).attr( 'action' ), 151 | 'amount': amount, 152 | 'job': loggedInUser.job 153 | }) 154 | }) 155 | .then(() => { 156 | refreshbossactions(); 157 | }); 158 | } 159 | }); 160 | 161 | $('#bossactions-bank').submit(() => { return false; }); 162 | 163 | refreshbossactions(); 164 | 165 | $('.bossactions-menu-square').click( function() { 166 | let baPage = $( this ).attr( 'page' ); 167 | 168 | if ( baPage != _baPage ) { 169 | $( _baPage ).fadeOut('fast', () => { 170 | _baPage = baPage; 171 | $( _baPage ).fadeIn(); 172 | }); 173 | } 174 | }); 175 | -------------------------------------------------------------------------------- /client/html/programs/calcylator/calcylator.css: -------------------------------------------------------------------------------- 1 | .program-calcylator-header { 2 | color: #000000; 3 | background: url(../../assets/images/blurr.png); 4 | font-size: 14px; 5 | } 6 | 7 | .program-calcylator { 8 | height: 100%; 9 | width: 100%; 10 | color: #000000; 11 | background: url(../../assets/images/blurr.png); 12 | } 13 | 14 | .program-calcylator .program-content { 15 | overflow: hidden; 16 | position: relative; 17 | } 18 | 19 | .icon-calcylator { 20 | background-position: -600px 0; 21 | } 22 | 23 | .icon-calcylator:hover { 24 | background-position: -600px -60px; 25 | } 26 | 27 | .icon-calcylator:active { 28 | background-position: -600px -120px; 29 | } 30 | 31 | .icon-calcylator-small { 32 | background-position: -612px -193px; 33 | } 34 | 35 | .program-calcylator input { 36 | margin: 0 !important; 37 | padding: 0 !important; 38 | } 39 | 40 | .program-calcylator h6 { 41 | font-size: 20px; 42 | font-weight: bold; 43 | padding: 4px; 44 | text-align: right; 45 | height: 27px; 46 | } 47 | 48 | #calcylator-numbers { 49 | height: 100%; 50 | } 51 | 52 | .calc-numb { 53 | display: inline-block; 54 | background: #ffffff; 55 | width: 45px; 56 | height: 45px; 57 | float: left; 58 | text-align: center; 59 | position: relative; 60 | border: 1px solid rgba(219, 219, 219, 0.438); 61 | } 62 | 63 | .calc-numb:hover { 64 | background: #dbdbdb; 65 | } 66 | 67 | .calc-numb:active { 68 | background: #d3d3d3; 69 | } 70 | 71 | .c-num { 72 | font-weight: bold; 73 | } 74 | 75 | .c-action:hover { 76 | color: #ffffff; 77 | background: #1a86db; 78 | } 79 | 80 | .c-action:active { 81 | color: #ffffff; 82 | background: #197fce; 83 | } -------------------------------------------------------------------------------- /client/html/programs/calcylator/calcylator.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

CE

6 |

C

7 |

8 |

/

9 |

7

10 |

8

11 |

9

12 |

*

13 |

4

14 |

5

15 |

6

16 |

-

17 |

1

18 |

2

19 |

3

20 |

+

21 |

±

22 |

0

23 |

.

24 |

=

25 |
26 |
27 |
28 | 29 | -------------------------------------------------------------------------------- /client/html/programs/calcylator/calcylator.js: -------------------------------------------------------------------------------- 1 | $('.calc-numb').click( function() { 2 | let text = $( this ).text(); 3 | let currText = $('#calc-enumb').text(); 4 | 5 | if ( $( this ).hasClass( 'c-action' ) ) { 6 | switch( text ) { 7 | case '±': 8 | 9 | break; 10 | case '⇦': 11 | $('#calc-enumb').text(`${ currText.substr(0, currText.length - 1) }`); 12 | break; 13 | case 'C': 14 | $('#calc-enumb').text(' '); 15 | break; 16 | case 'CE': 17 | $('#calc-enumb').text(' '); 18 | break; 19 | case '=': 20 | $('#calc-enumb').text( eval( currText.replace(/\s/g, '') ) ); 21 | break; 22 | case '.': 23 | $('#calc-enumb').text(`${ currText }${ text }`); 24 | break; 25 | default: 26 | $('#calc-enumb').text(`${ currText } ${ text } `); 27 | } 28 | } else { 29 | $('#calc-enumb').text( currText + text ); 30 | } 31 | }); -------------------------------------------------------------------------------- /client/html/programs/cardealer/cardealer.css: -------------------------------------------------------------------------------- 1 | .program-cardealer-header { 2 | background: rgba(255,0,0,1); 3 | color: #ffffff; 4 | } 5 | 6 | .program-cardealer { 7 | height: 100%; 8 | width: 100%; 9 | color: #ffffff; 10 | background: linear-gradient(45deg, #a42fde 0%, #a42fde 14%, #ff0000 100%); 11 | } 12 | 13 | .icon-cardealer { 14 | background-position: -240px 0; 15 | } 16 | 17 | .icon-cardealer:hover { 18 | background-position: -240px -60px; 19 | } 20 | 21 | .icon-cardealer:active { 22 | background-position: -240px -120px; 23 | } 24 | 25 | .icon-cardealer-small { 26 | background-position: -251px -193px; 27 | } 28 | 29 | .program-cardealer .card { 30 | background: transparent; 31 | } 32 | 33 | .program-cardealer .card .card-image img{ 34 | height: 114px; 35 | } 36 | 37 | .program-cardealer .card-content { 38 | padding: 10px; 39 | text-align: center; 40 | color: #ffffff; 41 | background: rgba(0, 0, 0, 0.2); 42 | } 43 | 44 | .program-cardealer .card-title { 45 | font-size: 20px; 46 | } 47 | 48 | #cardealer-list { 49 | display: none; 50 | } 51 | 52 | #cardealer-list .card-content { 53 | height: 53px; 54 | overflow: hidden; 55 | } 56 | 57 | .cardealer-header h6 { 58 | text-align: center; 59 | font-size: 22px; 60 | margin: 30px 0 30px 0; 61 | text-transform: uppercase; 62 | } 63 | 64 | #cardealer-list-header .material-icons { 65 | float: left; 66 | } 67 | 68 | #cardealer-vehicle { 69 | display: none; 70 | margin-top: 40px; 71 | text-align: center; 72 | } 73 | 74 | #cardealer-vehicle i { 75 | float: left; 76 | } 77 | 78 | .vehicle-image:nth-child(-n+2) { 79 | width: 46.5%; 80 | margin-bottom: -5px; 81 | } 82 | 83 | #large-image { 84 | display: none; 85 | position: absolute; 86 | left: 150px; 87 | top: 80px; 88 | } 89 | 90 | #large-image img { 91 | width: 100%; 92 | height: 100%; 93 | } 94 | 95 | .hidden { 96 | display: none; 97 | } 98 | 99 | #cardealer-vehicle-stats { 100 | margin: 20px 0 40px 21px; 101 | text-align: left; 102 | } 103 | 104 | #cardealer-vehicle-stats li span:nth-child(odd) { 105 | font-weight: bold; 106 | } 107 | 108 | #cardealer-vehicle-stats ul { 109 | padding: 10px; 110 | width: 274px; 111 | } 112 | 113 | #cardealer-vehicle-statbars { 114 | margin-left: 80px; 115 | background-color: rgba(0, 0, 0, 0.2); 116 | border-radius: 5px; 117 | padding: 10px; 118 | width: 274px; 119 | } 120 | 121 | .stat-wrapper { 122 | width: 200px; 123 | } 124 | 125 | .stat-wrapper .stat-title { 126 | font-weight: bold; 127 | } 128 | 129 | .stat-wrapper .stat-bar { 130 | width: 100%; 131 | height: 8px; 132 | background: linear-gradient(257deg, rgba(255,1,249,1) 0%, rgba(179,1,124,1) 100%); 133 | } 134 | 135 | .stat-wrapper .stat-amount { 136 | float: right; 137 | margin: -16px -52px 0 0 ; 138 | } 139 | 140 | .stat-box { 141 | display: inline-block; 142 | } -------------------------------------------------------------------------------- /client/html/programs/cardealer/cardealer.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | arrow_back 12 |
13 |
14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | arrow_back 22 |
23 |
24 |
25 |
26 |
    27 |
  • 28 | Model: 29 | 30 |
  • 31 |
  • 32 | Manufacturer: 33 | 34 |
  • 35 |
  • 36 | Price: 37 | 38 |
  • 39 |
  • 40 | Seats: 41 | 42 |
  • 43 |
  • 44 | Top speed: 45 | 46 |
  • 47 |
48 |
49 |
50 | Speed 51 |
52 | 53 |
54 |
55 | Acceleration 56 |
57 | 58 |
59 |
60 | Braking 61 |
62 | 63 |
64 |
65 | Handling 66 |
67 | 68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | -------------------------------------------------------------------------------- /client/html/programs/cardealer/cardealer.js: -------------------------------------------------------------------------------- 1 | let blacklistedCategory = ['military', 'industrial', 'emergency', 'utility', 'helicopters', 'planes', 'service', 'boats', 'commercial', 'trains']; 2 | let blacklistedVehicle = ['caracara', 'insurgent', 'insurgent pick-up', 'insurgent pick-ip custom', 'menacer', 'ramp buggy', 'technical', 'technical aqua', 'technical custom', 'oppressor', 'oppressor mk ii', 'vigilante (car)', 'armored boxville', 'turreted limo']; 3 | let showLarge = false; 4 | let currentAngle; 5 | 6 | fetch('https://gta.now.sh/api/vehicles/class') 7 | .then(response => response.json()) 8 | .then(categories => { 9 | Object.keys( categories ).forEach(category => { 10 | if ( !blacklistedCategory.includes(category) ) { 11 | let div = `
12 | 13 |
14 |
15 | 16 |
17 |
18 | ${ category } 19 |
20 |
21 |
22 |
`; 23 | 24 | $('#cardealer-category').append( div ); 25 | } 26 | }); 27 | }); 28 | 29 | function showLargeImage( angle ) { 30 | currentAngle = angle; 31 | 32 | $(`.${ angle }`).removeClass('hidden'); 33 | 34 | $('#large-image').fadeIn('fast', function() { 35 | showLarge = true; 36 | }); 37 | } 38 | 39 | function showVehicle( vehicleName ) { 40 | $('#large-image').html(''); 41 | 42 | fetch(`https://gta.now.sh/api/vehicles/${ vehicleName }`) 43 | .then(response => response.json()) 44 | .then(vehicle => { 45 | let divSmallerImages = ''; 46 | let divLargerImages = ''; 47 | 48 | Object.keys( vehicle.images ).forEach(angle => { 49 | divSmallerImages += ``; 50 | divLargerImages += ``; 51 | }); 52 | 53 | $('#cardealer-vehicle-content').html(''); 54 | $('#large-image').html(''); 55 | 56 | $('#cardealer-vehicle-content').append( divSmallerImages ); 57 | $('#large-image').append( divLargerImages ); 58 | 59 | $('#vehicle-model').text(vehicle.model); 60 | $('#vehicle-manufacturer').text(vehicle.manufacturer); 61 | $('#vehicle-seats').text(vehicle.seats); 62 | $('#vehicle-price').text(vehicle.price); 63 | 64 | $('#vehicle-speed .stat-amount').text(vehicle.speed); 65 | $('#vehicle-speed .stat-bar').css({ width: `${ vehicle.speed }%` }); 66 | $('#vehicle-acceleration .stat-amount').text(vehicle.acceleration); 67 | $('#vehicle-acceleration .stat-bar').css({ width: `${ vehicle.acceleration }%` }); 68 | $('#vehicle-braking .stat-amount').text(vehicle.braking); 69 | $('#vehicle-braking .stat-bar').css({ width: `${ vehicle.braking }%` }); 70 | $('#vehicle-handling .stat-amount').text(vehicle.handling); 71 | $('#vehicle-handling .stat-bar').css({ width: `${ vehicle.handling }%` }); 72 | 73 | if ( vehicle.topSpeed ) { 74 | $('#vehicle-topspeed').text(`${ vehicle.topSpeed.mph } mph | ${ vehicle.topSpeed.kmh } kmh`); 75 | } 76 | 77 | // Ugly timeout to give some extra time for the images to load.. 78 | $('#cardealer-list').fadeOut(500, () => { 79 | $('#cardealer-vehicle h6').text( vehicleName ); 80 | $('#cardealer-vehicle').fadeIn('fast'); 81 | }); 82 | }); 83 | } 84 | 85 | function showVehicleCategory( category ) { 86 | $('#cardealer-list-content').html(''); 87 | 88 | fetch(`https://gta.now.sh/api/vehicles/class/${ category }`) 89 | .then(response => response.json()) 90 | .then(vehicles => { 91 | $('#cardealer-category').fadeOut('fast', () => { 92 | Object.keys( vehicles ).forEach(vehicle => { 93 | if ( !blacklistedVehicle.includes( vehicle ) ) { 94 | let div = `
95 | 96 |
97 |
98 | 99 |
100 |
101 | ${ vehicle } 102 |
103 |
104 |
105 |
`; 106 | 107 | $('#cardealer-list-content').append( div ); 108 | } 109 | }); 110 | }); 111 | 112 | $('#cardealer-list-header h6').text( category ); 113 | $('#cardealer-list-content').scrollTop(); 114 | $('#cardealer-list').fadeIn('slow'); 115 | }); 116 | } 117 | 118 | function goBack( type) { 119 | if ( type === 'category' ) { 120 | $('#cardealer-list').fadeOut('fast', () => { 121 | $('#cardealer-category').fadeIn('fast'); 122 | }); 123 | } else { 124 | $('#cardealer-vehicle').fadeOut('fast', () => { 125 | $('#cardealer-vehicle-content').html(''); 126 | $('#cardealer-list').fadeIn('fast'); 127 | }); 128 | } 129 | } 130 | 131 | $('body').on('click', '.program-cardealer', () => { 132 | if ( showLarge ) { 133 | $(`.${ currentAngle }`).addClass('hidden'); 134 | $('#large-image').hide(); 135 | showLarge = false; 136 | } 137 | }); -------------------------------------------------------------------------------- /client/html/programs/controlpanel/controlpanel.css: -------------------------------------------------------------------------------- 1 | .program-controlpanel-header { 2 | background: #0078d7; 3 | color: #ffffff; 4 | } 5 | 6 | .program-controlpanel { 7 | height: 100%; 8 | width: 100%; 9 | color: #000000; 10 | background: rgb(253, 253, 255); 11 | } 12 | 13 | .icon-controlpanel { 14 | background-position: -900px 0; 15 | } 16 | 17 | .icon-controlpanel:hover { 18 | background-position: -900px -60px; 19 | } 20 | 21 | .icon-controlpanel:active { 22 | background-position: -900px -120px; 23 | } 24 | 25 | .icon-controlpanel-small { 26 | background-position: -912px -193px; 27 | } 28 | 29 | .icons-system-and-security { 30 | background-position: -140px 0; 31 | } 32 | 33 | .icons-system-user-accounts { 34 | background-position: -140px -140px; 35 | } 36 | 37 | .icons-system-appearance { 38 | background-position: -140px -175px; 39 | } 40 | 41 | .icons-system-network-and-internet { 42 | background-position: -140px -35px; 43 | } 44 | 45 | .icons-system-time { 46 | background-position: -140px -210px; 47 | } 48 | 49 | .icons-system-hardware { 50 | background-position: -140px -70px; 51 | } 52 | 53 | .icons-system-program { 54 | background-position: -140px -105px; 55 | } 56 | 57 | .icons-system-access { 58 | background-position: -140px -245px; 59 | } 60 | 61 | .icons-system-admin { 62 | background-position: -175px 0; 63 | } 64 | 65 | .program-controlpanel h6 { 66 | color: #2d6db1; 67 | font-size: 15px; 68 | font-weight: 500; 69 | margin-bottom: 25px; 70 | } 71 | 72 | .controlpanel-content-wrapper .icons-system-admin { 73 | float: left; 74 | background-position: -175px -10px; 75 | margin: 0 -5px 0 -10px; 76 | } 77 | 78 | .controlpanel-category span { 79 | color: #04971c; 80 | } 81 | 82 | .controlpanel-category span:hover { 83 | color: #29ce45; 84 | cursor: pointer; 85 | text-decoration: underline; 86 | } 87 | 88 | .controlpanel-category li { 89 | color: #0066cc; 90 | font-size: 11px; 91 | } 92 | 93 | .controlpanel-category li:hover { 94 | cursor: pointer; 95 | color: #4a9aeb; 96 | text-decoration: underline; 97 | } 98 | 99 | .controlpanel-category { 100 | position: relative; 101 | padding: 4px; 102 | border-radius: 2px; 103 | } 104 | 105 | .controlpanel-category:hover { 106 | background-color: #e5f3ff; 107 | } 108 | 109 | .controlpanel-icon-wrapper { 110 | float: left; 111 | } 112 | 113 | .controlpanel-content-wrapper{ 114 | margin-left: 50px; 115 | } 116 | 117 | .c-m30 { 118 | margin-top: -30px; 119 | } 120 | 121 | .c-m50 { 122 | margin-top: -50px; 123 | } 124 | 125 | .c-m60 { 126 | margin-top: -60px; 127 | } -------------------------------------------------------------------------------- /client/html/programs/controlpanel/controlpanel.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
Adjust your computer's settings
7 |
8 |
9 |
10 |
11 |
12 | System and Security 13 |
    14 |
  • Review your computer's status
  • 15 |
  • Save backup copies of your files with File History
  • 16 |
  • Backup and Restore (windows 7)
  • 17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | User Accounts 26 |
    27 |
  • Change account type
  • 28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Appearance and Personalisation 37 |
    38 |
  • Change the theme
  • 39 |
  • Adjust screen resolution
  • 40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Network and Internet 49 |
    50 |
  • View network status and tasks
  • 51 |
  • Choose homegroup and sharing options
  • 52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Clock, Language and Region 61 |
    62 |
  • Add a language
  • 63 |
  • Change input methods
  • 64 |
  • Change datem time or number formats
  • 65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | Harware and Sound 74 |
    75 |
  • View devices and printers
  • 76 |
  • Add a device
  • 77 |
  • Adjust commonly used mobility settings
  • 78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | Ease of Access 87 |
    88 |
  • Let Windows suggest settings
  • 89 |
  • Optimise visual display
  • 90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | Program 99 |
    100 |
  • Uninstall
  • 101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | 110 | -------------------------------------------------------------------------------- /client/html/programs/controlpanel/controlpanel.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/programs/controlpanel/controlpanel.js -------------------------------------------------------------------------------- /client/html/programs/folder/folder.css: -------------------------------------------------------------------------------- 1 | .program-folder-header { 2 | background: #ffffff; 3 | color: #000000; 4 | border-bottom: 1px solid #d5d5d5; 5 | } 6 | 7 | .program-folder { 8 | height: 100%; 9 | width: 100%; 10 | color: #000000; 11 | background: #ffffff; 12 | } 13 | 14 | .icon-folder { 15 | background-position: -780px 0; 16 | } 17 | 18 | .icon-folder:hover { 19 | background-position: -780px -60px; 20 | } 21 | 22 | .icon-folder:active { 23 | background-position: -780px -120px; 24 | } 25 | 26 | .icon-folder-small { 27 | background-position: -791px -193px; 28 | } 29 | 30 | #f-contextmenu { 31 | display: none; 32 | z-index: 100; 33 | position: absolute; 34 | width: 100px; 35 | height: auto; 36 | left: 0; 37 | top: 0; 38 | background: url(../../assets/images/blurr.png); 39 | color: #000000; 40 | } 41 | 42 | #f-contextmenu li { 43 | padding: 4px; 44 | } 45 | 46 | 47 | #f-contextmenu li:nth-child(even) { 48 | background: rgba(0, 0, 0, 0.1); 49 | } 50 | 51 | #f-contextmenu li:hover { 52 | color: #ffffff; 53 | background: #0078d7; 54 | } 55 | 56 | #f-contextmenu li:active { 57 | background: #0065b8; 58 | } 59 | 60 | #f-contextmenu li .material-icons { 61 | margin: -5px 5px 0 0; 62 | vertical-align: middle; 63 | font-size: 18px; 64 | } 65 | 66 | #f-icons { 67 | width: 100%; 68 | height: 100%; 69 | } 70 | 71 | #f-icons .icon { 72 | display: inline-block; 73 | } -------------------------------------------------------------------------------- /client/html/programs/folder/folder.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
    5 |
  • addRestore
  • 6 |
7 |
8 |
9 | 10 |
11 |
12 |
13 | 14 | -------------------------------------------------------------------------------- /client/html/programs/folder/folder.js: -------------------------------------------------------------------------------- 1 | 2 | $('body').on('contextmenu', '.program-folder .icon', ( e ) => { 3 | $('#f-contextmenu').css({ 4 | top: $(e.target).position().top + 20, 5 | left: $(e.target).position().left + 20 6 | }); 7 | 8 | let classes = $( e.target ).parent('.icon').attr('class').split(' '); 9 | 10 | for ( let i = 0; i < classes.length; i++ ) { 11 | if ( classes[i].includes('program-') ) { 12 | $('#f-restore').attr('identifier', classes[i]); 13 | } 14 | } 15 | 16 | $('#f-contextmenu').show(); 17 | e.preventDefault(); 18 | }); 19 | 20 | $('#f-icons').click(() => { 21 | $('#f-contextmenu').hide(); 22 | }); 23 | 24 | $('#f-restore').click( function() { 25 | let ji = false; 26 | 27 | let id = $( this ).attr('identifier'); 28 | 29 | for ( let j = 0; j < 8; j++ ) { 30 | for ( let i = 0; i < 17; i++ ) { 31 | if ( $(`.${ j }-${ i }`).find('.icon').length === 0 ) { 32 | if ( !ji ) { 33 | ji = true; 34 | $(`.${ j }-${ i }`).append( $(`.${ id }`) ); 35 | $(`.${ id }`).draggable({disabled: false}); 36 | } 37 | } 38 | } 39 | } 40 | 41 | $( `.program-folder .${ id }` ).remove(); 42 | 43 | $('#f-contextmenu').hide(); 44 | }); -------------------------------------------------------------------------------- /client/html/programs/forum/forum.css: -------------------------------------------------------------------------------- 1 | .program-forum-header { 2 | background: rgb(167, 167, 167); 3 | color: #ffffff; 4 | } 5 | 6 | .program-forum { 7 | height: 100%; 8 | width: 100%; 9 | color: #444444; 10 | background: rgb(253, 253, 255); 11 | } 12 | 13 | .icon-forum { 14 | background-position: -300px 0; 15 | } 16 | 17 | .icon-forum:hover { 18 | background-position: -300px -60px; 19 | } 20 | 21 | .icon-forum:active { 22 | background-position: -300px -120px; 23 | } 24 | 25 | .icon-forum-small { 26 | background-position: -311px -193px; 27 | } 28 | 29 | .program-forum .select-dropdown span { 30 | color: #444444; 31 | } 32 | 33 | .program-forum .select-dropdown li img { 34 | height: 30px; 35 | width: 30px; 36 | margin-top: 10px; 37 | } 38 | 39 | .program-forum .input-field input[type=text]:focus, 40 | .program-forum textarea:focus { 41 | border-bottom: 1px solid #444444 !important; 42 | box-shadow: none !important; 43 | } 44 | 45 | .program-forum textarea:focus + label { 46 | color: #444444 !important; 47 | } 48 | 49 | .forum-post { 50 | padding: 10px !important; 51 | color: #444444; 52 | position: relative; 53 | } 54 | 55 | .forum-post .material-icons { 56 | font-size: 30px; 57 | float: left; 58 | margin-left: 19px; 59 | } 60 | 61 | .forum-post img { 62 | float: left; 63 | border-radius: 100%; 64 | margin-left: 10px; 65 | width: 50px; 66 | height: 50px; 67 | } 68 | 69 | .forum-post-details { 70 | width: 68px; 71 | overflow: hidden; 72 | float: left; 73 | text-align: center; 74 | } 75 | 76 | .forum-post-text { 77 | padding: 10px; 78 | width: 84%; 79 | color: #ffffff; 80 | border-bottom-right-radius: 15px; 81 | position: relative; 82 | background: #6d6d6d; 83 | white-space: pre-wrap; 84 | } 85 | 86 | .forum-post-username { 87 | margin-top: 60px; 88 | } 89 | 90 | .forum-post-text::before { 91 | content: ' '; 92 | position: absolute; 93 | width: 0; 94 | height: 0; 95 | } 96 | 97 | .forum-post-text { 98 | border-bottom-right-radius: 15px; 99 | float: right; 100 | } 101 | 102 | .forum-post-text::before { 103 | left: -10px; 104 | border-top: 10px solid transparent; 105 | border-bottom: 10px solid transparent; 106 | border-right: 10px solid #6d6d6d; 107 | } 108 | 109 | .news .forum-post-text { 110 | background: rgb(96, 143, 58); 111 | } 112 | 113 | .news .forum-post-text::before { 114 | border-right-color: rgb(96, 143, 58) !important; 115 | border-left-color: rgb(96, 143, 58) !important; 116 | } 117 | 118 | .news .material-icons { 119 | color: rgb(96, 143, 58); 120 | } 121 | 122 | .info .forum-post-text { 123 | background: rgb(58, 102, 143); 124 | } 125 | 126 | .info .forum-post-text::before { 127 | border-right-color: rgb(58, 102, 143) !important; 128 | border-left-color: rgb(58, 102, 143) !important; 129 | } 130 | 131 | .info .material-icons { 132 | color: rgb(58, 102, 143); 133 | } 134 | 135 | .important .forum-post-text { 136 | background: rgb(143, 58, 58); 137 | } 138 | 139 | .important .material-icons { 140 | color: rgb(143, 58, 58); 141 | } 142 | 143 | .important .forum-post-text::before { 144 | border-right-color: rgb(143, 58, 58) !important; 145 | border-left-color: rgb(143, 58, 58) !important; 146 | } 147 | 148 | .forum-delete { 149 | position: absolute; 150 | top: 20px; 151 | color: rgb(143, 58, 58) !important; 152 | } 153 | 154 | .forum-delete { 155 | left: -40px; 156 | } 157 | 158 | #forum-posts { 159 | margin-bottom: 50px; 160 | } -------------------------------------------------------------------------------- /client/html/programs/forum/forum.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
Forum -
6 |
7 |
8 |
9 | 15 | 16 | 17 |
18 |
19 | 20 | 21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | 30 | -------------------------------------------------------------------------------- /client/html/programs/forum/forum.js: -------------------------------------------------------------------------------- 1 | $('.program-forum h6').text(`Forum - ${loggedInUser.job}`); 2 | $('select').formSelect(); 3 | 4 | function fetchPosts() { 5 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:fetchForumPosts`, { 6 | method: 'POST', 7 | body: JSON.stringify({ 8 | type: 'fetchForumPosts', 9 | data: { 10 | '@job': loggedInUser.job 11 | } 12 | }) 13 | }) 14 | .then( response => response.json() ) 15 | .then( data => { 16 | if ( data != 'false' ) { 17 | $('#forum-posts').html(''); 18 | 19 | Object.keys(data).forEach(( k ) => { 20 | let icon = ''; 21 | let forumDelete = ''; 22 | 23 | if ( data[k].category != 'message' ) { 24 | let forumIcon = 'fiber_new'; 25 | 26 | if ( data[k].category === 'important' ) { 27 | forumIcon = 'warning'; 28 | } else if ( data[k].category === 'info') { 29 | forumIcon = 'info'; 30 | } 31 | 32 | icon = `${forumIcon}`; 33 | } 34 | 35 | if ( data[k].username === loggedInUser.username || loggedInUser.job === 'all' || loggedInUser.group === 'admin' ) { 36 | forumDelete = `delete`; 37 | } 38 | 39 | forumDiv = `
40 |
41 | ${forumDelete} 42 | 43 |

${data[k].username}

44 | ${icon} 45 |

${data[k].date}

46 |
47 |

${data[k].text}

48 |
`; 49 | 50 | $('#forum-posts').prepend(forumDiv); 51 | }); 52 | } 53 | }); 54 | } 55 | 56 | setTimeout(() => { 57 | fetchPosts(); 58 | }, 200); 59 | 60 | function refreshforum() { 61 | fetchPosts(); 62 | } 63 | 64 | $('.program-forum form').submit( () => { 65 | let forumCategory = $('.program-forum .selected').text().toLowerCase(); 66 | let forumText = $('#forum-textarea').val(); 67 | let today = new Date(); 68 | let date = `${today.getDate()}/${today.getMonth() + 1}`; 69 | 70 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:addForumPost`, { 71 | method: 'POST', 72 | body: JSON.stringify({ 73 | type: 'addForumPost', 74 | data: { 75 | '@category': forumCategory, 76 | '@text': forumText, 77 | '@username': loggedInUser.username, 78 | '@avatar': loggedInUser.avatar, 79 | '@date': date, 80 | '@job': loggedInUser.job 81 | } 82 | }) 83 | }) 84 | .then(() => { 85 | setTimeout(() => { 86 | fetchPosts(); 87 | }, 100); 88 | }); 89 | 90 | $('#forum-textarea').val(''); 91 | 92 | return false; 93 | }); 94 | 95 | $('body').on('click', '.forum-delete', function () { 96 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:deleteForumPost`, { 97 | method: 'POST', 98 | body: JSON.stringify({ 99 | type: 'deleteForumPost', 100 | data: { 101 | '@id': $(this).closest('.forum-post').attr('post') 102 | } 103 | }) 104 | }); 105 | 106 | $(this).closest('.forum-post').remove(); 107 | }); -------------------------------------------------------------------------------- /client/html/programs/forum/important.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/programs/forum/important.png -------------------------------------------------------------------------------- /client/html/programs/forum/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/programs/forum/info.png -------------------------------------------------------------------------------- /client/html/programs/forum/news.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/programs/forum/news.png -------------------------------------------------------------------------------- /client/html/programs/groups/groups.css: -------------------------------------------------------------------------------- 1 | .program-groups-header { 2 | background: rgb(73, 21, 21); 3 | color: #ffffff; 4 | } 5 | 6 | .program-groups { 7 | height: 100%; 8 | width: 100%; 9 | color: #ffffff; 10 | background: rgb(105, 41, 41); 11 | } 12 | 13 | .icon-groups { 14 | background-position: -180px 0; 15 | } 16 | 17 | .icon-groups:hover { 18 | background-position: -180px -60px; 19 | } 20 | 21 | .icon-groups:active { 22 | background-position: -180px -120px; 23 | } 24 | 25 | .icon-groups-small { 26 | background-position: -192px -193px; 27 | } 28 | 29 | .program-groups h6 { 30 | margin-bottom: 30px; 31 | } 32 | 33 | .program-groups .input-field input { 34 | color: #ffffff; 35 | border-bottom: 1px solid #ffffff; 36 | } 37 | 38 | .program-groups .input-field label { 39 | color: #ffffff; 40 | } 41 | 42 | .program-groups .input-field input[type=text]:focus + label, 43 | .program-groups .input-field input[type=password]:focus + label, 44 | .program-groups textarea:focus + label { 45 | color: #ffffff !important; 46 | } 47 | 48 | .program-groups input[type=text]:disabled + label { 49 | color: #ffffff !important; 50 | } 51 | 52 | .program-groups input[type=text]:disabled { 53 | color: #ffffff !important; 54 | border-bottom: 1px solid #9c9c9c !important; 55 | } 56 | 57 | .program-groups .input-field input[type=text]:focus, 58 | .program-groups .input-field input[type=password]:focus { 59 | border-bottom: 1px solid #ffffff !important; 60 | box-shadow: 0 1px 0 0 #ffffff !important; 61 | } 62 | 63 | .program-groups .input-field input[type=text].invalid, 64 | .program-groups .input-field input[type=password].invalid { 65 | border-bottom: 1px solid red; 66 | box-shadow: 0 1px 0 0 red; 67 | } 68 | 69 | .program-groups .input-field input[type=text].valid, 70 | .program-groups .input-field input[type=password].valid { 71 | border-bottom: 1px solid green; 72 | box-shadow: 0 1px 0 0 green; 73 | } 74 | 75 | .program-groups button { 76 | background: #ffffff; 77 | color: #000000; 78 | } 79 | 80 | .program-groups button:hover { 81 | background: #ffffff; 82 | } 83 | 84 | .program-groups button:focus { 85 | background: #ffffff; 86 | } 87 | 88 | .program-groups .input-field .helper-text { 89 | position: absolute; 90 | width: 100%; 91 | } 92 | 93 | .program-groups .collapsible { 94 | border: none; 95 | margin: 0 0 10px 0; 96 | } 97 | 98 | .program-groups .collapsible-header { 99 | background: rgb(73, 21, 21); 100 | border: none; 101 | } 102 | 103 | .program-groups .collapsible-body { 104 | border-bottom: 1px solid rgb(73, 21, 21); 105 | } 106 | 107 | .program-groups .collapsible-body span { 108 | display: list-item; 109 | } 110 | 111 | #program-groups-register { 112 | background: rgb(73, 21, 21); 113 | } 114 | 115 | #groups-delete-user button { 116 | margin-top: 30px; 117 | } -------------------------------------------------------------------------------- /client/html/programs/groups/groups.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
Admin panel
6 |
7 |
    8 |
  • 9 |
    groupUsers
    10 |
    11 |
  • 12 |
13 |
14 |
15 |
    16 |
  • 17 |
    person_addRegister user
    18 |
    19 |
    20 |
    21 |
    22 | 23 | 24 | 25 |
    26 |
    27 | 28 | 29 |
    30 |
    31 | 32 | 33 |
    34 |
    35 | 36 | 37 |
    38 |
    39 | 40 | 41 |
    42 |
    43 | 44 | 45 |
    46 | 47 |
    48 |
    49 |
    50 |
  • 51 |
52 |
    53 |
  • 54 |
    editUpdate user
    55 |
    56 |
    57 |
    58 |
    59 | 60 | 61 | 62 |
    63 |
    64 | 65 | 66 |
    67 |
    68 | 69 | 70 |
    71 |
    72 | 73 | 74 |
    75 |
    76 | 77 | 78 |
    79 |
    80 | 81 | 82 |
    83 |
    84 | 85 | 86 |
    87 |
    88 | 89 | 90 |
    91 | 92 |
    93 |
    94 |
    95 |
  • 96 |
97 |
    98 |
  • 99 |
    deleteDelete user
    100 |
    101 |
    102 |
    103 |
    104 | 105 | 106 | 107 |
    108 | 109 |
    110 |
    111 |
    112 |
  • 113 |
114 |
115 |
116 |
117 |
118 |
119 | 120 | -------------------------------------------------------------------------------- /client/html/programs/groups/groups.js: -------------------------------------------------------------------------------- 1 | function getUsers( job, group ) { 2 | let fetchType = 'fetchAllUsers'; 3 | let fetchParam = {}; 4 | 5 | if ( job != 'all' && group ) { 6 | fetchType = 'fetchUsersByJob'; 7 | fetchParam = { 8 | '@job' : job 9 | } 10 | } 11 | 12 | if ( job != 'all' ) { 13 | $('#groups-register-job').val(job); 14 | $('#groups-update-job').val(job); 15 | $('#groups-update-job').attr('disabled', true); 16 | $('#groups-register-job').attr('disabled', true); 17 | $('#groups-update-job').attr('disabled', true); 18 | 19 | M.updateTextFields(); 20 | } 21 | 22 | fetch(`http://${ GetParentResourceName() }/jsfour-computer:${ fetchType }`, { 23 | method: 'POST', 24 | body: JSON.stringify({ 25 | type: fetchType, 26 | data: fetchParam 27 | }) 28 | }) 29 | .then( response => response.json() ) 30 | .then( data => { 31 | if ( data != 'false' && data.length > 0 ) { 32 | $('#program-groups-users').html(' '); 33 | 34 | Object.keys( data ).forEach(( k ) => { 35 | $('#program-groups-users').append(` 45 | ${ data[k].username }`) 46 | }); 47 | 48 | $('.collapsible').collapsible(); 49 | } 50 | }); 51 | } 52 | 53 | function refreshgroups() { 54 | getUsers( loggedInUser.job, loggedInUser.group ); 55 | } 56 | 57 | getUsers( loggedInUser.job, loggedInUser.group ); 58 | 59 | $('body').on('click', '.program-groups .collapsible', function () { 60 | $('.active').attr('collapsible', $(this).attr('id')); 61 | }); 62 | 63 | $('body').on('click', '#program-groups-users span', function () { 64 | let active = $('.active').attr('collapsible'); 65 | 66 | if ( active === 'groups-delete-collapsible' ) { 67 | $('#groups-delete-username').val( $(this).attr('username') ); 68 | $('#groups-delete-username').attr( 'identifier', $(this).attr('identifier') ); 69 | $('#groups-delete-username').attr( 'email', `${ $(this).attr('username').toLowerCase() }@${ $(this).attr('job').toLowerCase() }.com` ); 70 | 71 | if ( $(this).attr('job') === 'all' ) { 72 | $('#groups-delete-user button').attr('disabled', true); 73 | } else { 74 | $('#groups-delete-user button').attr('disabled', false); 75 | } 76 | } else { 77 | $('#groups-register-collapsible').collapsible('close'); 78 | $('#groups-delete-collapsible').collapsible('close'); 79 | 80 | $('#groups-update-username').val( $(this).attr('username') ); 81 | $('#groups-update-username').attr( 'oldUsername', $(this).attr('username') ); 82 | $('#groups-update-username').attr( 'identifier', $(this).attr('identifier') ); 83 | $('#groups-update-username').attr( 'avatar', $(this).attr('avatar') ); 84 | 85 | if ( $(this).attr('job').toLowerCase() != 'null' ) { 86 | $('#groups-update-username').attr( 'email', `${ $(this).attr('username').toLowerCase() }@${ $(this).attr('job').toLowerCase() }.com` ); 87 | } else { 88 | $('#groups-update-username').attr( 'email', $(this).attr('job').toLowerCase()); 89 | } 90 | 91 | $('#groups-update-password').val( $(this).attr('password') ); 92 | $('#groups-update-firstname').val( $(this).attr('firstname') ); 93 | $('#groups-update-lastname').val( $(this).attr('lastname') ); 94 | $('#groups-update-group').val( $(this).attr('group') ); 95 | $('#groups-update-avatar').val( $(this).attr('avatar') ); 96 | $('#groups-update-desktop').val( $(this).attr('desktop') ); 97 | 98 | if ( loggedInUser.job === 'all' ) { 99 | $('#groups-update-job').val( $(this).attr('job') ); 100 | } 101 | 102 | $('#groups-update-collapsible').collapsible('open'); 103 | } 104 | 105 | M.updateTextFields(); 106 | }); 107 | 108 | function updateRows( type ) { 109 | $(`#groups-${type}-user input`).removeClass('valid'); 110 | $(`#groups-${type}-user input`).removeClass('invalid'); 111 | 112 | let inputs = $(`#groups-${type}-user`).find('input'); 113 | let rows = {}; 114 | let fetchType = 'addUser'; 115 | 116 | for ( let i = 0; i < inputs.length; i++ ) { 117 | if ( inputs.eq(i).val() ) { 118 | rows[`@${inputs.eq(i).attr('id').split('-')[2]}`] = inputs.eq(i).val().toLowerCase(); 119 | } 120 | } 121 | 122 | if ( type != 'register' ) { 123 | fetchType = 'updateUser'; 124 | rows['@new'] = rows['@password']; 125 | rows['@id'] = $('#groups-update-username').attr( 'identifier' ); 126 | rows['@email'] = `${ $('#groups-update-username').val().toLowerCase() }@${ $('#groups-update-job').val().toLowerCase() }.com`; 127 | } else { 128 | rows['@email'] = `${ $('#groups-register-username').val().toLowerCase() }@${ $('#groups-register-job').val().toLowerCase() }.com`; 129 | rows['@avatar'] = `https://via.placeholder.com/50/${ (Math.random()*0xFFFFFF<<0).toString(16) }/?text=${ $('#groups-register-username').val().toUpperCase()[0] }` ; 130 | } 131 | 132 | if ( $('#groups-update-username').val() != $('#groups-update-username').attr('oldUsername') ) { 133 | rows['@uniqueValue'] = '@username'; 134 | } 135 | 136 | if ( $('#groups-update-group').val().toLowerCase() === 'null' ) { 137 | rows['@group'] = 'user'; 138 | $('#groups-update-group').val('user'); 139 | } 140 | 141 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:${ fetchType }`, { 142 | method: 'POST', 143 | body: JSON.stringify({ 144 | type: fetchType, 145 | data: rows 146 | }) 147 | }) 148 | .then( response => response.text() ) 149 | .then( text => { 150 | if ( text != 'false' ) { 151 | refreshgroups(); 152 | 153 | $(`#groups-${type}-user input`).removeClass('invalid'); 154 | $(`#groups-${type}-user input`).addClass('valid'); 155 | 156 | setTimeout(() => { 157 | $(`#groups-${type}-user input`).removeClass('valid'); 158 | }, 1000); 159 | 160 | if ( $('#groups-update-username').attr('avatar') != loggedInUser.avatar ) { 161 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:updateForumAvatar`, { 162 | method: 'POST', 163 | body: JSON.stringify({ 164 | type: 'updateForumAvatar', 165 | data: { 166 | '@avatar': $('#groups-update-avatar').val(), 167 | '@username': $('#groups-update-username').attr( 'identifier' ) 168 | } 169 | }) 170 | }); 171 | } 172 | 173 | if ( type === 'register' ) { 174 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:fetchID`, { 175 | method: 'POST', 176 | body: JSON.stringify({ 177 | type: 'fetchID', 178 | data: { 179 | '@username': $('#groups-register-username').val() 180 | } 181 | }) 182 | }) 183 | .then( response => response.json() ) 184 | .then( data => { 185 | if ( parseInt( data[0].id ) ) { 186 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:registerMail`, { 187 | method: 'POST', 188 | body: JSON.stringify({ 189 | type: 'registerMail', 190 | data: { 191 | '@id': data[0].id, 192 | '@email': `${ $('#groups-register-username').val().toLowerCase() }@${ $('#groups-register-job').val().toLowerCase() }.com`, 193 | '@folder': $('#groups-update-username').attr( 'identifier' ) 194 | } 195 | }) 196 | }); 197 | } 198 | }); 199 | } else { 200 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:updateEmail`, { 201 | method: 'POST', 202 | body: JSON.stringify({ 203 | type: 'updateEmail', 204 | data: { 205 | '@id': $('#groups-update-username').attr( 'identifier' ), 206 | '@email': `${ $('#groups-update-username').val().toLowerCase() }@${ $('#groups-update-job').val().toLowerCase() }.com`, 207 | '@oldemail': $('#groups-update-username').attr( 'email' ) 208 | } 209 | }) 210 | }); 211 | } 212 | } else { 213 | $(`#groups-${type}-user input`).removeClass('valid'); 214 | $(`#groups-${type}-username`).addClass('invalid'); 215 | 216 | setTimeout(() => { 217 | $(`#groups-${type}-user input`).removeClass('invalid'); 218 | }, 2000); 219 | } 220 | }); 221 | } 222 | 223 | $('#groups-register-user').submit(() => { updateRows('register'); return false; }); 224 | $('#groups-update-user').submit(() => { updateRows('update'); return false; }); 225 | 226 | $('#groups-delete-user').submit(() => { 227 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:deleteUser`, { 228 | method: 'POST', 229 | body: JSON.stringify({ 230 | type: 'deleteUser', 231 | data: { 232 | '@id' : $('#groups-delete-username').attr('identifier') 233 | } 234 | }) 235 | }) 236 | .then( response => response.text() ) 237 | .then( data => { 238 | if ( JSON.parse( data ) ) { 239 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:deleteEmail`, { 240 | method: 'POST', 241 | body: JSON.stringify({ 242 | type: 'deleteEmail', 243 | data: { 244 | '@id': $('#groups-delete-username').attr('identifier'), 245 | '@email': $('#groups-delete-username').attr('email') 246 | } 247 | }) 248 | }); 249 | 250 | refreshgroups(); 251 | 252 | $(`#groups-delete-username`).removeClass('invalid'); 253 | $(`#groups-delete-username`).addClass('valid'); 254 | 255 | $('#groups-delete-username').val(''); 256 | 257 | setTimeout(() => { 258 | $(`#groups-delete-username`).removeClass('valid'); 259 | }, 1000); 260 | } else { 261 | $(`#groups-delete-username`).removeClass('valid'); 262 | $(`#groups-delete-username`).addClass('invalid'); 263 | 264 | setTimeout(() => { 265 | $(`#groups-delete-username`).removeClass('invalid'); 266 | }, 1000); 267 | } 268 | }); 269 | 270 | return false; 271 | }); 272 | 273 | M.updateTextFields(); 274 | 275 | $('.nospace').keydown(( e ) => { if ( e.which === 32) return false; }); -------------------------------------------------------------------------------- /client/html/programs/jobcenter/jobcenter.css: -------------------------------------------------------------------------------- 1 | .program-jobcenter-header { 2 | background: #ffffff; 3 | color: #000000; 4 | } 5 | 6 | .program-jobcenter { 7 | height: 100%; 8 | width: 100%; 9 | color: #000000; 10 | background: #efefef; 11 | } 12 | 13 | .program-jobcenter .container { 14 | margin-bottom: 30px; 15 | } 16 | 17 | .icon-jobcenter { 18 | background-position: -660px 0; 19 | } 20 | 21 | .icon-jobcenter:hover { 22 | background-position: -660px -60px; 23 | } 24 | 25 | .icon-jobcenter:active { 26 | background-position: -660px -120px; 27 | } 28 | 29 | .icon-jobcenter-small { 30 | background-position: -671px -193px; 31 | } 32 | 33 | .program-jobcenter .input-field input.invalid { 34 | border-bottom: 1px solid red !important; 35 | box-shadow: 0 1px 0 0 red !important; 36 | } 37 | 38 | .program-jobcenter .input-field input.valid { 39 | border-bottom: 1px solid green !important; 40 | box-shadow: 0 1px 0 0 green !important; 41 | } 42 | 43 | #jc-search { 44 | position: relative; 45 | width: 100%; 46 | background: #00005a; 47 | padding: 25px 0 10px 0; 48 | } 49 | 50 | #jc-search input { 51 | background: #ffffff; 52 | height: 34px !important; 53 | padding-left: 10px !important; 54 | border-radius: 6px 0 0 6px !important; 55 | border: 1px solid #00005a !important; 56 | border-right: none !important; 57 | width: 84%; 58 | } 59 | 60 | #jc-search input:focus { 61 | border: 1px solid #00005a !important; 62 | box-shadow: none !important; 63 | } 64 | 65 | .program-jobcenter input, 66 | .program-jobcenter textarea, 67 | .program-jobcenter input:focus + label, 68 | .program-jobcenter textarea:focus + label { 69 | color: #00005a !important; 70 | } 71 | 72 | #jc-add-submit { 73 | background: #00005a; 74 | } 75 | 76 | #jc-add-form { 77 | display: none; 78 | } 79 | 80 | #jc-add-form form { 81 | margin-top: 20px; 82 | } 83 | 84 | #jc-add-form textarea { 85 | height: 100px; 86 | } 87 | 88 | #jc-search button { 89 | height: 35px; 90 | width: 102px; 91 | margin-left: -10px; 92 | background: #92eb42; 93 | padding: 10px; 94 | border: none; 95 | border-radius: 0 6px 6px 0; 96 | transition: all 0.2s ease; 97 | } 98 | 99 | #jc-search button:hover { 100 | background: #abff5c; 101 | } 102 | 103 | #jc-search button:active { 104 | color: #ffffff; 105 | background: #1616b2; 106 | } 107 | 108 | #jc-search form .material-icons { 109 | font-size: 18px; 110 | float: left; 111 | margin-right: -14px; 112 | } 113 | 114 | #jc-search span { 115 | display: none; 116 | color:#ffffff; 117 | } 118 | 119 | #jc-search span .material-icons { 120 | vertical-align: middle; 121 | margin-right: 10px; 122 | } 123 | 124 | #jc-search p { 125 | color: #ffffff; 126 | font-size: 16px; 127 | } 128 | 129 | #jc-list h6 { 130 | font-size: 20px; 131 | font-weight: 500; 132 | margin-bottom: 30px; 133 | } 134 | 135 | #jc-list h6 span { 136 | border-bottom: 4px solid #92eb42; 137 | } 138 | 139 | .jc-job { 140 | background: #ffffff; 141 | padding: 10px 10px 18px 10px; 142 | margin-bottom: 10px; 143 | display: inline-block; 144 | width: 49.3%; 145 | border: 1px solid transparent; 146 | } 147 | 148 | .jc-job:hover { 149 | /* background: rgb(247, 247, 247); */ 150 | border: 1px solid #424ae0; 151 | } 152 | 153 | .jc-job:nth-child(even) { 154 | float: right; 155 | } 156 | 157 | .jc-job img { 158 | width: 50px; 159 | height: 50px; 160 | max-width: 50px; 161 | max-height: 50px; 162 | float: left; 163 | margin-right: 10px; 164 | } 165 | 166 | .jc-job h5 { 167 | color: #00005a; 168 | font-weight: 400; 169 | font-size: 20px; 170 | margin: 0; 171 | } 172 | 173 | .jc-job p { 174 | font-size: 14px; 175 | } 176 | 177 | #jc-job { 178 | display: none; 179 | margin-top: 20px; 180 | } 181 | 182 | #jc-job-delete, 183 | #jc-job-save, 184 | #jc-job-edit { 185 | display: none; 186 | color: #00005a; 187 | float: right; 188 | } 189 | 190 | #jc-job-title { 191 | color: #00005a !important; 192 | font-weight: 400; 193 | font-size: 25px; 194 | margin: 0; 195 | } 196 | 197 | #jc-job-image, 198 | #jc-job-group { 199 | display: none; 200 | color: #00005a !important; 201 | font-weight: 400; 202 | font-size: 25px; 203 | margin: 0; 204 | } 205 | 206 | #jc-job-title:disabled { 207 | border: none !important; 208 | } 209 | 210 | #jc-job-job { 211 | color: #444444; 212 | font-size: 15px; 213 | margin: -10px 0 0 0; 214 | } 215 | 216 | #jc-job-job:disabled { 217 | border: none !important; 218 | } 219 | 220 | #jc-job-text { 221 | margin-top: 20px; 222 | resize: none; 223 | height: 600px; 224 | } 225 | 226 | #jc-search form { 227 | position: relative; 228 | } 229 | 230 | #jc-search-clear { 231 | position: absolute; 232 | top: 29px; 233 | right: 130px; 234 | font-size: 25px !important; 235 | } 236 | 237 | #jc-job-text:disabled { 238 | border: none; 239 | } 240 | 241 | #jc-add { 242 | float: right; 243 | display: none;; 244 | } 245 | 246 | .program-jobcenter input:focus, 247 | .program-jobcenter textarea:focus { 248 | border-bottom: 1px solid #00005a !important; 249 | box-shadow: none !important; 250 | } 251 | -------------------------------------------------------------------------------- /client/html/programs/jobcenter/jobcenter.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 14 |
15 |
16 |
0 jobs found add
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 | 35 |
36 |
37 | 38 | 39 |
40 |
41 | 42 | 43 |
44 |
45 | 46 |
47 |
48 |
49 |
50 |
51 | edit 52 | save 53 | delete 54 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |
62 |
63 | 64 | -------------------------------------------------------------------------------- /client/html/programs/jobcenter/jobcenter.js: -------------------------------------------------------------------------------- 1 | let jobs = {}; 2 | 3 | function fetchAllAds() { 4 | $('#jc-jobs').html(''); 5 | 6 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:fetchAllJobAds`, { 7 | method: 'POST', 8 | body: JSON.stringify({ 9 | type: 'fetchAllJobAds' 10 | }) 11 | }) 12 | .then( response => response.json() ) 13 | .then( data => { 14 | if ( data != 'false' && data.length > 0 ) { 15 | $('#jc-list h6 span').text( Object.keys( data ).length ); 16 | 17 | Object.keys( data ).forEach(( k ) => { 18 | if ( !data[k].title ) { 19 | data[k].title = 'This is a null title' 20 | } else { 21 | if ( data[k].title.length > 25 ) { 22 | data[k].title = data[k].title.substr(0, 25) + '..'; 23 | } 24 | } 25 | 26 | jobs[ data[k].id ] = { 27 | id: data[k].id, 28 | image: data[k].image, 29 | title: data[k].title, 30 | group: data[k].group, 31 | job: data[k].name, 32 | text: data[k].text 33 | }; 34 | 35 | let div = `
36 | 37 |
${ data[k].title }
38 |

${ data[k].name }

39 |
`; 40 | 41 | $('#jc-jobs').prepend( div ); 42 | }); 43 | } 44 | }); 45 | } 46 | 47 | function searchAds( keyword ) { 48 | Object.keys( jobs ).forEach(( k ) => { 49 | if ( jobs[k].job.toLowerCase().includes( keyword.toLowerCase() ) ) { 50 | $('#jc-jobs').html(''); 51 | 52 | let div = `
53 | 54 |
${ jobs[k].title }
55 |

${ jobs[k].job }

56 |
`; 57 | 58 | $('#jc-jobs').append( div ); 59 | } 60 | }); 61 | } 62 | 63 | function refreshjobcenter() { 64 | fetchAllAds(); 65 | } 66 | 67 | fetchAllAds(); 68 | 69 | if ( loggedInUser.job === 'all' || ( loggedInUser.group === 'admin' ) ) { 70 | $('#jc-add').css('display', 'block'); 71 | } 72 | 73 | $('#jc-add').click(()=> { 74 | $('#jc-search span').show(); 75 | $('#jc-search form').slideUp('fast'); 76 | 77 | $('#jc-list').fadeOut('fast', function() { 78 | $('#jc-add-form').fadeIn(); 79 | }); 80 | }); 81 | 82 | $('#jc-add-form form').submit(() => { 83 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:addJobAd`, { 84 | method: 'POST', 85 | body: JSON.stringify({ 86 | type: 'addJobAd', 87 | data: { 88 | '@group':$('#jc-add-group').val().toLowerCase(), 89 | '@name': $('#jc-add-name').val().toLowerCase(), 90 | '@image': $('#jc-add-image').val(), 91 | '@title': $('#jc-add-title').val(), 92 | '@text': $('#jc-add-text').val(), 93 | } 94 | }) 95 | }) 96 | .then(() => { 97 | setTimeout(() => { 98 | fetchAllAds(); 99 | $('#jc-search form').slideDown('fast'); 100 | $('#jc-search span').hide(); 101 | 102 | $('#jc-job, #jc-add-form').fadeOut('fast', function() { 103 | $('#jc-list').fadeIn(); 104 | }); 105 | }, 500); 106 | }); 107 | 108 | return false; 109 | }); 110 | 111 | $('body').on('click', '.jc-job', function() { 112 | let ad = $( this ).attr('identifier'); 113 | 114 | $('#jc-search span').show(); 115 | $('#jc-search form').slideUp('fast'); 116 | 117 | $('#jc-job-title').val( jobs[ad].title ); 118 | $('#jc-job-job').val( jobs[ad].job ); 119 | $('#jc-job-text').val( jobs[ad].text ); 120 | $('#jc-job-image').val( jobs[ad].image ); 121 | $('#jc-job-group').val( jobs[ad].group ); 122 | $('#jc-job-save').attr('identifier', ad); 123 | $('#jc-job-delete').attr('identifier', ad); 124 | 125 | if ( loggedInUser.job === 'all' || ( loggedInUser.job === jobs[ad].job && loggedInUser.group === 'admin' ) ) { 126 | $('#jc-job-edit').css('display', 'block'); 127 | } 128 | 129 | $('#jc-list').fadeOut('fast', function() { 130 | $('#jc-job').fadeIn(); 131 | }); 132 | }); 133 | 134 | $('#jc-search span').click(() => { 135 | $('#jc-search form').slideDown('fast'); 136 | $('#jc-search span').hide(); 137 | 138 | $('#jc-job, #jc-add-form').fadeOut('fast', function() { 139 | $('#jc-list').fadeIn(); 140 | }); 141 | }); 142 | 143 | function edit() { 144 | if ( $('#jc-job-save').css('display') === 'block' ) { 145 | $('#jc-job-save, #jc-job-image, #jc-job-group, #jc-job-delete').css('display', 'none'); 146 | } else { 147 | $('#jc-job-save, #jc-job-image, #jc-job-group, #jc-job-delete').css('display', 'block'); 148 | } 149 | 150 | $('#jc-job input, #jc-job textarea').attr('disabled', $('#jc-job input').attr('disabled') ? false : true); 151 | } 152 | 153 | $('#jc-job-delete').click( function() { 154 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:deleteJobAd`, { 155 | method: 'POST', 156 | body: JSON.stringify({ 157 | type: 'deleteJobAd', 158 | data: { 159 | '@id': $( this ).attr('identifier') 160 | } 161 | }) 162 | }) 163 | .then(() => { 164 | setTimeout(() => { 165 | fetchAllAds(); 166 | $('#jc-search form').slideDown('fast'); 167 | $('#jc-search span').hide(); 168 | 169 | $('#jc-job, #jc-add-form').fadeOut('fast', function() { 170 | $('#jc-list').fadeIn(); 171 | }); 172 | }, 500); 173 | }); 174 | }); 175 | 176 | $('#jc-job-edit').click(() => { 177 | edit(); 178 | }); 179 | 180 | $('#jc-job-save').click( function() { 181 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:updateJobAd`, { 182 | method: 'POST', 183 | body: JSON.stringify({ 184 | type: 'updateJobAd', 185 | data: { 186 | '@name': $('#jc-job-job').val(), 187 | '@text': $('#jc-job-text').val(), 188 | '@title': $('#jc-job-title').val(), 189 | '@image': $('#jc-job-image').val(), 190 | '@group': $('#jc-job-group').val(), 191 | '@id': $( this ).attr('identifier') 192 | } 193 | }) 194 | }) 195 | .then(() => { 196 | edit(); 197 | fetchAllAds(); 198 | }); 199 | }); 200 | 201 | $('#jc-search button').click(() => { 202 | if ($('#jc-search input').val().length > 0 ) { 203 | searchAds( $('#jc-search input').val() ); 204 | return false; 205 | } 206 | }) 207 | 208 | $('#jc-search form').submit(() => { 209 | searchAds( $('#jc-search input').val() ); 210 | return false; 211 | }); 212 | 213 | $('#jc-search-clear').click(() => { 214 | if ($('#jc-search input').val().length > 0 ) { 215 | $('#jc-search input').val(''); 216 | fetchAllAds(); 217 | } 218 | }); -------------------------------------------------------------------------------- /client/html/programs/mail/mail.css: -------------------------------------------------------------------------------- 1 | .program-mail-header { 2 | margin-bottom: -22px; 3 | color: #ffffff; 4 | position: relative; 5 | z-index: 10; 6 | } 7 | 8 | .program-mail { 9 | height: 100%; 10 | width: 100%; 11 | color: #000000; 12 | background: url(mail.jpg); 13 | } 14 | 15 | .program-mail-header .program-close, 16 | .program-mail-header .program-fullscreen, 17 | .program-mail-header .program-minimize, 18 | .program-mail-header .program-refresh { 19 | color: #000000 !important; 20 | } 21 | 22 | .icon-mail { 23 | background-position: -840px 0; 24 | } 25 | 26 | .icon-mail:hover { 27 | background-position: -840px -60px; 28 | } 29 | 30 | .icon-mail:active { 31 | background-position: -840px -120px; 32 | } 33 | 34 | .icon-mail-small { 35 | background-position: -852px -193px; 36 | } 37 | 38 | #mail-menu { 39 | position: absolute; 40 | top: 0; 41 | left: 0; 42 | color: #ffffff; 43 | background: url(../../assets/images/blurr-blue.png); 44 | width: 180px; 45 | height: 100%; 46 | text-align: left; 47 | z-index: 10; 48 | overflow: auto; 49 | } 50 | 51 | #mail-menu h6 { 52 | font-size: 15px; 53 | padding: 5px; 54 | margin: 0; 55 | } 56 | 57 | #mail-menu .material-icons { 58 | padding: 5px; 59 | } 60 | 61 | #mail-menu li { 62 | width: 180px; 63 | } 64 | 65 | .mail-menu-content:hover, 66 | #mail-menu .material-icons:hover, 67 | #mail-menu li:hover { 68 | background: rgba(255, 255, 255, 0.1); 69 | } 70 | 71 | #mail-menu li .material-icons { 72 | vertical-align: middle; 73 | } 74 | 75 | .mail-menu-content { 76 | padding: 5px 5px 5px 35px; 77 | border-left: 4px solid transparent; 78 | width: 180px; 79 | position: relative; 80 | } 81 | 82 | .active-email { 83 | border-left: 4px solid #ffffff !important; 84 | } 85 | 86 | .mail-unread-count { 87 | position: absolute; 88 | right: 10px; 89 | top: 10px; 90 | } 91 | 92 | .mail-menu-content p { 93 | font-size: 12px; 94 | } 95 | 96 | .mail-menu-content p:nth-child(odd) { 97 | font-weight: bold; 98 | font-size: 14px; 99 | } 100 | 101 | #mail-inbox { 102 | position: absolute; 103 | top: 0; 104 | left: 180px; 105 | background: #ffffff; 106 | width: 200px; 107 | height: 100%; 108 | border-right: 1px solid #eeeeee; 109 | overflow: auto; 110 | } 111 | 112 | #mail-menu::-webkit-scrollbar, 113 | #mail-inbox::-webkit-scrollbar { 114 | width: 0; 115 | background: transparent; 116 | } 117 | 118 | .mail-inbox-content { 119 | padding: 10px; 120 | border-bottom: 1px solid #eeeeee; 121 | border-left: 4px solid transparent; 122 | color: #5f5f5f; 123 | font-size: 12px; 124 | min-height: 75px 125 | } 126 | 127 | .mail-inbox-content:hover { 128 | background: #f3f3f3; 129 | } 130 | 131 | .mail-inbox-content img { 132 | float: left; 133 | margin-right: 5px; 134 | } 135 | 136 | .inbox-name, 137 | .inbox-title { 138 | color: #252525; 139 | } 140 | 141 | .inbox-unread { 142 | border-left: 4px solid #0e4c81; 143 | } 144 | 145 | .inbox-unread .inbox-name { 146 | font-weight: bold; 147 | } 148 | 149 | .inbox-unread .inbox-title { 150 | font-weight: bold; 151 | color: #135995; 152 | } 153 | 154 | .inbox-active { 155 | background: #ddedf9 !important; 156 | } 157 | 158 | #mail-email { 159 | display: none; 160 | position: absolute; 161 | top: 0; 162 | left: 380px; 163 | background: #ffffff; 164 | width: 100%; 165 | height: 100%; 166 | padding: 10px 10px 10px 10px; 167 | } 168 | 169 | #mail-email-header { 170 | margin-top: 15px; 171 | } 172 | 173 | #mail-email-header p { 174 | color: #444444; 175 | font-size: 12px; 176 | display: inline-block; 177 | padding: 4px 8px 4px 8px; 178 | } 179 | 180 | #mail-email-header p:hover { 181 | background: rgba(0, 0, 0, 0.1); 182 | } 183 | 184 | #mail-email-header .material-icons { 185 | vertical-align: middle; 186 | } 187 | 188 | #mail-email h6 { 189 | font-size: 15px; 190 | font-weight: bold; 191 | margin: 0 0 10px 0; 192 | } 193 | 194 | #mail-email-content { 195 | padding: 15px; 196 | } 197 | 198 | #mail-email-sender { 199 | margin-bottom: 20px; 200 | } 201 | 202 | #mail-email-sender img { 203 | float: left; 204 | margin-right: 10px; 205 | } 206 | 207 | #email-title { 208 | font-weight: bold; 209 | font-size: 10px; 210 | } 211 | 212 | #email-date { 213 | font-size: 12px; 214 | } 215 | 216 | #email-to { 217 | margin-top: 15px; 218 | font-size: 14px; 219 | } 220 | 221 | #mail-send { 222 | display: none; 223 | position: absolute; 224 | top: 0; 225 | left: 380px; 226 | background: #ffffff; 227 | width: 100%; 228 | height: 100%; 229 | padding: 10px 10px 10px 10px; 230 | overflow: auto; 231 | } 232 | 233 | #mail-send form { 234 | margin-top: 35px; 235 | } 236 | 237 | #mail-send input { 238 | width: 361px; 239 | height: 15px; 240 | border-bottom: 1px solid #c9c9c9; 241 | box-shadow: none !important; 242 | } 243 | 244 | #mail-send input:focus { 245 | border-bottom: 1px solid #c9c9c9; 246 | box-shadow: none !important; 247 | } 248 | 249 | #mail-send-text { 250 | position: absolute; 251 | top: 187px; 252 | left: 10px; 253 | width: 399px; 254 | resize: none; 255 | border: none; 256 | height: 500px; 257 | } 258 | 259 | #mail-send-text:focus { 260 | outline: none; 261 | } 262 | 263 | .input-wrapper { 264 | position: relative; 265 | } 266 | 267 | #mail-send-from { 268 | padding-left: 40px !important; 269 | } 270 | 271 | #mail-send-to { 272 | padding-left: 20px !important; 273 | width: 380px !important; 274 | } 275 | 276 | #mail-send-title { 277 | width: 399px !important; 278 | } 279 | 280 | .input-wrapper span { 281 | position: absolute; 282 | left: 0; 283 | top: 0; 284 | } 285 | 286 | .changeFolder { 287 | font-size: 12px; 288 | padding: 5px 5px 5px 35px; 289 | border-left: 4px solid transparent; 290 | } 291 | 292 | .active-folder { 293 | border-left: 4px solid #ffffff !important; 294 | } 295 | 296 | #mail-folder-menu { 297 | display: none; 298 | z-index: 10; 299 | position: absolute; 300 | background: #efefef; 301 | height: 100%; 302 | width: 110px; 303 | left: 180px; 304 | top: 0; 305 | padding: 10px; 306 | } 307 | 308 | #mail-folder-menu li:first-child { 309 | margin-bottom: 10px; 310 | } 311 | 312 | #mail-folder-menu .changeFolder { 313 | padding: 0; 314 | float: left; 315 | width: 130px; 316 | } 317 | 318 | #mail-send-header { 319 | width: 399px; 320 | background: #f7f7f7; 321 | padding: 5px; 322 | margin-bottom: 15px; 323 | } 324 | 325 | #mail-send-header li { 326 | display: inline-block; 327 | } 328 | 329 | #mail-send-header .material-icons { 330 | font-size: 20px; 331 | vertical-align: middle; 332 | } 333 | 334 | #mail-send-delete { 335 | margin-right: 10px; 336 | } 337 | 338 | #mail-send-submit, 339 | #mail-send-delete, 340 | .mail-send-option { 341 | padding: 5px; 342 | } 343 | 344 | #mail-send-submit:hover, 345 | #mail-send-delete:hover, 346 | .mail-send-option:hover { 347 | background: #e6e6e6; 348 | } 349 | 350 | #mail-inbox-junk, 351 | #mail-inbox-deleted, 352 | #mail-inbox-sent { 353 | display: none; 354 | } 355 | 356 | #email-text { 357 | white-space: pre; 358 | } 359 | 360 | #email-name { 361 | font-size: 14px; 362 | font-weight: bold; 363 | } 364 | 365 | #mail-register { 366 | display: none; 367 | background: #0078d7; 368 | position: absolute; 369 | top: 0; 370 | left: 0; 371 | width: 100%; 372 | height: 100%; 373 | text-align: center; 374 | padding-top: 15%; 375 | } 376 | 377 | #mail-register h6 { 378 | color: #f3f3f3; 379 | margin-bottom: 10px; 380 | } 381 | 382 | #mail-register input { 383 | text-align: right; 384 | color:#ffffff; 385 | border-bottom: 1px solid #ffffff; 386 | box-shadow: none; 387 | } 388 | 389 | #mail-register .textleft { 390 | text-align: left; 391 | } 392 | 393 | #mail-register p { 394 | color:#ffffff; 395 | margin-top: 12px; 396 | } 397 | 398 | .program-mail .invalid { 399 | border-bottom: 1px solid red !important; 400 | box-shadow: 0 1px 0 0 red !important; 401 | } 402 | 403 | .program-mail .valid { 404 | border-bottom: 1px solid green !important; 405 | box-shadow: 0 1px 0 0 green !important; 406 | } -------------------------------------------------------------------------------- /client/html/programs/mail/mail.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
Welcome!
5 |
6 |
7 |
8 |
9 | 10 |

@

11 | 12 |
13 |
14 | 15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
Mail
23 | menu 24 |
    25 |
  • addSend
  • 26 |
27 |
28 |
    29 |
  • folder_openFolders
  • 30 |
  • Inbox
  • 31 |
  • Sent
  • 32 |
  • Junk
  • 33 |
  • Deleted
  • 34 |
35 |
36 |
37 |
    38 |
  • All folders
  • 39 |
  • Inbox
  • 40 |
  • Sent
  • 41 |
  • Junk
  • 42 |
  • Deleted
  • 43 |
44 |
45 |
46 |
47 | 48 |
49 |
50 | 51 |
52 |
53 | 54 |
55 |
56 | 57 |
58 |
59 |
60 |
61 |
62 |
    63 |
  • format_bold
  • 64 |
  • format_italic
  • 65 |
  • format_underline
  • 66 |
  • border_color
  • 67 |
  • format_color_text
  • 68 |
  • sendSend
  • 69 |
70 |
71 |
72 | 73 | From: 74 |
75 |
76 | 77 | To: 78 |
79 | 80 | 81 |
82 |
83 |
84 |
85 |

replyreply

86 |

arrow_forwardforward

87 |

deletedelete

88 |

flagflag

89 |
90 |
91 |
92 |
93 | 94 |

95 |

96 |

To:

97 |
98 |

99 |
100 |
101 |
102 |
103 |
104 | 105 | -------------------------------------------------------------------------------- /client/html/programs/mail/mail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/programs/mail/mail.jpg -------------------------------------------------------------------------------- /client/html/programs/medicalrecords/medicalrecords.css: -------------------------------------------------------------------------------- 1 | .program-medicalrecords-header { 2 | background: #466bd1; 3 | color: #ffffff; 4 | } 5 | 6 | .program-medicalrecords { 7 | height: 100%; 8 | width: 100%; 9 | color: #466bd1; 10 | background: #f1f1f1; 11 | } 12 | 13 | .icon-medicalrecords { 14 | background-position: 0 0; 15 | } 16 | 17 | .icon-medicalrecords:hover { 18 | background-position: 0 -60px; 19 | } 20 | 21 | .icon-medicalrecords:active { 22 | background-position: 0 -120px; 23 | } 24 | 25 | .icon-medicalrecords-small { 26 | background-position: -11px -193px; 27 | } 28 | 29 | .program-medicalrecords .input-field .material-icons { 30 | position: absolute; 31 | right: 10px; 32 | top: 10px; 33 | } 34 | 35 | .program-medicalrecords .input-field .material-icons:nth-child(even) { 36 | right: 30px; 37 | } 38 | 39 | .program-medicalrecords input, 40 | .program-medicalrecords input + label, 41 | .program-medicalrecords textarea, 42 | .program-medicalrecords textarea + label { 43 | color: #466bd1 !important; 44 | } 45 | 46 | .program-medicalrecords .input-field input, 47 | .program-medicalrecords .input-field textarea { 48 | border-bottom: 1px solid #466bd1 !important; 49 | box-shadow: none !important; 50 | } 51 | 52 | .program-medicalrecords .input-field input:focus, 53 | .program-medicalrecords textarea:focus { 54 | border-bottom: 1px solid #466bd1 !important; 55 | box-shadow: none !important; 56 | } 57 | 58 | .program-medicalrecords input:focus + label, 59 | .program-medicalrecords textarea:focus + label { 60 | color: #466bd1 !important; 61 | } 62 | 63 | .program-medicalrecords textarea { 64 | height: 150px; 65 | } 66 | 67 | .search-record { 68 | padding: 5px 10px 5px 10px; 69 | margin-bottom: 10px; 70 | background: #466bd1; 71 | color: #ffffff; 72 | } 73 | 74 | .search-record:hover, 75 | .program-medicalrecords button:hover { 76 | background: #3c5cb4; 77 | } 78 | 79 | .search-record:active, 80 | .program-medicalrecords button:active, 81 | .program-medicalrecords button:focus { 82 | background: #334f9b; 83 | } 84 | 85 | .program-medicalrecords .input-field input.invalid { 86 | border-bottom: 1px solid red !important; 87 | box-shadow: 0 1px 0 0 red !important; 88 | } 89 | 90 | .program-medicalrecords .input-field input.valid { 91 | border-bottom: 1px solid green !important; 92 | box-shadow: 0 1px 0 0 green !important; 93 | } 94 | 95 | .search-record .records { 96 | float: right; 97 | } 98 | 99 | .search-record .records p { 100 | font-size: 11px; 101 | line-height: 14px; 102 | display: inline-block; 103 | vertical-align: middle; 104 | } 105 | 106 | .search-record .records .material-icons { 107 | font-size: 14px; 108 | } 109 | 110 | .sr-dob { 111 | font-size: 12px; 112 | } 113 | 114 | .medicalrecords-add, 115 | .medicalrecords-record { 116 | display: none; 117 | } 118 | 119 | .medicalrecords-menu { 120 | position: absolute; 121 | top: 22px; 122 | left: 0; 123 | height: 100%; 124 | background: #e7e7e7; 125 | color: #444444; 126 | } 127 | 128 | .medicalrecords-menu .material-icons { 129 | padding: 8px 5px 8px 5px; 130 | display: list-item; 131 | } 132 | 133 | .program-medicalrecords button { 134 | background: #466bd1; 135 | } 136 | 137 | .mb { 138 | margin-bottom: 40px; 139 | } 140 | 141 | .medicalrecords-record .collapsible-header { 142 | position: relative; 143 | } 144 | 145 | .medicalrecords-record .collapsible-header p:nth-child(even) { 146 | position: absolute; 147 | right: 4rem; 148 | } 149 | 150 | .medicalrecords-record .collapsible-header .material-icons { 151 | position: absolute; 152 | right: 0; 153 | color: #d14646; 154 | } 155 | 156 | .medicalrecords-record .collapsible-body { 157 | color: #444444; 158 | position: relative; 159 | } 160 | 161 | .medicalrecords-record .collapsible-body p:nth-child(even) { 162 | white-space: pre-wrap; 163 | } 164 | 165 | .medicalrecords-record .collapsible-body p:nth-child(odd) { 166 | position: absolute; 167 | top: 0; 168 | right: 1rem; 169 | font-size: 12px; 170 | color: #466bd1; 171 | } 172 | 173 | .medicalrecords-record h6 { 174 | line-height: 20px; 175 | } 176 | 177 | .medicalrecords-record h6 .material-icons { 178 | margin-top: -6px; 179 | vertical-align: middle; 180 | } 181 | 182 | .mr-back { 183 | position: absolute; 184 | left: 10%; 185 | top: 35px; 186 | } -------------------------------------------------------------------------------- /client/html/programs/medicalrecords/medicalrecords.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | search 5 | list_alt 6 | add 7 |
8 |
9 |
10 | 25 |
26 | arrow_back 27 |
28 |
29 |
30 | 31 | 32 |
33 |
34 | 35 | 36 |
37 |
38 | 39 | 40 |
41 |
42 | 43 | 44 |
45 |
46 | 47 | 48 |
49 |
50 | 51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /client/html/programs/medicalrecords/medicalrecords.js: -------------------------------------------------------------------------------- 1 | if ( !jsloaded.includes('medicalrecords') ) { 2 | let _page = '.medicalrecords-search'; 3 | let _record = false; 4 | let _data = 'null'; 5 | 6 | jsloaded.push('medicalrecords'); 7 | 8 | function fetchUserRecords( type, data, open ) { 9 | let fetchType = 'medicalrecordsFetchAll'; 10 | let rows = {}; 11 | 12 | if ( type === 'user' ) { 13 | fetchType = 'medicalrecordsFetchUser'; 14 | 15 | let d = data.split(' '); 16 | 17 | rows['@firstname'] = d[0]; 18 | rows['@lastname'] = d[1]; 19 | rows['@dob'] = d[2]; 20 | 21 | $( _page ).fadeOut('fast', () => { 22 | _page = '.medicalrecords-record'; 23 | $( _page ).fadeIn(); 24 | }); 25 | } 26 | 27 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:${ fetchType }`, { 28 | method: 'POST', 29 | body: JSON.stringify({ 30 | type: fetchType, 31 | data: rows 32 | }) 33 | }) 34 | .then( response => response.json() ) 35 | .then( data => { 36 | if ( data != 'false' && data.length > 0 ) { 37 | if ( type === 'user' ) { 38 | $( `#${ device }-frame .medicalrecords-record` ).html( ' ' ); 39 | $( `#${ device }-frame .medicalrecords-record` ).append(`arrow_back
${ rows['@firstname'] } ${ rows['@lastname'] } (${ rows['@dob'] }) Records add
`); 40 | 41 | Object.keys( data ).forEach(( k ) => { 42 | let li = ` 43 |
  • 44 |
    45 |

    ${ data[k].title }

    46 |

    ${ data[k].date }

    47 | delete 48 |
    49 |
    50 |

    ${ data[k].uploader }

    51 |

    ${ data[k].text }

    52 |
    53 |
  • `; 54 | 55 | $( `#${ device }-frame .medicalrecords-record` ).find('.collapsible').append( li ); 56 | }); 57 | 58 | $('.collapsible').collapsible(); 59 | } else { 60 | $( `#${ device }-frame .medicalrecords-result` ).html( ' ' ); 61 | 62 | Object.keys( data ).forEach(( k ) => { 63 | let elem = `
    64 |
    65 |
    66 |

    ${ data[k].count }

    67 |

    list_alt

    68 |
    69 |

    ${ data[k].name.split(' ')[0] } ${ data[k].name.split(' ')[1] }

    70 |

    ${ data[k].dob }

    71 |
    72 |
    `; 73 | 74 | $( `#${ device }-frame .medicalrecords-result` ).append( elem ); 75 | }); 76 | } 77 | 78 | if ( open ) { 79 | $( `#${ device }-frame .medicalrecords-record` ).find('.collapsible').collapsible('open', 0); 80 | } 81 | } 82 | }); 83 | } 84 | 85 | function searchRecords() { 86 | let search = $( `#${ device }-frame .medicalrecords-search-input` ).val(); 87 | 88 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:medicalrecordsSearch`, { 89 | method: 'POST', 90 | body: JSON.stringify({ 91 | type: 'medicalrecordsSearch', 92 | data: { 93 | '@firstname': search, 94 | '@lastname': search, 95 | '@dob': search 96 | } 97 | }) 98 | }) 99 | .then( response => response.json() ) 100 | .then( data => { 101 | if ( data != 'false' && data.length > 0 ) { 102 | $( `#${ device }-frame .medicalrecords-result` ).html( ' ' ); 103 | Object.keys( data ).forEach(( k ) => { 104 | let elem = `
    105 |
    106 |
    107 |

    ${ data[k].count }

    108 |

    list_alt

    109 |
    110 |

    ${ data[k].name.split(' ')[0] } ${ data[k].name.split(' ')[1] }

    111 |

    ${ data[k].dob }

    112 |
    113 |
    `; 114 | 115 | $( `#${ device }-frame .medicalrecords-result` ).append( elem ); 116 | }); 117 | } else { 118 | $( `#${ device }-frame .medicalrecords-search-input` ).addClass('invalid'); 119 | 120 | setTimeout(() => { 121 | $( `#${ device }-frame .medicalrecords-search-input` ).removeClass('invalid'); 122 | }, 2000); 123 | } 124 | }); 125 | } 126 | 127 | function refreshmedicalrecords() { 128 | if ( _page === '.medicalrecords-record' ) { 129 | fetchUserRecords( 'user', _data ); 130 | } 131 | 132 | fetchUserRecords( 'all' ); 133 | } 134 | 135 | fetchUserRecords( 'all' ); 136 | 137 | $('.mr-search').click(() => { 138 | if ( $('.medicalrecords-search-input').val().length > 0 ) { 139 | searchRecords(); 140 | } 141 | }); 142 | 143 | $('.mr-clear').click(() => { 144 | $('.medicalrecords-search-input').val(''); 145 | 146 | M.updateTextFields(); 147 | 148 | fetchUserRecords( 'all' ); 149 | }); 150 | 151 | $('body').on('click', '.mr-delete', function () { 152 | let id = $(this).attr('identifier'); 153 | 154 | $( this ).closest('li').remove(); 155 | 156 | let len = $('.medicalrecords-record .collapsible li').length; 157 | 158 | if ( len === 0 ) { 159 | $('.medicalrecords-record .collapsible').remove(); 160 | } 161 | 162 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:medicalrecordsDelete`, { 163 | method: 'POST', 164 | body: JSON.stringify({ 165 | type: 'medicalrecordsDelete', 166 | data: { 167 | '@id': id 168 | } 169 | }) 170 | }) 171 | .then(() => { 172 | fetchUserRecords( 'all' ); 173 | }); 174 | }); 175 | 176 | $('body').on('click', '.mr-back', function () { 177 | $( _page ).fadeOut('fast', () => { 178 | _page = '.medicalrecords-search'; 179 | fetchUserRecords( 'all' ); 180 | $( _page ).fadeIn(); 181 | }); 182 | }); 183 | 184 | $('body').on('click', '.mr-add-shortcut', function () { 185 | $( _page ).fadeOut('fast', () => { 186 | _page = '.medicalrecords-add'; 187 | 188 | let data = _data.split(' '); 189 | 190 | $('.medicalrecords-add-firstname').val( data[0] ); 191 | $('.medicalrecords-add-lastname').val( data[1] ); 192 | $('.medicalrecords-add-dob').val( data[2] ); 193 | 194 | M.updateTextFields(); 195 | 196 | $( _page ).fadeIn(); 197 | }); 198 | }); 199 | 200 | $('body').on('click', '.medicalrecords-page', function () { 201 | let page = $( this ).attr( 'page' ); 202 | 203 | if ( $( this ).attr( 'load' ) ) { 204 | let data = `${ $( this ).attr( 'firstname' ) } ${ $( this ).attr( 'lastname' ) } ${ $( this ).attr( 'dob' ) }`; 205 | 206 | if ( _data != data ) { 207 | _data = data; 208 | fetchUserRecords( 'user', _data ); 209 | $('.medicalrecords-search-input').val(''); 210 | fetchUserRecords( 'all' ); 211 | } 212 | } 213 | 214 | if ( page != _page && $( page ).contents().length > 1 ) { 215 | $( _page ).fadeOut('fast', () => { 216 | _page = page; 217 | $( _page ).fadeIn(); 218 | }); 219 | } 220 | }); 221 | 222 | $('.medicalrecords-search-form').submit(() => { 223 | searchRecords(); 224 | 225 | return false; 226 | }); 227 | 228 | $('.medicalrecords-add-form').submit(() => { 229 | let inputs = $(`#${ device }-frame .medicalrecords-add-form`).find('input'); 230 | let rows = {}; 231 | 232 | rows['@text'] = $(`#${ device }-frame .medicalrecords-add-form`).find('textarea').val(); 233 | rows['@date'] = getDate(); 234 | rows['@uploader'] = `${ loggedInUser.firstname } ${ loggedInUser.lastname }`; 235 | 236 | for ( let i = 0; i < inputs.length; i++ ) { 237 | if ( inputs.eq(i).val() ) { 238 | rows[`@${ inputs.eq(i).attr('class').split('-')[2] }`] = inputs.eq(i).val().toLowerCase(); 239 | } 240 | } 241 | 242 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:medicalrecordsAdd`, { 243 | method: 'POST', 244 | body: JSON.stringify({ 245 | type: 'medicalrecordsAdd', 246 | data: rows 247 | }) 248 | }) 249 | .then( () => { 250 | $(`#${ device }-frame .medicalrecords-add-form input, #${ device }-frame .medicalrecords-add-form textarea`).addClass( 'valid' ); 251 | 252 | setTimeout(() => { 253 | fetchUserRecords( 'all' ); 254 | 255 | let d = `${ $(`#${ device }-frame .medicalrecords-add-firstname`).val() } ${ $(`#${ device }-frame .medicalrecords-add-lastname`).val() } ${ $(`#${ device }-frame .medicalrecords-add-dob`).val() }` 256 | 257 | fetchUserRecords( 'user', d, true ); 258 | 259 | $(`#${ device }-frame .medicalrecords-add-form input`).val(''); 260 | $(`#${ device }-frame .medicalrecords-add-form textarea`).val(''); 261 | 262 | $( '.valid' ).removeClass( 'valid' ); 263 | 264 | M.updateTextFields(); 265 | 266 | $( _page ).fadeOut('fast', () => { 267 | _page = '.medicalrecords-record'; 268 | $( _page ).fadeIn(); 269 | }); 270 | }, 1500); 271 | }); 272 | 273 | return false; 274 | }); 275 | } 276 | -------------------------------------------------------------------------------- /client/html/programs/programConfig.js: -------------------------------------------------------------------------------- 1 | const programs = { 2 | 'account': { 3 | 'title': 'Account', // Title in the left corner of the program 4 | 'icons': { // Icon options 5 | start: true, // Start menu icon 6 | desktop: false, // Desktop icon 7 | taskbar: true // Taskbar icon 8 | }, 9 | 'options': { // Program window options 10 | allowMinimize: true, // Minimze window 11 | allowResize: true, // Toggle fullscreen 12 | allowRefresh: false // Enables the refresh function, calls the programs refresh function: refreshprogram() where the program is the name, in this case refreshaccount() 13 | }, 14 | 'access': { // Allowed jobs and group. 15 | group: 'all', // Allowed group. admin, user, all, null 16 | job: ['all'] // Allowed job, if set to 'all' every job will see it 17 | }, 18 | 'onStart': { // When the program loads in this will run.. 19 | fullscreen: true // Only currently used to start the program in fullscreen or not 20 | }, 21 | 'tablet': false // Allows the program to be accessed through the tablet if set to true 22 | }, 23 | 'groups': { 24 | 'title': 'Groups', 25 | 'icons': { 26 | start: true 27 | }, 28 | 'options': { 29 | allowMinimize: true, 30 | allowResize: true, 31 | allowRefresh: true 32 | }, 33 | 'access': { 34 | group: 'admin', 35 | job: ['all'] 36 | }, 37 | 'onStart': { 38 | fullscreen: true 39 | } 40 | }, 41 | 'medicalrecords': { 42 | 'title': 'Medical Records', 43 | 'icons': { 44 | desktop: true 45 | }, 46 | 'options': { 47 | allowResize: true, 48 | allowMinimize: true, 49 | allowRefresh: true 50 | }, 51 | 'access': { 52 | group: 'all', 53 | job: ['ambulance'] 54 | }, 55 | 'onStart': { 56 | fullscreen: true 57 | }, 58 | 'tablet': true 59 | }, 60 | 'cardealer': { 61 | 'title': 'Car dealer', 62 | 'icons': { 63 | desktop: true 64 | }, 65 | 'options': { 66 | allowMinimize: true 67 | }, 68 | 'access': { 69 | group: 'null', 70 | job: ['all'] 71 | }, 72 | 'onStart': { 73 | fullscreen: true 74 | } 75 | }, 76 | 'forum': { 77 | 'title': 'Forum', 78 | 'icons': { 79 | desktop: true 80 | }, 81 | 'options': { 82 | allowMinimize: true, 83 | allowRefresh: true, 84 | allowResize: true 85 | }, 86 | 'access': { 87 | group: 'all', 88 | job: ['police', 'ambulance'] 89 | }, 90 | 'onStart': { 91 | fullscreen: true 92 | } 93 | }, 94 | 'twitter': { 95 | 'title': 'Twitter', 96 | 'icons': { 97 | desktop: true 98 | }, 99 | 'options': { 100 | allowMinimize: true, 101 | allowResize: true 102 | }, 103 | 'access': { 104 | group: 'all', 105 | job: ['all'] 106 | }, 107 | 'onStart': { 108 | fullscreen: true 109 | } 110 | }, 111 | 'bossactions': { 112 | 'title': 'Employees', 113 | 'icons': { 114 | desktop: true 115 | }, 116 | 'options': { 117 | allowMinimize: true, 118 | allowResize: true, 119 | allowRefresh: true 120 | }, 121 | 'access': { 122 | group: 'admin', 123 | job: ['all'] 124 | }, 125 | 'onStart': { 126 | fullscreen: true 127 | }, 128 | 'ESX': true 129 | }, 130 | 'calcylator': { 131 | 'title': 'Calcylator', 132 | 'options': { 133 | allowMinimize: true 134 | }, 135 | 'icons': { 136 | start: true 137 | }, 138 | 'access': { 139 | group: 'all', 140 | job: ['all'] 141 | }, 142 | 'onStart': { 143 | width: '180px', 144 | height: '295px' 145 | } 146 | }, 147 | 'jobcenter': { 148 | 'title': 'Job Center', 149 | 'options': { 150 | allowMinimize: true, 151 | allowResize: true, 152 | allowRefresh: true 153 | }, 154 | 'icons': { 155 | desktop: true 156 | }, 157 | 'access': { 158 | group: 'all', 159 | job: ['all'] 160 | }, 161 | 'onStart': { 162 | fullscreen: true 163 | } 164 | }, 165 | 'terminal': { 166 | 'title': 'Terminal', 167 | 'options': { 168 | allowMinimize: true 169 | }, 170 | 'icons': { 171 | start: true 172 | }, 173 | 'access': { 174 | group: 'all', 175 | job: ['all'] 176 | }, 177 | 'onStart': { 178 | width: '500px', 179 | height: '300px' 180 | } 181 | }, 182 | 'folder': { 183 | 'title': 'Folder', 184 | 'options': { 185 | allowMinimize: true, 186 | allowResize: true 187 | }, 188 | 'icons': { 189 | desktop: true 190 | }, 191 | 'access': { 192 | group: 'all', 193 | job: ['all'] 194 | }, 195 | 'onStart': { 196 | width: '600px', 197 | height: '350px', 198 | iconDroppable: true 199 | } 200 | }, 201 | 'mail': { 202 | 'title': 'Mail', 203 | 'options': { 204 | allowMinimize: true, 205 | allowResize: true, 206 | allowRefresh: true 207 | }, 208 | 'icons': { 209 | start: true 210 | }, 211 | 'access': { 212 | group: 'all', 213 | job: ['all'] 214 | }, 215 | 'onStart': { 216 | fullscreen: false 217 | } 218 | }, 219 | 'controlpanel': { 220 | 'title': 'Control Panel', 221 | 'icons': { 222 | start: true 223 | }, 224 | 'options': { 225 | allowMinimize: true, 226 | allowResize: true 227 | }, 228 | 'access': { 229 | group: 'all', 230 | job: ['all'] 231 | }, 232 | 'onStart': { 233 | fullscreen: false 234 | } 235 | }, 236 | 'settings': { 237 | 'title': 'Settings', 238 | 'options': { 239 | allowMinimize: true 240 | }, 241 | 'access': { 242 | group: 'all', 243 | job: ['all'] 244 | }, 245 | 'onStart': { 246 | fullscreen: false, 247 | width: '610px', 248 | height: '450px', 249 | top: '50px', 250 | right: '50px' 251 | } 252 | }, 253 | } -------------------------------------------------------------------------------- /client/html/programs/settings/settings.css: -------------------------------------------------------------------------------- 1 | .program-settings-header { 2 | margin-bottom: -22px; 3 | color: #ffffff; 4 | position: relative; 5 | z-index: 10; 6 | } 7 | 8 | .program-settings-header .program-close, 9 | .program-settings-header .program-fullscreen, 10 | .program-settings-header .program-minimize, 11 | .program-settings-header .program-refresh { 12 | color: #000000 !important; 13 | } 14 | 15 | .program-settings { 16 | height: 100%; 17 | width: 100%; 18 | color: #000000; 19 | } 20 | 21 | .icon-settings { 22 | background-position: -960px 0; 23 | } 24 | 25 | .icon-settings:hover { 26 | background-position: -960px -60px; 27 | } 28 | 29 | .icon-settings:active { 30 | background-position: -960px -120px; 31 | } 32 | 33 | .icon-settings-small { 34 | background-position: -972px -193px; 35 | } 36 | 37 | #settings-menu { 38 | opacity: 0.95; 39 | position: absolute; 40 | left: 0; 41 | top: 0; 42 | height: 100%; 43 | width: 190px; 44 | background: url(../../assets/images/blurr-dark.png) 45 | } 46 | 47 | #settings-menu h6 { 48 | font-size: 12px; 49 | color: #ffffff; 50 | margin: 0; 51 | padding: 10px; 52 | } 53 | 54 | #settings-menu ul { 55 | margin-top: 40px; 56 | position: relative; 57 | } 58 | 59 | #settings-menu li { 60 | width: 100%; 61 | height: 35px; 62 | border-left: 4px solid transparent; 63 | } 64 | 65 | #settings-menu .active-tab { 66 | border-left: 4px solid #039be5; 67 | } 68 | 69 | #settings-menu li:hover { 70 | background-color: rgba(255, 255, 255, 0.2); 71 | } 72 | 73 | #settings-menu li:active { 74 | background-color: rgba(255, 255, 255, 0.3); 75 | } 76 | 77 | #settings-menu li span:nth-child(odd) { 78 | float: left; 79 | } 80 | 81 | #settings-menu li span:nth-child(even) { 82 | color: #ffffff; 83 | font-size: 12px; 84 | line-height: 35px; 85 | } 86 | 87 | #settings-content { 88 | position: absolute; 89 | top: 0; 90 | background: #ffffff; 91 | width: 100%; 92 | height: 100%; 93 | margin-left: 190px; 94 | } 95 | 96 | .icons-system-home { 97 | background-position: -105px -175px; 98 | } 99 | 100 | .icons-system-vpn { 101 | background-position: -105px 0px; 102 | } 103 | 104 | .icons-system-proxy { 105 | background-position: -105px -35px; 106 | } 107 | 108 | .icons-system-status { 109 | background-position: -105px -70px; 110 | } 111 | 112 | .icons-system-remote-connection { 113 | background-position: -105px -140px; 114 | } 115 | 116 | .icons-system-data-usage { 117 | background-position: -105px -105px; 118 | } -------------------------------------------------------------------------------- /client/html/programs/settings/settings.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
      5 |
    • 6 | 7 | Home 8 |
    • 9 |
      Network & Internet
      10 |
    • 11 | 12 | Status 13 |
    • 14 |
    • 15 | 16 | Ethernet 17 |
    • 18 |
    • 19 | 20 | Remote connection 21 |
    • 22 |
    • 23 | 24 | VPN 25 |
    • 26 |
    • 27 | 28 | Data usage 29 |
    • 30 |
    • 31 | 32 | Proxy 33 |
    • 34 |
    35 |
    36 |
    37 | 38 |
    39 |
    40 |
    41 | 42 | -------------------------------------------------------------------------------- /client/html/programs/settings/settings.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/programs/settings/settings.js -------------------------------------------------------------------------------- /client/html/programs/template/template.css: -------------------------------------------------------------------------------- 1 | .program-records-header { 2 | background: rgb(167, 167, 167); 3 | color: #ffffff; 4 | } 5 | 6 | .program-records { 7 | height: 100%; 8 | width: 100%; 9 | color: #000000; 10 | background: rgb(253, 253, 255); 11 | } 12 | 13 | .icon-records { 14 | background-position: -420px 0; 15 | } 16 | 17 | .icon-records:hover { 18 | background-position: -420px -60px; 19 | } 20 | 21 | .icon-records:active { 22 | background-position: -420px -120px; 23 | } 24 | 25 | .icon-records-small { 26 | background-position: -420px -193px; 27 | } -------------------------------------------------------------------------------- /client/html/programs/template/template.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    template
    6 |
    7 |
    8 |
    9 |
    10 | 11 | -------------------------------------------------------------------------------- /client/html/programs/template/template.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonassvensson4/jsfour-computer/6e229a262bc9982141e0f20d32314910284dabb5/client/html/programs/template/template.js -------------------------------------------------------------------------------- /client/html/programs/terminal/terminal.css: -------------------------------------------------------------------------------- 1 | .program-terminal-header { 2 | background: #ffffff; 3 | color: #000000; 4 | } 5 | 6 | .program-terminal { 7 | height: 100%; 8 | width: 100%; 9 | color: #e4e4e4; 10 | background: #000000; 11 | font-size: 12px; 12 | } 13 | 14 | .program-terminal .program-content { 15 | height: 276px; 16 | } 17 | 18 | .icon-terminal { 19 | background-position: -720px 0; 20 | } 21 | 22 | .icon-terminal:hover { 23 | background-position: -720px -60px; 24 | } 25 | 26 | .icon-terminal:active { 27 | background-position: -720px -120px; 28 | } 29 | 30 | .icon-terminal-small { 31 | background-position: -731px -193px; 32 | } 33 | 34 | #t-text span { 35 | margin-left: 20px; 36 | } 37 | 38 | #t-input span { 39 | float: left; 40 | } 41 | 42 | #t-input input { 43 | width: 50%; 44 | height: 18px; 45 | float: left; 46 | font-size: 12px; 47 | color: #ffffff; 48 | border: none !important; 49 | } 50 | 51 | #t-input input:active, 52 | #t-input input:focus { 53 | border: none !important; 54 | box-shadow: none !important; 55 | outline: none !important; 56 | } 57 | 58 | #t-input input::selection { 59 | color: #000000; 60 | background: #ffffff; 61 | } -------------------------------------------------------------------------------- /client/html/programs/terminal/terminal.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    Microsoft Windows [Version 10.0.17134.885]

    4 |

    (c) 2018 Microsoft Corporation.


    5 |
    6 | 7 |
    8 |
    9 | C:\Users\> 10 | 11 | 12 |
    13 |
    14 |
    15 | 16 | -------------------------------------------------------------------------------- /client/html/programs/terminal/terminal.js: -------------------------------------------------------------------------------- 1 | let tHeight = 0; 2 | 3 | $('#t-text').empty(); 4 | 5 | function terminalText( text ) { 6 | let texts = text.split(','); 7 | 8 | for (let i = 0; i < texts.length; i++) { 9 | $('#t-text').append( `

    ${ texts[i] }

    ` ); 10 | tHeight += 22; 11 | } 12 | 13 | $('.program-terminal .program-content').animate({ scrollTop: tHeight }); 14 | } 15 | 16 | function wrongCommand() { 17 | terminalText('Wrong command.. Use help'); 18 | } 19 | 20 | function terminalCmd( cmds ) { 21 | let cmd = cmds.split(' '); 22 | 23 | terminalText( `${ $('#t-input span').text() + cmd[0]}
    ` ); 24 | 25 | switch( cmd[0] ) { 26 | case 'ipconfig': 27 | if ( cmd[1] && cmd[1] === '/all' ) { 28 | terminalText(`Ethernet adapter Ethernet:
    , 29 | Connection-specific DNS Suffix . : lan, 30 | Description. . . . . . . . . . . . . . . . . . . : Realtek PCIe GBE Family Controller, 31 | Physical Address . . . . . . . . . . . . . . : 0D-1A-1C-BA-FA-0C, 32 | DHCP Enabled . . . . . . . . . . . . . . . . : Yes, 33 | Autoconfiguration Enabled . . . . . : Yes, 34 | IPv6 Address. . . . . . . . . . . . . . . . . . : fd1a:b211:4323:0:73fb:4270:4f0d:8f31, 35 | Temporary IPv6 Address. . . . . . . . : fd1a:b321:4412:1:c2f4:44ab:2fe4:a772, 36 | Link-local IPv6 Address . . . . . . . . : fe70::42af:2143:3b1a:5b33%6, 37 | IPv4 Address. . . . . . . . . . . . . . . . . . : 192.168.1.100, 38 | Subnet Mask . . . . . . . . . . . . . . . . . : 255.255.255.0, 39 | Lease Obainted. . . . . . . . . . . . . . . : 2020-03-03 08:14:00, 40 | Lease Expires . . . . . . . . . . . . . . . . : 2020-03-03 22:22:22, 41 | Default Gateway . . . . . . . . . . . . . . : 192.168.1.1, 42 | DHCP Server . . . . . . . . . . . . . . . . . : 192.168.1.1, 43 | DHCPv6 IAID . . . . . . . . . . . . . . . . . : 317237474, 44 | DHCPv6 Client DUID . . . . . . . . . : 00-01-02-03-04-05-06-07-08-09-10-AB, 45 | DNS servers . . . . . . . . . . . . . . . . . : 192.168.1.1`); 46 | 47 | terminalText(''); 48 | } else { 49 | terminalText(`Ethernet adapter Ethernet:
    , 50 | Connection-specific DNS Suffix . : lan, 51 | IPv6 Address. . . . . . . . . . . . . . . . . . : fd1a:b211:4323:0:73fb:4270:4f0d:8f31, 52 | Temporary IPv6 Address. . . . . . . . : fd1a:b321:4412:1:c2f4:44ab:2fe4:a772, 53 | Link-local IPv6 Address . . . . . . . . : fe70::42af:2143:3b1a:5b33%6, 54 | IPv4 Address. . . . . . . . . . . . . . . . . . : 192.168.1.100, 55 | Subnet Mask . . . . . . . . . . . . . . . . . : 255.255.255.0, 56 | Default Gateway . . . . . . . . . . . . . . : 192.168.1.1`); 57 | 58 | terminalText(''); 59 | } 60 | break; 61 | case 'ping': 62 | let ip = cmd[1]; 63 | if ( ip ) { 64 | let time = [getRandomInt(60, 14), getRandomInt(60, 14), getRandomInt(60, 14), getRandomInt(60, 14)]; 65 | terminalText(`Pinging ${ip} with 32 bytes of data:`); 66 | 67 | setTimeout(function () { 68 | terminalText(`Reply from ${ip}: bytes=32 time=${time[0]}ms TTL=57`); 69 | setTimeout(function () { 70 | terminalText(`Reply from ${ip}: bytes=32 time=${time[1]}ms TTL=57`); 71 | setTimeout(function () { 72 | terminalText(`Reply from ${ip}: bytes=32 time=${time[2]}ms TTL=57`); 73 | setTimeout(function () { 74 | terminalText(`Reply from ${ip}: bytes=32 time=${time[3]}ms TTL=57
    `); 75 | terminalText(`Ping statistics for ${ip}:, ` + 76 | `Packets: Sent = 4. Received = 4. Lost = 0 (0% loss), ` + 77 | `Approximate round trip times in milli-seconds:, ` + 78 | `Minimum = ${Math.min(...time)}ms. Maximum = ${Math.max(...time)}ms. Average = ${Math.round(time.reduce((a, b) => a + b, 0) / time.length)}ms`); 79 | terminalText(''); 80 | }, 700); 81 | }, 700); 82 | }, 700); 83 | }, 700); 84 | } else { 85 | wrongCommand(); 86 | } 87 | break; 88 | case 'clear': 89 | $('#t-text').empty(); 90 | break; 91 | case 'help': 92 | case 'cmdlist': 93 | case 'commands': 94 | terminalText(`Command list:, 95 | clear, 96 | ipconfig, 97 | ping [ip]`); 98 | terminalText(''); 99 | break; 100 | default: 101 | terminalText('Command not found.. Use /help'); 102 | } 103 | } 104 | 105 | $('#t-input span').text(`C:\\Users\\${ loggedInUser.username }>`); 106 | 107 | $('.program-terminal').click(() => { 108 | $('#t-input input').focus(); 109 | }); 110 | 111 | $('#t-input').submit(() => { 112 | if ( $('#t-input input').val().length > 0 ) { 113 | terminalCmd( $('#t-input input').val().toLowerCase() ); 114 | $('#t-input input').val(''); 115 | } 116 | 117 | return false; 118 | }); -------------------------------------------------------------------------------- /client/html/programs/twitter/twitter.css: -------------------------------------------------------------------------------- 1 | .program-twitter-header { 2 | background: #4b8ebb; 3 | color: #ffffff; 4 | } 5 | 6 | .program-twitter { 7 | height: 100%; 8 | width: 100%; 9 | color: #ffffff; 10 | background: #66bbf2; 11 | } 12 | 13 | .icon-twitter { 14 | background-position: -360px 0; 15 | } 16 | 17 | .icon-twitter:hover { 18 | background-position: -360px -60px; 19 | } 20 | 21 | .icon-twitter:active { 22 | background-position: -360px -120px; 23 | } 24 | 25 | .icon-twitter-small { 26 | background-position: -370px -193px; 27 | } 28 | 29 | #twitter-dashboard { 30 | margin-top: 10px; 31 | background: #ffffff; 32 | height: 150px; 33 | } 34 | 35 | #twitter-dashboard-content { 36 | background: #4c97c9; 37 | height: 100px; 38 | width: 100%; 39 | padding-top: 50px; 40 | margin-bottom: 60px; 41 | } 42 | 43 | #twitter-dashboard-content img { 44 | width: 60px; 45 | height: 60px; 46 | border-radius: 100%; 47 | float: left; 48 | margin: 20px; 49 | } 50 | 51 | #twitter-dashboard-content p { 52 | margin-top: 55px; 53 | color: #444444; 54 | font-weight: bold; 55 | font-size: 18px; 56 | } 57 | 58 | #twitter-dasboard-trending { 59 | padding: 5px 10px 10px 10px; 60 | background: #ffffff; 61 | height: 225px; 62 | color: #444444; 63 | } 64 | 65 | #twitter-dasboard-trending h6 { 66 | font-weight: bold; 67 | font-size: 18px; 68 | } 69 | 70 | #twitter-dasboard-trending li{ 71 | margin-bottom: 5px; 72 | } 73 | 74 | #twitter-dasboard-trending li p:nth-child(odd) { 75 | font-size: 14px; 76 | color: #4c97c9; 77 | font-weight: bold; 78 | } 79 | 80 | #twitter-dasboard-trending li p:nth-child(even) { 81 | font-size: 12px; 82 | } 83 | 84 | .program-twitter textarea { 85 | border-bottom: transparent !important; 86 | box-shadow: none !important; 87 | } 88 | 89 | .program-twitter textarea:focus { 90 | border-bottom: transparent !important; 91 | box-shadow: none !important; 92 | } 93 | 94 | .program-twitter textarea:focus + label { 95 | color: #444444 !important; 96 | } 97 | 98 | #twitter-textarea { 99 | background: #ffffff; 100 | border-radius: 5px; 101 | padding: 8px; 102 | } 103 | 104 | #twitter-content { 105 | margin-top: 10px; 106 | } 107 | 108 | #twitter-submit { 109 | color: #ffffff; 110 | background: #4c97c9; 111 | border-radius: 100px; 112 | padding: 8px; 113 | border: none; 114 | margin-top: 5px; 115 | } 116 | 117 | #twitter-submit:hover { 118 | background: #468dbd; 119 | } 120 | 121 | #twitter-submit:focus { 122 | background: #4084b1; 123 | } 124 | 125 | #twitter-posts { 126 | overflow: auto; 127 | } 128 | 129 | .twitter-post { 130 | background: #ffffff; 131 | color: #444444; 132 | margin-bottom: 10px; 133 | } 134 | 135 | .twitter-post-header { 136 | padding: 10px; 137 | width: 100%; 138 | height: 70px; 139 | } 140 | 141 | .twitter-post-header img { 142 | width: 50px; 143 | height: 50px; 144 | border-radius: 100%; 145 | float: left; 146 | } 147 | 148 | .twitter-post-header p { 149 | font-weight: bold; 150 | float: left; 151 | margin: 5px 0 0 10px; 152 | } 153 | 154 | .twitter-post-header span { 155 | font-weight: normal; 156 | margin-left: 5px; 157 | } 158 | 159 | .twitter-post-text { 160 | margin-top: -20px; 161 | padding: 0 10px 30px 70px; 162 | white-space: pre-wrap; 163 | } -------------------------------------------------------------------------------- /client/html/programs/twitter/twitter.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 | 9 |

    10 |
    11 | 15 |
    16 |
    17 |
    18 |
    19 | 20 | 21 |
    22 |
    23 |
    24 |
    25 |
    26 |
    27 |
    28 | 29 | -------------------------------------------------------------------------------- /client/html/programs/twitter/twitter.js: -------------------------------------------------------------------------------- 1 | let randomTrending = { 2 | 'Fivem': '13 tn tweets', 3 | 'Jsfour': '1337 tn tweets', 4 | 'Gtav': '304 tn tweets', 5 | 'Fifa': '200 tn tweets', 6 | 'Disney': '439 tn tweets', 7 | 'Sunes Sommar': '3.2 tn tweets', 8 | 'Phub': '700 tn tweets', 9 | 'Fortnite': '11.3 tn tweets', 10 | 'Steam': '8000 tweets', 11 | 'Startrek': '4 tn tweets', 12 | 'Discord': '380 tn tweets', 13 | 'Twitch': '12 tn tweets', 14 | 'Youtube': '24 tn tweets', 15 | 'Sweden': '56 tn tweets', 16 | 'Food': '70 tn tweets', 17 | 'Game Of Thrones': '176 tn tweets', 18 | 'John Wick': '12 tn tweets', 19 | 'The Lion King': '8.3 tn tweets', 20 | }; 21 | 22 | for (let i = 0; i < 4; i++) { 23 | let rnd = Object.keys(randomTrending)[Math.floor(Math.random() * Math.floor(Object.keys(randomTrending).length))]; 24 | 25 | $('#twitter-dasboard-trending ul').append(`
  • 26 |

    ${rnd}

    27 |

    ${randomTrending[rnd]}

    28 |
  • `); 29 | } 30 | 31 | $('#twitter-dashboard-content p').text( loggedInUser.username ); 32 | $('#twitter-dashboard-content img').attr('src', loggedInUser.avatar); 33 | 34 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:tempData`, { 35 | method: 'POST', 36 | body: JSON.stringify({ 37 | type: 'get', 38 | program: 'twitter' 39 | }) 40 | }) 41 | .then( response => response.text()) 42 | .then( data => { 43 | if ( data != 'null' ) { 44 | data = JSON.parse(data); 45 | 46 | Object.keys( data ).forEach(key => { 47 | let d = JSON.parse(data[key]); 48 | 49 | let toAppend = `
    50 |
    51 | 52 |

    ${ d.username } @${ d.username }

    53 |
    54 |

    ${ d.text }

    55 |
    `; 56 | 57 | $('#twitter-posts').prepend( toAppend ); 58 | }); 59 | } 60 | }); 61 | 62 | $('.program-twitter form').submit(() => { 63 | fetch(`https://${ GetParentResourceName() }/jsfour-computer:emitNet`, { 64 | method: 'POST', 65 | body: JSON.stringify({ 66 | type: 'all', 67 | tempdata: true, 68 | data: { 69 | 'program': 'twitter', 70 | 'text': $('#twitter-textarea').val(), 71 | 'username': loggedInUser.username, 72 | 'avatar': loggedInUser.avatar 73 | } 74 | }) 75 | }); 76 | 77 | $('#twitter-textarea').val(''); 78 | 79 | return false; 80 | }); 81 | 82 | function toNUItwitter( data ) { 83 | let toAppend = `
    84 |
    85 | 86 |

    ${ data.username } @${ data.username }

    87 |
    88 |

    ${ data.text }

    89 |
    `; 90 | 91 | $('#twitter-posts').prepend( toAppend ); 92 | } 93 | -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'adamant' 2 | 3 | game 'gta5' 4 | 5 | ui_page 'client/html/index.html' 6 | 7 | client_script { 8 | 'client/config.js', 9 | 'client/client.js' 10 | } 11 | 12 | server_script { 13 | 'server/server.js' 14 | } 15 | 16 | artifact_version '1.0.0.1222' 17 | 18 | files { 19 | 'client/html/index.html', 20 | 'client/html/**/*.css', 21 | 'client/html/**/*.js', 22 | 'client/html/**/*.json', 23 | 'client/html/**/*.html', 24 | 'client/html/**/*.png', 25 | 'client/html/**/*.jpg', 26 | 'client/html/**/*.gif', 27 | 'client/html/assets/css/*.css', 28 | 'client/html/assets/js/*.js', 29 | 'client/html/assets/js/*.json', 30 | 'client/html/assets/sounds/*.ogg', 31 | 'client/html/assets/images/*.png', 32 | 'client/html/assets/images/*.jpg', 33 | 'client/html/assets/images/*.gif', 34 | 'client/html/assets/fonts/roboto/*.woff', 35 | 'client/html/assets/fonts/roboto/*.woff2', 36 | 'client/html/assets/fonts/justsignature/*.woff', 37 | 'client/html/assets/fonts/handwritten/*.woff', 38 | } -------------------------------------------------------------------------------- /jsfour_computer.sql: -------------------------------------------------------------------------------- 1 | USE `essentialmode`; 2 | 3 | CREATE TABLE IF NOT EXISTS `jsfour_mail` ( 4 | `id` int(11) NOT NULL AUTO_INCREMENT, 5 | `from` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 6 | `to` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 7 | `title` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 8 | `text` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 9 | `date` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 10 | `folder` varchar(255) COLLATE utf8mb4_bin DEFAULT 'inbox', 11 | `read` tinyint(4) DEFAULT '0', 12 | `avatar` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 13 | `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 14 | PRIMARY KEY (`id`) 15 | ); 16 | 17 | CREATE TABLE IF NOT EXISTS `jsfour_forum` ( 18 | `id` int(11) NOT NULL AUTO_INCREMENT, 19 | `category` varchar(255) COLLATE utf8mb4_bin DEFAULT 'post', 20 | `text` longtext COLLATE utf8mb4_bin, 21 | `username` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 22 | `date` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 23 | `avatar` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 24 | `job` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 25 | PRIMARY KEY (`id`) 26 | ); 27 | 28 | CREATE TABLE IF NOT EXISTS `jsfour_medicalrecords` ( 29 | `id` int(11) NOT NULL AUTO_INCREMENT, 30 | `firstname` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 31 | `lastname` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 32 | `dob` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 33 | `date` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 34 | `uploader` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 35 | `title` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 36 | `text` longtext COLLATE utf8mb4_bin, 37 | PRIMARY KEY (`id`) 38 | ); 39 | 40 | CREATE TABLE `jsfour_users` ( 41 | `id` int(11) NOT NULL AUTO_INCREMENT, 42 | `username` varchar(255) COLLATE utf8mb4_bin NOT NULL, 43 | `password` varchar(255) COLLATE utf8mb4_bin NOT NULL, 44 | `firstname` varchar(255) COLLATE utf8mb4_bin NOT NULL, 45 | `lastname` varchar(255) COLLATE utf8mb4_bin NOT NULL, 46 | `group` varchar(255) COLLATE utf8mb4_bin NOT NULL, 47 | `job` varchar(255) COLLATE utf8mb4_bin NOT NULL, 48 | `avatar` varchar(255) COLLATE utf8mb4_bin DEFAULT 'https://via.placeholder.com/50?text=A', 49 | `desktop` varchar(255) COLLATE utf8mb4_bin DEFAULT 'assets/images/windows.png', 50 | `iconslots` longtext, 51 | PRIMARY KEY (`id`), 52 | UNIQUE KEY `username_UNIQUE` (`username`) 53 | ); 54 | 55 | 56 | INSERT INTO `jsfour_users` (`username`, `password`, `firstname`, `lastname`, `group`, `job`, `avatar`, `desktop`) VALUES ('admin', 'admin', 'admin', 'admin', 'admin', 'all', 'https://via.placeholder.com/50x50', 'assets/images/windows.png'); 57 | 58 | CREATE TABLE `jsfour_jobs` ( 59 | `id` int(11) NOT NULL AUTO_INCREMENT, 60 | `group` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 61 | `name` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL, 62 | `text` longtext COLLATE utf8mb4_bin, 63 | `title` varchar(255) COLLATE utf8mb4_bin DEFAULT 'Title', 64 | `image` varchar(255) COLLATE utf8mb4_bin DEFAULT 'https://via.placeholder.com/50/FFFFFFF/?text=JOB', 65 | PRIMARY KEY (`id`) 66 | ); 67 | 68 | # REMOVE # DOWN BELOW IF YOU HAVE ESX_JOBS INSTALLED 69 | # INSERT INTO `jsfour_jobs` (`group`, `name`) SELECT `name`, `label` FROM `jobs` WHERE `name` != 'unemployed' AND `whitelisted` = 0; 70 | --------------------------------------------------------------------------------