├── .env.example ├── .gitattributes ├── .gitignore ├── .phpstorm.meta.php ├── Procfile ├── README.md ├── _ide_helper.php ├── app ├── Console │ └── Kernel.php ├── Exceptions │ └── Handler.php ├── Forms │ ├── ClassInformationForm.php │ ├── SubjectForm.php │ ├── UserForm.php │ ├── UserProfileForm.php │ └── UserSettingsForm.php ├── Http │ ├── Controllers │ │ ├── Admin │ │ │ ├── ClassInformationsController.php │ │ │ ├── ClassStudentsController.php │ │ │ ├── ClassTeachingsController.php │ │ │ ├── SubjectsController.php │ │ │ ├── UserProfileController.php │ │ │ ├── UserSettingsController.php │ │ │ └── UsersController.php │ │ ├── Api │ │ │ ├── AuthController.php │ │ │ ├── Student │ │ │ │ ├── ClassInformationsController.php │ │ │ │ ├── ClassTeachingsController.php │ │ │ │ ├── ClassTestResultsController.php │ │ │ │ ├── ClassTestsController.php │ │ │ │ └── StudentClassTestsController.php │ │ │ ├── StudentsController.php │ │ │ ├── SubjectsController.php │ │ │ ├── Teacher │ │ │ │ ├── ClassInformationsController.php │ │ │ │ ├── ClassTeachingsController.php │ │ │ │ └── ClassTestsController.php │ │ │ └── TeachersController.php │ │ ├── Auth │ │ │ ├── ForgotPasswordController.php │ │ │ ├── LoginController.php │ │ │ ├── RegisterController.php │ │ │ └── ResetPasswordController.php │ │ ├── Controller.php │ │ └── HomeController.php │ ├── Kernel.php │ ├── Middleware │ │ ├── EncryptCookies.php │ │ ├── RedirectIfAuthenticated.php │ │ ├── TrimStrings.php │ │ └── VerifyCsrfToken.php │ └── Requests │ │ ├── ClassStudentRequest.php │ │ ├── ClassTeachingRequest.php │ │ ├── ClassTestRequest.php │ │ └── StudentClassTestRequest.php ├── Models │ ├── Admin.php │ ├── ClassInformation.php │ ├── ClassTeaching.php │ ├── ClassTest.php │ ├── Question.php │ ├── QuestionChoice.php │ ├── State.php │ ├── Student.php │ ├── StudentClassTest.php │ ├── StudentQuestionChoice.php │ ├── Subject.php │ ├── Teacher.php │ ├── User.php │ └── UserProfile.php ├── Notifications │ └── UserCreated.php └── Providers │ ├── AppServiceProvider.php │ ├── AuthServiceProvider.php │ ├── BroadcastServiceProvider.php │ ├── EventServiceProvider.php │ └── RouteServiceProvider.php ├── artisan ├── bootstrap ├── app.php ├── autoload.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── auth.php ├── broadcasting.php ├── cache.php ├── database.php ├── filesystems.php ├── jwt.php ├── mail.php ├── queue.php ├── services.php ├── session.php └── view.php ├── database ├── .gitignore ├── factories │ └── ModelFactory.php ├── migrations │ ├── 2014_10_12_000000_create_users_table.php │ ├── 2014_10_12_100000_create_password_resets_table.php │ ├── 2017_07_18_215254_create_teachers_table.php │ ├── 2017_07_18_215304_create_students_table.php │ ├── 2017_07_18_215311_create_admins_table.php │ ├── 2017_07_18_221623_create_user_profiles_tables.php │ ├── 2017_07_19_171120_create_class_informations.php │ ├── 2017_07_19_173844_create_subjects_table.php │ ├── 2017_07_26_002618_create_class_information_student_table.php │ ├── 2017_08_01_233524_create_class_teachings_table.php │ ├── 2017_08_22_193453_create_class_tests_table.php │ ├── 2017_08_22_193530_create_questions_table.php │ ├── 2017_08_22_193547_create_question_choices_table.php │ ├── 2017_08_29_012930_create_student_class_tests_table.php │ └── 2017_08_29_012950_create_student_question_choices_table.php └── seeds │ ├── ClassInformationsTableSeeder.php │ ├── ClassTestsTableSeeder.php │ ├── DatabaseSeeder.php │ ├── StudentClassTestTableSeeder.php │ ├── SubjectsTableSeeder.php │ └── UsersTableSeeder.php ├── package.json ├── phpunit.xml ├── public ├── .htaccess ├── css │ ├── admin.css │ ├── admin.css.map │ ├── app.css │ ├── spa.css │ └── spa.css.map ├── favicon.ico ├── fonts │ └── vendor │ │ └── bootstrap-sass │ │ └── bootstrap │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 ├── index.php ├── js │ ├── admin.js │ ├── admin.js.map │ ├── app.js │ ├── spa.js │ └── spa.js.map ├── mix-manifest.json └── robots.txt ├── resources ├── assets │ ├── admin │ │ ├── js │ │ │ ├── admin.js │ │ │ ├── bootstrap.js │ │ │ ├── components │ │ │ │ ├── Example.vue │ │ │ │ └── class_information │ │ │ │ │ ├── ClassStudent.vue │ │ │ │ │ └── ClassTeaching.vue │ │ │ ├── services │ │ │ │ ├── adminConfig.js │ │ │ │ └── resources.js │ │ │ └── store │ │ │ │ ├── class_student.js │ │ │ │ ├── class_teaching.js │ │ │ │ └── store.js │ │ └── sass │ │ │ ├── _variables.scss │ │ │ └── admin.scss │ └── spa │ │ ├── js │ │ ├── bootstrap.js │ │ ├── components │ │ │ ├── App.vue │ │ │ ├── Login.vue │ │ │ ├── Logout.vue │ │ │ ├── student │ │ │ │ ├── StudentClassInformationList.vue │ │ │ │ ├── StudentClassTeachingList.vue │ │ │ │ ├── StudentMenu.vue │ │ │ │ ├── chart │ │ │ │ │ └── StudentChartPerSubject.vue │ │ │ │ └── class_test │ │ │ │ │ ├── StudentClassTestDo.vue │ │ │ │ │ ├── StudentClassTestList.vue │ │ │ │ │ └── StudentClassTestQuestion.vue │ │ │ ├── teacher │ │ │ │ ├── TeacherClassInformationList.vue │ │ │ │ ├── TeacherClassTeachingList.vue │ │ │ │ ├── TeacherMenu.vue │ │ │ │ └── class_test │ │ │ │ │ ├── TeacherClassTestList.vue │ │ │ │ │ ├── TeacherClassTestQuestionForm.vue │ │ │ │ │ ├── TeacherClassTestQuestionList.vue │ │ │ │ │ ├── TeacherClassTestStepData.vue │ │ │ │ │ └── TeacherClassTestStepQuestions.vue │ │ │ └── templates │ │ │ │ └── menu.html │ │ ├── filters.js │ │ ├── mixins │ │ │ ├── auth.mixin.js │ │ │ ├── class_information.mixin.js │ │ │ └── menu.mixin.js │ │ ├── router.js │ │ ├── router.map.js │ │ ├── services │ │ │ ├── jwt-token.js │ │ │ ├── localstorage.js │ │ │ ├── resources.js │ │ │ └── spaConfig.js │ │ ├── spa.js │ │ └── store │ │ │ ├── auth.js │ │ │ ├── store.js │ │ │ ├── student.js │ │ │ ├── student │ │ │ ├── class_information.js │ │ │ ├── class_teaching.js │ │ │ ├── class_test.js │ │ │ └── student_class_test.js │ │ │ ├── teacher.js │ │ │ └── teacher │ │ │ ├── class_information.js │ │ │ ├── class_teaching.js │ │ │ └── class_test.js │ │ └── sass │ │ ├── _variables.scss │ │ └── spa.scss ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php └── views │ ├── admin │ ├── class_informations │ │ ├── class_student.blade.php │ │ ├── class_teaching.blade.php │ │ ├── create.blade.php │ │ ├── edit.blade.php │ │ ├── index.blade.php │ │ └── show.blade.php │ ├── subjects │ │ ├── create.blade.php │ │ ├── edit.blade.php │ │ ├── index.blade.php │ │ └── show.blade.php │ └── users │ │ ├── create.blade.php │ │ ├── edit.blade.php │ │ ├── index.blade.php │ │ ├── profile │ │ └── edit.blade.php │ │ ├── settings.blade.php │ │ ├── show.blade.php │ │ ├── show_details.blade.php │ │ └── tabs-component.blade.php │ ├── auth │ ├── login.blade.php │ ├── passwords │ │ ├── email.blade.php │ │ └── reset.blade.php │ └── register.blade.php │ ├── home.blade.php │ ├── layouts │ ├── app.blade.php │ └── spa.blade.php │ └── welcome.blade.php ├── routes ├── api.php ├── channels.php ├── console.php └── web.php ├── server.php ├── storage ├── app │ ├── .gitignore │ └── public │ │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tests ├── CreatesApplication.php ├── Feature │ └── ExampleTest.php ├── TestCase.php └── Unit │ └── ExampleTest.php ├── webpack.mix.js └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_LOG_LEVEL=debug 6 | APP_URL=http://localhost 7 | 8 | DB_CONNECTION=mysql 9 | DB_HOST=127.0.0.1 10 | DB_PORT=3306 11 | DB_DATABASE=homestead 12 | DB_USERNAME=homestead 13 | DB_PASSWORD=secret 14 | 15 | BROADCAST_DRIVER=log 16 | CACHE_DRIVER=file 17 | SESSION_DRIVER=file 18 | QUEUE_DRIVER=sync 19 | 20 | REDIS_HOST=127.0.0.1 21 | REDIS_PASSWORD=null 22 | REDIS_PORT=6379 23 | 24 | MAIL_DRIVER=smtp 25 | MAIL_HOST=smtp.mailtrap.io 26 | MAIL_PORT=2525 27 | MAIL_USERNAME=null 28 | MAIL_PASSWORD=null 29 | MAIL_ENCRYPTION=null 30 | 31 | PUSHER_APP_ID= 32 | PUSHER_APP_KEY= 33 | PUSHER_APP_SECRET= 34 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | /.idea 7 | /.vagrant 8 | Homestead.json 9 | Homestead.yaml 10 | npm-debug.log 11 | yarn-error.log 12 | .env -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: vendor/bin/heroku-php-apache2 public/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Esse código foi utilizado para a criação do curso [Sistema de gestão educacional com Laravel e Vue.js](https://www.schoolofnet.com/projeto-pratico/php/laravel/sistema-de-gestao-educacional-com-laravel-e-vuejs/) da School of Net. 4 | 5 | A School of Net é uma escola online que ensina as mais diversas tecnologias no mundo da programação, desenvolvimento web, games, design e infraestrutura. 6 | 7 | School of Net - [https://www.schoolofnet.com](https://www.schoolofnet.com) 8 | 9 | Blog da School of Net - [https://blog.schoolofnet.com](https://blog.schoolofnet.com) 10 | 11 | SONCast - Podcast da School of Net - [https://podcast.schoolofnet.com](https://podcast.schoolofnet.com) 12 | 13 | Canal da School of Net no Youtube: [http://www.youtube.com/c/SchoolofNetCursos](http://www.youtube.com/c/SchoolofNetCursos) -------------------------------------------------------------------------------- /app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire') 28 | // ->hourly(); 29 | } 30 | 31 | /** 32 | * Register the Closure based commands for the application. 33 | * 34 | * @return void 35 | */ 36 | protected function commands() 37 | { 38 | require base_path('routes/console.php'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 50 | return response()->json(['error' => 'Model not found'], 404); 51 | } 52 | } 53 | 54 | return parent::render($request, $exception); 55 | } 56 | 57 | /** 58 | * Convert an authentication exception into an unauthenticated response. 59 | * 60 | * @param \Illuminate\Http\Request $request 61 | * @param \Illuminate\Auth\AuthenticationException $exception 62 | * @return \Illuminate\Http\Response 63 | */ 64 | protected function unauthenticated($request, AuthenticationException $exception) 65 | { 66 | if ($request->expectsJson()) { 67 | return response()->json(['error' => 'Unauthenticated.'], 401); 68 | } 69 | 70 | return redirect()->guest(route('login')); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/Forms/ClassInformationForm.php: -------------------------------------------------------------------------------- 1 | format('Y-m-d'):$value; 14 | }; 15 | $this 16 | ->add('date_start', 'date', [ 17 | 'label' => 'Data Início', 18 | 'rules' => 'required|date', 19 | 'value' => $formatDate 20 | ]) 21 | ->add('date_end', 'date', [ 22 | 'label' => 'Data Final', 23 | 'rules' => 'required|date', 24 | 'value' => $formatDate 25 | ]) 26 | ->add('cycle', 'number', [ 27 | 'label' => 'Ciclo', 28 | 'rules' => 'required|integer' 29 | ]) 30 | ->add('subdivision', 'number', [ 31 | 'label' => 'Sub-divisão', 32 | 'rules' => 'integer' 33 | ]) 34 | ->add('semester', 'number', [ 35 | 'label' => 'Semestre (1 ou 2)', 36 | 'rules' => 'required|in:1,2' 37 | ]) 38 | ->add('year', 'number', [ 39 | 'label' => 'Ano', 40 | 'rules' => 'required|integer' 41 | ]); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/Forms/SubjectForm.php: -------------------------------------------------------------------------------- 1 | add('name', 'text', [ 13 | 'label' => 'Nome', 14 | 'rules' => 'required|max:255' 15 | ]); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Forms/UserForm.php: -------------------------------------------------------------------------------- 1 | getData('id'); 13 | $this 14 | ->add('name', 'text', [ 15 | 'label' => 'Nome', 16 | 'rules' => 'required|max:255' 17 | ]) 18 | ->add('email', 'email',[ 19 | 'label' => 'E-mail', 20 | 'rules' => "required|max:255|unique:users,email,{$id}" 21 | ]) 22 | ->add('type', 'select',[ 23 | 'label' => 'Tipo de usuário', 24 | 'choices' => $this->roles(), 25 | 'rules' => 'required|in:'.implode(',',array_keys($this->roles())) 26 | ]) 27 | ->add('send_mail','checkbox', [ 28 | 'label' => 'Enviar e-mail de boas-vindas', 29 | 'value' => true, 30 | 'checked' => false 31 | ]); 32 | } 33 | 34 | protected function roles(){ 35 | return [ 36 | User::ROLE_ADMIN => 'Administrador', 37 | User::ROLE_TEACHER => 'Professor', 38 | User::ROLE_STUDENT => 'Aluno', 39 | ]; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Forms/UserProfileForm.php: -------------------------------------------------------------------------------- 1 | add('address', 'text', [ 13 | 'label' => 'Endereço', 14 | 'rules' => 'required|max:255' 15 | ]) 16 | ->add('cep', 'text', [ 17 | 'label' => 'CEP', 18 | 'rules' => 'required|max:8' 19 | ]) 20 | ->add('number', 'text', [ 21 | 'label' => 'Número', 22 | 'rules' => 'required|max:255' 23 | ]) 24 | ->add('complement', 'text', [ 25 | 'label' => 'Complemento', 26 | 'rules' => 'max:255' 27 | ]) 28 | ->add('city', 'text', [ 29 | 'label' => 'Cidade', 30 | 'rules' => 'required|max:255' 31 | ]) 32 | ->add('neighborhood', 'text', [ 33 | 'label' => 'Bairro', 34 | 'rules' => 'required|max:255' 35 | ]) 36 | ->add('state', 'text', [ 37 | 'label' => 'Estado', 38 | 'rules' => 'required|max:255' 39 | ]); 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Forms/UserSettingsForm.php: -------------------------------------------------------------------------------- 1 | add('password', 'password',[ 13 | 'rules' => 'required|min:6|max:16|confirmed' 14 | ]) 15 | ->add('password_confirmation', 'password'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/ClassStudentsController.php: -------------------------------------------------------------------------------- 1 | ajax()) { 21 | return view('admin.class_informations.class_student', compact('class_information')); 22 | }else{ 23 | return $class_information->students()->get(); 24 | } 25 | } 26 | 27 | /** 28 | * Store a newly created resource in storage. 29 | * 30 | * @param \Illuminate\Http\Request $request 31 | * @return \Illuminate\Http\Response 32 | */ 33 | public function store(ClassStudentRequest $request,ClassInformation $class_information) 34 | { 35 | $student = Student::find($request->get('student_id')); 36 | $class_information->students()->save($student); 37 | return $student; 38 | } 39 | 40 | /** 41 | * Remove the specified resource from storage. 42 | * 43 | * @param int $id 44 | * @return \Illuminate\Http\Response 45 | */ 46 | public function destroy(ClassInformation $class_information, Student $student) 47 | { 48 | $class_information->students()->detach([$student->id]); 49 | return response()->json([],204); //status code - no content 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/ClassTeachingsController.php: -------------------------------------------------------------------------------- 1 | ajax()) { 23 | return view('admin.class_informations.class_teaching', compact('class_information')); 24 | }else{ 25 | return $class_information->teachings()->get(); 26 | } 27 | } 28 | 29 | /** 30 | * Store a newly created resource in storage. 31 | * 32 | * @param \Illuminate\Http\Request $request 33 | * @return \Illuminate\Http\Response 34 | */ 35 | public function store(ClassTeachingRequest $request,ClassInformation $class_information) 36 | { 37 | $teaching = $class_information->teachings()->create([ 38 | 'subject_id' => $request->get('subject_id'), 39 | 'teacher_id' => $request->get('teacher_id'), 40 | ]); 41 | return $teaching; 42 | } 43 | 44 | /** 45 | * Remove the specified resource from storage. 46 | * 47 | * @param int $id 48 | * @return \Illuminate\Http\Response 49 | */ 50 | public function destroy(ClassInformation $class_information, ClassTeaching $teaching) 51 | { 52 | $teaching->delete(); 53 | return response()->json([],204); //status code - no content 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/UserProfileController.php: -------------------------------------------------------------------------------- 1 | route('admin.users.profile.update', ['user' => $user->id]), 23 | 'method' => 'PUT', 24 | 'model' => $user->profile, 25 | 'data' => ['user' => $user] 26 | ]); 27 | return view('admin.users.profile.edit', compact('form')); 28 | } 29 | 30 | /** 31 | * Update the specified resource in storage. 32 | * 33 | * @param \Illuminate\Http\Request $request 34 | * @param \SON\Models\UserProfile $userProfile 35 | * @return \Illuminate\Http\Response 36 | */ 37 | public function update(User $user) 38 | { 39 | $form = \FormBuilder::create(UserProfileForm::class); 40 | 41 | if (!$form->isValid()) { 42 | return redirect() 43 | ->back() 44 | ->withErrors($form->getErrors()) 45 | ->withInput(); 46 | } 47 | 48 | $data = $form->getFieldValues(); 49 | $user->profile->address?$user->profile->update($data):$user->profile()->create($data); 50 | 51 | 52 | session()->flash('message', 'Perfil alterado com sucesso.'); 53 | return redirect()->route('admin.users.profile.update', ['user' => $user->id]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/Http/Controllers/Admin/UserSettingsController.php: -------------------------------------------------------------------------------- 1 | route('admin.users.settings.update'), 17 | 'method' => 'PUT' 18 | ]); 19 | 20 | return view('admin.users.settings', compact('form')); 21 | } 22 | 23 | /** 24 | * Update the specified resource in storage. 25 | * 26 | * @return \Illuminate\Http\Response 27 | * @internal param User $user 28 | * @internal param int $id 29 | */ 30 | public function update(Request $request) 31 | { 32 | /** @var Form $form */ 33 | $form = \FormBuilder::create(UserSettingsForm::class); 34 | 35 | if (!$form->isValid()) { 36 | return redirect()->back()->withErrors($form->getErrors())->withInput(); 37 | } 38 | 39 | $data = $form->getFieldValues(); 40 | $data['password'] = bcrypt($data['password']); 41 | \Auth::user()->update($data); 42 | $request->session()->flash('message', 'Senha alterada com sucesso'); 43 | return redirect()->route('admin.users.settings.edit'); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/AuthController.php: -------------------------------------------------------------------------------- 1 | only($this->username(), 'password'); 28 | $usernameKey = $this->usernameKey(); 29 | $data[$usernameKey] = $data[$this->username()]; 30 | unset($data[$this->username()]); 31 | return $data; 32 | } 33 | 34 | protected function usernameKey() 35 | { 36 | $email = \Request::get($this->username()); 37 | $validator = \Validator::make([ 38 | 'email' => $email 39 | ], ['email' => 'email']); 40 | return $validator->fails() ? 'enrolment' : 'email'; 41 | } 42 | 43 | public function username() 44 | { 45 | return 'username'; 46 | } 47 | 48 | public function accessToken(Request $request) 49 | { 50 | $this->validateLogin($request); 51 | 52 | $credentials = $this->credentials($request); 53 | 54 | if ($token = \Auth::guard('api')->attempt($credentials)) { 55 | return ['token' => $token]; 56 | } 57 | 58 | return response()->json([ 59 | 'error' => \Lang::get('auth.failed') 60 | ],400); 61 | } 62 | 63 | public function logout(){ 64 | \Auth::guard('api')->logout(); 65 | return response()->json([],204); //No content 66 | } 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Student/ClassInformationsController.php: -------------------------------------------------------------------------------- 1 | userable; 18 | $results = $student->classInformations; 19 | /*$results = ClassInformation 20 | ::byStudent(\Auth::user()->userable->id) 21 | ->get();*/ 22 | 23 | return $results; 24 | } 25 | 26 | 27 | /** 28 | * Display the specified resource. 29 | * 30 | * @param int $id 31 | * @return \Illuminate\Http\Response 32 | */ 33 | public function show($id) 34 | { 35 | $student = \Auth::user()->userable; 36 | $result = $student->classInformations()->findOrFail($id); 37 | /*$result = ClassInformation 38 | ::byStudent(\Auth::user()->userable->id) 39 | ->findOrFail($id);*/ 40 | return $result; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Student/ClassTeachingsController.php: -------------------------------------------------------------------------------- 1 | userable; 18 | $results = $student 19 | ->classInformations() 20 | ->find($classInformation->id) 21 | ->teachings; 22 | 23 | return $results; 24 | } 25 | 26 | 27 | /** 28 | * Display the specified resource. 29 | * 30 | * @param int $id 31 | * @return \Illuminate\Http\Response 32 | */ 33 | public function show(ClassInformation $classInformation, $id) 34 | { 35 | $student = \Auth::user()->userable; 36 | $result = $student 37 | ->classInformations() 38 | ->find($classInformation->id) 39 | ->teachings() 40 | ->findOrFail($id); 41 | 42 | return $result; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Student/ClassTestResultsController.php: -------------------------------------------------------------------------------- 1 | selectRaw(implode(',', $selects)) 21 | ->join('class_tests', 'class_tests.id', '=', 'student_class_tests.class_test_id') 22 | //->join('class_teachings','class_teachings.id','=','class_tests.class_teaching_id') 23 | //->join('subjects','subjects.id','=','class_teachings.subject_id') 24 | ->where('student_id',25) 25 | ->where('class_tests.class_teaching_id',166) 26 | ->orderBy('student_class_tests.created_at', 'asc') 27 | ->get(); 28 | $results->map(function ($item) { //\stdClass 29 | $item->created_at = (new Carbon($item->created_at))->format(Carbon::ISO8601); 30 | return $item; 31 | }); 32 | return $results; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Student/ClassTestsController.php: -------------------------------------------------------------------------------- 1 | userable->id; 15 | $results = ClassTest 16 | ::where('class_teaching_id', $classTeaching->id) 17 | ->byStudent($studentId) 18 | ->get(); 19 | $results = array_map(function($classTest) use($studentId){ 20 | $studentClassTest = StudentClassTest 21 | ::where('class_test_id',$classTest['id']) 22 | ->where('student_id',$studentId) 23 | ->first(); 24 | if($studentClassTest){ 25 | $classTest['student_class_test']['id'] = $studentClassTest->id; 26 | if(ClassTest::greatherDateEnd30Minutes($classTest['date_end'])){ 27 | $classTest['student_class_test']['point'] = $studentClassTest->point; 28 | } 29 | } 30 | return $classTest; 31 | },$results->toArray()); 32 | return $results; 33 | } 34 | 35 | public function show(ClassTeaching $classTeaching, $id) 36 | { 37 | $result = ClassTest 38 | ::byStudent(\Auth::user()->userable->id) 39 | ->findOrFail($id); 40 | 41 | $array = $result->toArray(); 42 | 43 | $array['questions'] = array_map(function ($question) use($array) { 44 | 45 | if(!ClassTest::greatherDateEnd30Minutes($array['date_end'])) { 46 | $question['choices'] = array_map(function ($choice) use ($array){ 47 | unset($choice['true']); 48 | return $choice; 49 | }, $question['choices']->toArray()); 50 | } 51 | 52 | return $question; 53 | 54 | }, $result->questions->toArray()); 55 | 56 | return $array; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Student/StudentClassTestsController.php: -------------------------------------------------------------------------------- 1 | input() + [ 16 | 'student_id' => \Auth::user()->userable->id 17 | ]); 18 | return $studentClassTest; 19 | 20 | } 21 | 22 | public function show(ClassTest $classTest, $id) 23 | { 24 | if (!ClassTest::greatherDateEnd30Minutes($classTest->date_end)) { 25 | abort(403); 26 | } 27 | 28 | $result = StudentClassTest 29 | ::where('student_id', \Auth::user()->userable->id) 30 | ->findOrFail($id); 31 | 32 | return $result->toArray() + [ 33 | 'choices' => $result 34 | ->choices 35 | ->pluck('question_choice_id', 'question_id') 36 | ->toArray() 37 | ]; 38 | 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/StudentsController.php: -------------------------------------------------------------------------------- 1 | get('q'); 14 | return !$search ? 15 | [] : 16 | Student::whereHas('user', function ($query) use ($search) { 17 | $query->where('users.name', 'LIKE', "%{$search}%"); 18 | })->take(10)->get(); 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/SubjectsController.php: -------------------------------------------------------------------------------- 1 | input('q'); 14 | 15 | return $search ?Subject::where('name','LIKE', '%'.$search.'%')->get():[]; 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Teacher/ClassInformationsController.php: -------------------------------------------------------------------------------- 1 | userable->id) 20 | ->get(); 21 | 22 | return $results; 23 | } 24 | 25 | 26 | /** 27 | * Display the specified resource. 28 | * 29 | * @param int $id 30 | * @return \Illuminate\Http\Response 31 | */ 32 | public function show($id) 33 | { 34 | $result = ClassInformation 35 | ::byTeacher(\Auth::user()->userable->id) 36 | ->findOrFail($id); 37 | return $result; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Teacher/ClassTeachingsController.php: -------------------------------------------------------------------------------- 1 | userable->id) 20 | ->get() 21 | ->toArray(); 22 | 23 | return array_map(function ($item) { 24 | unset($item['teacher']); 25 | return $item; 26 | }, $results); 27 | } 28 | 29 | 30 | /** 31 | * Display the specified resource. 32 | * 33 | * @param int $id 34 | * @return \Illuminate\Http\Response 35 | */ 36 | public function show($id) 37 | { 38 | $result = ClassTeaching 39 | ::where('teacher_id', \Auth::user()->userable->id) 40 | ->findOrFail($id) 41 | ->toArray(); 42 | 43 | unset($result['teacher']); 44 | return $result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/Teacher/ClassTestsController.php: -------------------------------------------------------------------------------- 1 | id) 16 | ->byTeacher(\Auth::user()->userable->id) 17 | ->get(); 18 | return $results; 19 | } 20 | 21 | public function store(ClassTestRequest $request,ClassTeaching $classTeaching) 22 | { 23 | return ClassTest::createFully($request->all()+['class_teaching_id' => $classTeaching->id]); 24 | } 25 | 26 | public function update(ClassTestRequest $request,ClassTeaching $classTeaching,ClassTest $classTest) 27 | { 28 | return $classTest->updateFully($request->all()); 29 | } 30 | 31 | public function show(ClassTeaching $classTeaching, $id) 32 | { 33 | $result = ClassTest 34 | ::byTeacher(\Auth::user()->userable->id) 35 | ->findOrFail($id); 36 | $array = $result->toArray(); 37 | $array['questions'] = $result->questions; 38 | return $result; 39 | } 40 | 41 | public function destroy(ClassTeaching $classTeaching,$classTestId) 42 | { 43 | $classTest = ClassTest 44 | ::byTeacher(\Auth::user()->userable->id) 45 | ->findOrFail($classTestId); 46 | $classTest->deleteFully(); 47 | return response()->json([],204); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /app/Http/Controllers/Api/TeachersController.php: -------------------------------------------------------------------------------- 1 | input('q'); 14 | 15 | return $search ?Teacher::whereHas('user', function($query) use($search){ 16 | $query->where('users.name', 'LIKE', '%'.$search.'%'); 17 | })->take(10)->get():[]; 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ForgotPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/LoginController.php: -------------------------------------------------------------------------------- 1 | middleware('guest')->except('logout'); 40 | } 41 | 42 | protected function credentials(Request $request) 43 | { 44 | $data = $request->only($this->username(),'password'); 45 | $usernameKey = $this->usernameKey(); 46 | $data[$usernameKey] = $data[$this->username()]; 47 | $data['userable_type'] = Admin::class; 48 | unset($data[$this->username()]); 49 | return $data; 50 | } 51 | 52 | protected function usernameKey(){ 53 | $email = \Request::get($this->username()); 54 | $validator = \Validator::make([ 55 | 'email' => $email 56 | ],['email' => 'email']); 57 | return $validator->fails() ? 'enrolment': 'email'; 58 | } 59 | 60 | public function username() 61 | { 62 | return 'username'; 63 | } 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/RegisterController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 40 | } 41 | 42 | /** 43 | * Get a validator for an incoming registration request. 44 | * 45 | * @param array $data 46 | * @return \Illuminate\Contracts\Validation\Validator 47 | */ 48 | protected function validator(array $data) 49 | { 50 | return Validator::make($data, [ 51 | 'name' => 'required|string|max:255', 52 | 'email' => 'required|string|email|max:255|unique:users', 53 | 'password' => 'required|string|min:6|confirmed', 54 | ]); 55 | } 56 | 57 | /** 58 | * Create a new user instance after a valid registration. 59 | * 60 | * @param array $data 61 | * @return \SON\Models\User 62 | */ 63 | protected function create(array $data) 64 | { 65 | return User::create([ 66 | 'name' => $data['name'], 67 | 'email' => $data['email'], 68 | 'password' => bcrypt($data['password']), 69 | ]); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /app/Http/Controllers/Auth/ResetPasswordController.php: -------------------------------------------------------------------------------- 1 | middleware('guest'); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | middleware('auth'); 17 | } 18 | 19 | /** 20 | * Show the application dashboard. 21 | * 22 | * @return \Illuminate\Http\Response 23 | */ 24 | public function index() 25 | { 26 | return view('home'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Http/Kernel.php: -------------------------------------------------------------------------------- 1 | [ 31 | \SON\Http\Middleware\EncryptCookies::class, 32 | \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, 33 | \Illuminate\Session\Middleware\StartSession::class, 34 | // \Illuminate\Session\Middleware\AuthenticateSession::class, 35 | \Illuminate\View\Middleware\ShareErrorsFromSession::class, 36 | \SON\Http\Middleware\VerifyCsrfToken::class, 37 | \Illuminate\Routing\Middleware\SubstituteBindings::class, 38 | ], 39 | 40 | 'api' => [ 41 | 'throttle:60,1', 42 | 'bindings', 43 | ], 44 | ]; 45 | 46 | /** 47 | * The application's route middleware. 48 | * 49 | * These middleware may be assigned to groups or used individually. 50 | * 51 | * @var array 52 | */ 53 | protected $routeMiddleware = [ 54 | 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 55 | 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 56 | 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 57 | 'can' => \Illuminate\Auth\Middleware\Authorize::class, 58 | 'guest' => \SON\Http\Middleware\RedirectIfAuthenticated::class, 59 | 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 60 | 'auth.renew' => AuthenticateAndRenew::class 61 | ]; 62 | } 63 | -------------------------------------------------------------------------------- /app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | check()) { 21 | return redirect('/home'); 22 | } 23 | 24 | return $next($request); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | route('class_information'); 28 | return [ 29 | 'student_id' => [ 30 | 'required', 31 | 'exists:students,id', 32 | Rule::unique('class_information_student','student_id') 33 | ->where('class_information_id',$class_information->id) 34 | ] 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/Http/Requests/ClassTeachingRequest.php: -------------------------------------------------------------------------------- 1 | route('class_information'); 28 | return [ 29 | 'teacher_id' => 'required|exists:teachers,id', 30 | 'subject_id' => [ 31 | 'required', 32 | 'exists:subjects,id', 33 | Rule::unique('class_teachings','subject_id') 34 | ->where('class_information_id',$class_information->id) 35 | ->where('teacher_id',$this->get('teacher_id')) 36 | ] 37 | ]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/Http/Requests/ClassTestRequest.php: -------------------------------------------------------------------------------- 1 | route('class_teaching'); 19 | $result = ClassTeaching 20 | ::where('teacher_id',\Auth::user()->userable->id) 21 | ->find($classTeaching->id); 22 | 23 | return $result != null; 24 | } 25 | 26 | /** 27 | * Get the validation rules that apply to the request. 28 | * 29 | * @return array 30 | */ 31 | public function rules() 32 | { 33 | return [ 34 | 'name' => 'required|max:255', 35 | 'date_start' => 'required|date_format:Y-m-d\TH:i', 36 | 'date_end' => 'required|date_format:Y-m-d\TH:i', 37 | 'questions' => 'required|array', 38 | 'questions.*.question' => 'required', 39 | 'questions.*.point' => 'required|numeric', 40 | 'questions.*.choices' => 'required|array|choice_true', 41 | 'questions.*.choices.*.choice' => 'required', 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/Http/Requests/StudentClassTestRequest.php: -------------------------------------------------------------------------------- 1 | route('class_test'); 20 | $result = ClassTest 21 | ::byStudent(\Auth::user()->userable->id) 22 | ->find($classTest->id); 23 | 24 | return $result != null; 25 | } 26 | 27 | protected function validationData() 28 | { 29 | $classTest = $this->route('class_test'); 30 | $data = [ 31 | 'class_test_id' => $classTest->id, 32 | 'date_start' => $classTest->date_start, 33 | 'date_end' => $classTest->date_end, 34 | 'date' => (new Carbon())->format(\DateTime::ISO8601) 35 | ]; 36 | /** 37 | * choices => [question_id => question_choice_id] 38 | */ 39 | $choices = $this->get('choices'); 40 | $data['choices'] = $choices; 41 | if(is_array($choices)){ 42 | $data['choices'] = []; 43 | foreach ($choices as $questionId => $choiceId){ 44 | array_push($data['choices'],[ 45 | 'question_id' => $questionId, 46 | 'question_choice_id' => $choiceId 47 | ]); 48 | } 49 | $this->merge($data); 50 | } 51 | return $data; 52 | } 53 | 54 | /** 55 | * Get the validation rules that apply to the request. 56 | * 57 | * @return array 58 | */ 59 | public function rules() 60 | { 61 | $classTest = $this->route('class_test'); 62 | return [ 63 | 'class_test_id' => [ 64 | Rule::unique('student_class_tests') 65 | ->where('student_id',\Auth::user()->userable->id) 66 | ], 67 | //'date' => 'after_or_equal:date_start|before_or_equal:date_end', 68 | 'date' => 'before_or_equal:date_end', 69 | 'choices' => 'required|array', 70 | 'choices.*.question_id' => [ 71 | 'required', 72 | Rule::exists('questions','id') 73 | ->where('class_test_id',$classTest->id) 74 | ], 75 | 'choices.*.question_choice_id' => 'required|choice_from_question' 76 | ]; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /app/Models/Admin.php: -------------------------------------------------------------------------------- 1 | morphOne(User::class,'userable'); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/Models/ClassInformation.php: -------------------------------------------------------------------------------- 1 | belongsToMany(Student::class); 27 | } 28 | 29 | public function teachings() 30 | { 31 | return $this->hasMany(ClassTeaching::class); 32 | } 33 | 34 | public function scopeByTeacher($query, $teacherId) 35 | { 36 | return $query->whereHas('teachings', function ($query) use($teacherId){ 37 | $query->where('teacher_id', $teacherId); 38 | }); 39 | } 40 | 41 | public function scopeByStudent($query, $studentId) 42 | { 43 | return $query->whereHas('students', function ($query) use($studentId){ 44 | $query->where('student_id', $studentId); 45 | }); 46 | } 47 | 48 | /** 49 | * A list of headers to be used when a table is displayed 50 | * 51 | * @return array 52 | */ 53 | public function getTableHeaders() 54 | { 55 | return [ 56 | 'ID', 57 | 'Data Início', 58 | 'Data Fim', 59 | 'Ciclo', 60 | 'Subdivisão', 61 | 'Semestre', 62 | 'Ano' 63 | ]; 64 | } 65 | 66 | /** 67 | * Get the value for a given header. Note that this will be the value 68 | * passed to any callback functions that are being used. 69 | * 70 | * @param string $header 71 | * @return mixed 72 | */ 73 | public function getValueForHeader($header) 74 | { 75 | switch ($header) { 76 | case 'ID': 77 | return $this->id; 78 | case 'Data Início': 79 | return $this->date_start->format('d/m/Y'); //Carbon 80 | case 'Data Fim': 81 | return $this->date_end->format('d/m/Y'); 82 | case 'Ciclo': 83 | return $this->cycle; 84 | case 'Subdivisão': 85 | return $this->subdivision; 86 | case 'Semestre': 87 | return $this->semester; 88 | case 'Ano': 89 | return $this->year; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /app/Models/ClassTeaching.php: -------------------------------------------------------------------------------- 1 | hasMany(ClassTest::class); 19 | } 20 | 21 | public function subject(){ 22 | return $this->belongsTo(Subject::class); 23 | } 24 | 25 | public function classInformation(){ 26 | return $this->belongsTo(ClassInformation::class); 27 | } 28 | 29 | public function teacher(){ 30 | return $this->belongsTo(Teacher::class); 31 | } 32 | 33 | public function toArray() 34 | { 35 | $data = parent::toArray(); 36 | $data['teacher'] = $this->teacher; 37 | $data['subject'] = $this->subject; 38 | $data['class_information'] = $this->classInformation; 39 | return $data; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/Models/Question.php: -------------------------------------------------------------------------------- 1 | hasMany(QuestionChoice::class); 17 | } 18 | 19 | public function toArray() 20 | { 21 | $data = parent::toArray(); 22 | $data['choices'] = $this->choices; 23 | return $data; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /app/Models/QuestionChoice.php: -------------------------------------------------------------------------------- 1 | 'boolean' 17 | ]; 18 | } 19 | -------------------------------------------------------------------------------- /app/Models/State.php: -------------------------------------------------------------------------------- 1 | morphOne(User::class,'userable'); 11 | } 12 | 13 | public function classInformations(){ 14 | return $this->belongsToMany(ClassInformation::class); 15 | } 16 | 17 | public function toArray() 18 | { 19 | $data = parent::toArray(); 20 | $this->user->makeHidden('userable_type','userable_id'); 21 | $data['user'] = $this->user; 22 | return $data; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/Models/StudentClassTest.php: -------------------------------------------------------------------------------- 1 | belongsTo(ClassTest::class); 16 | } 17 | 18 | public function student(){ 19 | return $this->belongsTo(Student::class); 20 | } 21 | 22 | public function choices(){ 23 | return $this->hasMany(StudentQuestionChoice::class); 24 | } 25 | 26 | public static function createFully(array $data){ 27 | $studentClassTest = parent::create($data); 28 | foreach ($data['choices'] as $choice){ 29 | //question_id and question_choice_id 30 | $studentClassTest->choices()->create($choice); 31 | } 32 | $studentClassTest->point = self::calculatePoint($studentClassTest); 33 | $studentClassTest->save(); 34 | return $studentClassTest; 35 | } 36 | 37 | public static function calculatePoint(StudentClassTest $studentClassTest){ 38 | $questions = $studentClassTest->classTest->questions; 39 | $studentChoices = $studentClassTest->choices; 40 | $point = 0; 41 | foreach ($questions as $question){ 42 | $studentChoice = $studentChoices->where('question_id',$question->id)->first(); 43 | if($studentChoice){ 44 | $choiceTrue = $question->choices()->where('true',true)->first(); 45 | $point += $choiceTrue->id == $studentChoice->question_choice_id 46 | ?(float)$question->point:0; 47 | } 48 | } 49 | return $point; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/Models/StudentQuestionChoice.php: -------------------------------------------------------------------------------- 1 | id; 36 | case 'Nome': 37 | return $this->name; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/Models/Teacher.php: -------------------------------------------------------------------------------- 1 | morphOne(User::class,'userable'); 11 | } 12 | 13 | public function toArray() 14 | { 15 | $data = parent::toArray(); 16 | $this->user->makeHidden('userable_type','userable_id'); 17 | $data['user'] = $this->user; 18 | return $data; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/Models/UserProfile.php: -------------------------------------------------------------------------------- 1 | token = $token; 24 | } 25 | 26 | /** 27 | * Get the notification's delivery channels. 28 | * 29 | * @param mixed $notifiable 30 | * @return array 31 | */ 32 | public function via($notifiable) 33 | { 34 | return ['mail']; 35 | } 36 | 37 | /** 38 | * Get the mail representation of the notification. 39 | * 40 | * @param mixed $notifiable 41 | * @return \Illuminate\Notifications\Messages\MailMessage 42 | */ 43 | public function toMail($notifiable) 44 | { 45 | $appName = config('app.name'); 46 | return (new MailMessage) 47 | ->subject("Sua conta no $appName foi criada") 48 | ->greeting("Olá {$notifiable->name}, seja bem-vindo ao $appName") 49 | ->line("Seu número de matrícula é: {$notifiable->enrolment}") 50 | ->action('Clique aqui para definir sua senha',route('password.reset',$this->token)) 51 | ->line('Obrigado por usar nossa aplicação!') 52 | ->salutation(''); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | filter(function ($item) { 23 | return isset($item['true']) && $item['true'] !== false; 24 | }); 25 | 26 | return $items->count() === 1; 27 | }); 28 | \Validator::extend('choice_from_question', function ($attribute, $value, $parameters, $validator) { 29 | 30 | $data = $validator->getData(); 31 | $questionIdAttr = str_replace('question_choice_id', 'question_id', $attribute); 32 | $questionId = array_get($data, $questionIdAttr); 33 | 34 | $choice = QuestionChoice 35 | ::where('question_id', $questionId) 36 | ->find($value); 37 | return $choice != null; 38 | }); 39 | } 40 | 41 | /** 42 | * Register any application services. 43 | * 44 | * @return void 45 | */ 46 | public function register() 47 | { 48 | if ($this->app->environment() !== 'production') { 49 | $this->app->register(\Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class); 50 | } 51 | 52 | $this->app->extend(FakerGenerator::class, function () { 53 | return FakerFactory::create('pt_BR'); 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 'SON\Policies\ModelPolicy', 20 | ]; 21 | 22 | /** 23 | * Register any authentication / authorization services. 24 | * 25 | * @return void 26 | */ 27 | public function boot() 28 | { 29 | $this->registerPolicies(); 30 | 31 | \Gate::define('admin', function($user){ 32 | return $user->userable instanceof Admin; 33 | }); 34 | 35 | \Gate::define('teacher', function($user){ 36 | return $user->userable instanceof Teacher; 37 | }); 38 | 39 | \Gate::define('student', function($user){ 40 | return $user->userable instanceof Student; 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | [ 17 | 'SON\Listeners\EventListener', 18 | ], 19 | ]; 20 | 21 | /** 22 | * Register any events for your application. 23 | * 24 | * @return void 25 | */ 26 | public function boot() 27 | { 28 | parent::boot(); 29 | 30 | // 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | mapApiRoutes(); 39 | 40 | $this->mapWebRoutes(); 41 | 42 | // 43 | } 44 | 45 | /** 46 | * Define the "web" routes for the application. 47 | * 48 | * These routes all receive session state, CSRF protection, etc. 49 | * 50 | * @return void 51 | */ 52 | protected function mapWebRoutes() 53 | { 54 | Route::middleware('web') 55 | ->namespace($this->namespace) 56 | ->group(base_path('routes/web.php')); 57 | } 58 | 59 | /** 60 | * Define the "api" routes for the application. 61 | * 62 | * These routes are typically stateless. 63 | * 64 | * @return void 65 | */ 66 | protected function mapApiRoutes() 67 | { 68 | Route::prefix('api') 69 | ->middleware('api') 70 | ->namespace($this->namespace) 71 | ->group(base_path('routes/api.php')); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 32 | 33 | $status = $kernel->handle( 34 | $input = new Symfony\Component\Console\Input\ArgvInput, 35 | new Symfony\Component\Console\Output\ConsoleOutput 36 | ); 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Shutdown The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once Artisan has finished running, we will fire off the shutdown events 44 | | so that any final work may be done by the application before we shut 45 | | down the process. This is the last thing to happen to the request. 46 | | 47 | */ 48 | 49 | $kernel->terminate($input, $status); 50 | 51 | exit($status); 52 | -------------------------------------------------------------------------------- /bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | SON\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | SON\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | SON\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /bootstrap/autoload.php: -------------------------------------------------------------------------------- 1 | =5.6.4", 9 | "kris/laravel-form-builder": "1.12.1", 10 | "laravel/framework": "5.4.*", 11 | "laravel/tinker": "~1.0", 12 | "patricktalmadge/bootstrapper": "5.10.2", 13 | "tymon/jwt-auth": "dev-develop#23034342c5eeacdcc0949a80ae4f2eada653f0ca", 14 | "barryvdh/laravel-ide-helper": "^2.4", 15 | "fzaninotto/faker": "~1.4" 16 | }, 17 | "require-dev": { 18 | "barryvdh/laravel-ide-helper": "^2.4", 19 | "fzaninotto/faker": "~1.4", 20 | "mockery/mockery": "0.9.*", 21 | "phpunit/phpunit": "~5.7" 22 | }, 23 | "autoload": { 24 | "classmap": [ 25 | "database" 26 | ], 27 | "psr-4": { 28 | "SON\\": "app/" 29 | } 30 | }, 31 | "autoload-dev": { 32 | "psr-4": { 33 | "Tests\\": "tests/" 34 | } 35 | }, 36 | "scripts": { 37 | "post-root-package-install": [ 38 | "php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 39 | ], 40 | "post-create-project-cmd": [ 41 | "php artisan key:generate" 42 | ], 43 | "post-install-cmd": [ 44 | "Illuminate\\Foundation\\ComposerScripts::postInstall", 45 | "php artisan optimize" 46 | ], 47 | "post-update-cmd": [ 48 | "Illuminate\\Foundation\\ComposerScripts::postUpdate", 49 | "php artisan ide-helper:generate", 50 | "php artisan ide-helper:meta", 51 | "php artisan optimize" 52 | ] 53 | }, 54 | "config": { 55 | "preferred-install": "dist", 56 | "sort-packages": true, 57 | "optimize-autoloader": true 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | // 40 | ], 41 | ], 42 | 43 | 'redis' => [ 44 | 'driver' => 'redis', 45 | 'connection' => 'default', 46 | ], 47 | 48 | 'log' => [ 49 | 'driver' => 'log', 50 | ], 51 | 52 | 'null' => [ 53 | 'driver' => 'null', 54 | ], 55 | 56 | ], 57 | 58 | ]; 59 | -------------------------------------------------------------------------------- /config/cache.php: -------------------------------------------------------------------------------- 1 | env('CACHE_DRIVER', 'file'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Cache Stores 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the cache "stores" for your application as 26 | | well as their drivers. You may even define multiple stores for the 27 | | same cache driver to group types of items stored in your caches. 28 | | 29 | */ 30 | 31 | 'stores' => [ 32 | 33 | 'apc' => [ 34 | 'driver' => 'apc', 35 | ], 36 | 37 | 'array' => [ 38 | 'driver' => 'array', 39 | ], 40 | 41 | 'database' => [ 42 | 'driver' => 'database', 43 | 'table' => 'cache', 44 | 'connection' => null, 45 | ], 46 | 47 | 'file' => [ 48 | 'driver' => 'file', 49 | 'path' => storage_path('framework/cache/data'), 50 | ], 51 | 52 | 'memcached' => [ 53 | 'driver' => 'memcached', 54 | 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), 55 | 'sasl' => [ 56 | env('MEMCACHED_USERNAME'), 57 | env('MEMCACHED_PASSWORD'), 58 | ], 59 | 'options' => [ 60 | // Memcached::OPT_CONNECT_TIMEOUT => 2000, 61 | ], 62 | 'servers' => [ 63 | [ 64 | 'host' => env('MEMCACHED_HOST', '127.0.0.1'), 65 | 'port' => env('MEMCACHED_PORT', 11211), 66 | 'weight' => 100, 67 | ], 68 | ], 69 | ], 70 | 71 | 'redis' => [ 72 | 'driver' => 'redis', 73 | 'connection' => 'default', 74 | ], 75 | 76 | ], 77 | 78 | /* 79 | |-------------------------------------------------------------------------- 80 | | Cache Key Prefix 81 | |-------------------------------------------------------------------------- 82 | | 83 | | When utilizing a RAM based store such as APC or Memcached, there might 84 | | be other applications utilizing the same cache. So, we'll specify a 85 | | value to get prefixed to all our keys so we can avoid collisions. 86 | | 87 | */ 88 | 89 | 'prefix' => 'laravel', 90 | 91 | ]; 92 | -------------------------------------------------------------------------------- /config/filesystems.php: -------------------------------------------------------------------------------- 1 | env('FILESYSTEM_DRIVER', 'local'), 17 | 18 | /* 19 | |-------------------------------------------------------------------------- 20 | | Default Cloud Filesystem Disk 21 | |-------------------------------------------------------------------------- 22 | | 23 | | Many applications store files both locally and in the cloud. For this 24 | | reason, you may specify a default "cloud" driver here. This driver 25 | | will be bound as the Cloud disk implementation in the container. 26 | | 27 | */ 28 | 29 | 'cloud' => env('FILESYSTEM_CLOUD', 's3'), 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Filesystem Disks 34 | |-------------------------------------------------------------------------- 35 | | 36 | | Here you may configure as many filesystem "disks" as you wish, and you 37 | | may even configure multiple disks of the same driver. Defaults have 38 | | been setup for each driver as an example of the required options. 39 | | 40 | | Supported Drivers: "local", "ftp", "s3", "rackspace" 41 | | 42 | */ 43 | 44 | 'disks' => [ 45 | 46 | 'local' => [ 47 | 'driver' => 'local', 48 | 'root' => storage_path('app'), 49 | ], 50 | 51 | 'public' => [ 52 | 'driver' => 'local', 53 | 'root' => storage_path('app/public'), 54 | 'url' => env('APP_URL').'/storage', 55 | 'visibility' => 'public', 56 | ], 57 | 58 | 's3' => [ 59 | 'driver' => 's3', 60 | 'key' => env('AWS_KEY'), 61 | 'secret' => env('AWS_SECRET'), 62 | 'region' => env('AWS_REGION'), 63 | 'bucket' => env('AWS_BUCKET'), 64 | ], 65 | 66 | ], 67 | 68 | ]; 69 | -------------------------------------------------------------------------------- /config/queue.php: -------------------------------------------------------------------------------- 1 | env('QUEUE_DRIVER', 'sync'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Queue Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may configure the connection information for each server that 26 | | is used by your application. A default configuration has been added 27 | | for each back-end shipped with Laravel. You are free to add more. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'sync' => [ 34 | 'driver' => 'sync', 35 | ], 36 | 37 | 'database' => [ 38 | 'driver' => 'database', 39 | 'table' => 'jobs', 40 | 'queue' => 'default', 41 | 'retry_after' => 90, 42 | ], 43 | 44 | 'beanstalkd' => [ 45 | 'driver' => 'beanstalkd', 46 | 'host' => 'localhost', 47 | 'queue' => 'default', 48 | 'retry_after' => 90, 49 | ], 50 | 51 | 'sqs' => [ 52 | 'driver' => 'sqs', 53 | 'key' => 'your-public-key', 54 | 'secret' => 'your-secret-key', 55 | 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', 56 | 'queue' => 'your-queue-name', 57 | 'region' => 'us-east-1', 58 | ], 59 | 60 | 'redis' => [ 61 | 'driver' => 'redis', 62 | 'connection' => 'default', 63 | 'queue' => 'default', 64 | 'retry_after' => 90, 65 | ], 66 | 67 | ], 68 | 69 | /* 70 | |-------------------------------------------------------------------------- 71 | | Failed Queue Jobs 72 | |-------------------------------------------------------------------------- 73 | | 74 | | These options configure the behavior of failed queue job logging so you 75 | | can control which database and table are used to store the jobs that 76 | | have failed. You may change them to any database / table you wish. 77 | | 78 | */ 79 | 80 | 'failed' => [ 81 | 'database' => env('DB_CONNECTION', 'mysql'), 82 | 'table' => 'failed_jobs', 83 | ], 84 | 85 | ]; 86 | -------------------------------------------------------------------------------- /config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | ], 21 | 22 | 'ses' => [ 23 | 'key' => env('SES_KEY'), 24 | 'secret' => env('SES_SECRET'), 25 | 'region' => 'us-east-1', 26 | ], 27 | 28 | 'sparkpost' => [ 29 | 'secret' => env('SPARKPOST_SECRET'), 30 | ], 31 | 32 | 'stripe' => [ 33 | 'model' => \SON\Models\User::class, 34 | 'key' => env('STRIPE_KEY'), 35 | 'secret' => env('STRIPE_SECRET'), 36 | ], 37 | 38 | ]; 39 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => realpath(storage_path('framework/views')), 32 | 33 | ]; 34 | -------------------------------------------------------------------------------- /database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite 2 | -------------------------------------------------------------------------------- /database/factories/ModelFactory.php: -------------------------------------------------------------------------------- 1 | define(\SON\Models\User::class, function (Faker\Generator $faker) { 16 | static $password; 17 | 18 | return [ 19 | 'name' => $faker->name, 20 | 'email' => $faker->unique()->safeEmail, 21 | 'password' => $password ?: $password = bcrypt('secret'), 22 | 'remember_token' => str_random(10), 23 | 'enrolment' => str_random(6) 24 | ]; 25 | }); 26 | 27 | $factory->define(\SON\Models\UserProfile::class, function (Faker\Generator $faker) { 28 | 29 | return [ 30 | 'address' => $faker->address, 31 | 'cep' => function() use($faker){ 32 | $cep = preg_replace('/[^0-9]/','',$faker->postcode()); 33 | return $cep; 34 | }, 35 | 'number' => rand(1,100), 36 | 'complement' => rand(1,10)%2==0?null:$faker->sentence, 37 | 'city' => $faker->city, 38 | 'neighborhood' => $faker->city, 39 | 'state' => collect(\SON\Models\State::$states)->random(), 40 | ]; 41 | }); 42 | 43 | $factory->define(\SON\Models\Subject::class, function (Faker\Generator $faker) { 44 | 45 | return [ 46 | 'name' => $faker->word, 47 | ]; 48 | }); 49 | 50 | 51 | $factory->define(\SON\Models\ClassInformation::class, function (Faker\Generator $faker) { 52 | 53 | return [ 54 | 'date_start' => $faker->date(), 55 | 'date_end' => $faker->date(), 56 | 'cycle' => rand(1,8), 57 | 'subdivision' => rand(1,16), 58 | 'semester' => rand(1,2), 59 | 'year' => rand(2017,2030), 60 | ]; 61 | }); 62 | 63 | $factory->define(\SON\Models\ClassTest::class, function (Faker\Generator $faker) { 64 | 65 | return [ 66 | 'date_start' => $faker->dateTimeBetween('now','+1 hour'), 67 | 'date_end' => $faker->dateTimeBetween('now','+1 hour'), 68 | 'name' => $faker->sentence(3), 69 | ]; 70 | }); 71 | 72 | $factory->define(\SON\Models\Question::class, function (Faker\Generator $faker) { 73 | 74 | return [ 75 | 'question' => "{$faker->sentence(6)}?", 76 | 'point' => $faker->randomFloat(2,1,3) 77 | ]; 78 | }); 79 | 80 | 81 | $factory->define(\SON\Models\QuestionChoice::class, function (Faker\Generator $faker) { 82 | 83 | return [ 84 | 'choice' => $faker->sentence(6) 85 | ]; 86 | }); 87 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->string('enrolment')->unique(); 21 | $table->string('password'); 22 | $table->nullableMorphs('userable'); 23 | $table->rememberToken(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('users'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2014_10_12_100000_create_password_resets_table.php: -------------------------------------------------------------------------------- 1 | string('email')->index(); 18 | $table->string('token'); 19 | $table->timestamp('created_at')->nullable(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('password_resets'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2017_07_18_215254_create_teachers_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->timestamps(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::dropIfExists('teachers'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /database/migrations/2017_07_18_215304_create_students_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->timestamps(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::dropIfExists('students'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /database/migrations/2017_07_18_215311_create_admins_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->timestamps(); 19 | }); 20 | } 21 | 22 | /** 23 | * Reverse the migrations. 24 | * 25 | * @return void 26 | */ 27 | public function down() 28 | { 29 | Schema::dropIfExists('admins'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /database/migrations/2017_07_18_221623_create_user_profiles_tables.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('address'); 19 | $table->string('cep', 8); 20 | $table->string('number'); 21 | $table->string('complement')->nullable(); 22 | $table->string('city'); 23 | $table->string('neighborhood'); 24 | $table->string('state', 2); 25 | $table->integer('user_id')->unsigned(); 26 | $table->foreign('user_id')->references('id')->on('users'); 27 | $table->timestamps(); 28 | }); 29 | } 30 | 31 | /** 32 | * Reverse the migrations. 33 | * 34 | * @return void 35 | */ 36 | public function down() 37 | { 38 | Schema::dropIfExists('user_profiles'); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /database/migrations/2017_07_19_171120_create_class_informations.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->date('date_start'); 19 | $table->date('date_end'); 20 | $table->string('cycle'); 21 | $table->string('subdivision')->nullable(); 22 | $table->integer('semester'); 23 | $table->integer('year'); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('class_informations'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2017_07_19_173844_create_subjects_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->string('name'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | 23 | /** 24 | * Reverse the migrations. 25 | * 26 | * @return void 27 | */ 28 | public function down() 29 | { 30 | Schema::dropIfExists('subjects'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /database/migrations/2017_07_26_002618_create_class_information_student_table.php: -------------------------------------------------------------------------------- 1 | integer('student_id')->unsigned(); 19 | $table->foreign('student_id')->references('id')->on('students'); 20 | 21 | $table->integer('class_information_id')->unsigned(); 22 | $table->foreign('class_information_id')->references('id')->on('class_informations'); 23 | 24 | $table->unique(['student_id','class_information_id']); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('class_information_student'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2017_08_01_233524_create_class_teachings_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->integer('subject_id')->unsigned(); 19 | $table->foreign('subject_id')->references('id')->on('subjects'); 20 | $table->integer('class_information_id')->unsigned(); 21 | $table->foreign('class_information_id')->references('id')->on('class_informations'); 22 | $table->integer('teacher_id')->unsigned(); 23 | $table->foreign('teacher_id')->references('id')->on('teachers'); 24 | $table->unique(['subject_id','class_information_id','teacher_id'],'class_teaching_unique'); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('class_teachings'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2017_08_22_193453_create_class_tests_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->dateTime('date_start'); 19 | $table->dateTime('date_end'); 20 | $table->string('name'); 21 | $table->integer('class_teaching_id')->unsigned(); 22 | $table->foreign('class_teaching_id')->references('id')->on('class_teachings'); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('class_tests'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2017_08_22_193530_create_questions_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->text('question'); 19 | $table->float('point'); 20 | $table->integer('class_test_id')->unsigned(); 21 | $table->foreign('class_test_id')->references('id')->on('class_tests'); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('questions'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /database/migrations/2017_08_22_193547_create_question_choices_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 19 | $table->text('choice'); 20 | $table->boolean('true')->default(false); 21 | $table->integer('question_id')->unsigned(); 22 | $table->foreign('question_id')->references('id')->on('questions'); 23 | $table->timestamps(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('question_choices'); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/migrations/2017_08_29_012930_create_student_class_tests_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->integer('student_id')->unsigned(); 19 | $table->foreign('student_id')->references('id')->on('students'); 20 | $table->integer('class_test_id')->unsigned(); 21 | $table->foreign('class_test_id')->references('id')->on('class_tests'); 22 | $table->float('point')->default(0); 23 | //$table->unique(['student_id','class_test_id']); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('student_class_tests'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/migrations/2017_08_29_012950_create_student_question_choices_table.php: -------------------------------------------------------------------------------- 1 | increments('id'); 18 | $table->integer('question_id')->unsigned(); 19 | $table->foreign('question_id')->references('id')->on('questions'); 20 | $table->integer('question_choice_id')->unsigned(); 21 | $table->foreign('question_choice_id')->references('id')->on('question_choices'); 22 | $table->integer('student_class_test_id')->unsigned(); 23 | $table->foreign('student_class_test_id')->references('id')->on('student_class_tests'); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('student_question_choices'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /database/seeds/ClassInformationsTableSeeder.php: -------------------------------------------------------------------------------- 1 | create() 19 | ->each(function(\SON\Models\ClassInformation $model) use($students,$teachers,$subjects){ 20 | /** @var \Illuminate\Support\Collection $studentsCol */ 21 | $studentsCol = $students->random(10); 22 | $model->students()->attach($studentsCol->pluck('id')); 23 | 24 | $teaching = rand(3,9); 25 | 26 | $teachersCol = $teachers->random($teaching); 27 | $subjectsCol = $subjects->random($teaching); 28 | foreach (range(1,$teaching) as $value){ 29 | $model->teachings()->create([ 30 | 'subject_id' => $subjectsCol->get($value-1)->id, 31 | 'teacher_id' => $teachersCol->get($value-1)->id, 32 | ]); 33 | } 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /database/seeds/ClassTestsTableSeeder.php: -------------------------------------------------------------------------------- 1 | make() 25 | ->each(function (ClassTest $model) use($classTeachings,$teacherDefault,$self){ 26 | $classTeaching = $classTeachings 27 | ->where('teacher_id',$teacherDefault->id) 28 | ->random(); 29 | $model->classTeaching()->associate($classTeaching); 30 | $model->save(); 31 | $self->createQuestions($model); 32 | }); 33 | 34 | factory(ClassTest::class,100) 35 | ->make() 36 | ->each(function (ClassTest $model) use($classTeachings,$self){ 37 | if(!$model->class_teaching_id){ 38 | $classTeaching = $classTeachings->random(); 39 | $model->classTeaching()->associate($classTeaching); 40 | $model->save(); 41 | $self->createQuestions($model); 42 | } 43 | }); 44 | } 45 | 46 | protected function createQuestions(ClassTest $classTest){ 47 | $questions = factory(Question::class, 4)->create([ 48 | 'class_test_id' => $classTest->id 49 | ]); 50 | 51 | $this->createChoices($questions); 52 | } 53 | 54 | protected function createChoices(Collection $questions){ 55 | $questions->each(function(Question $question){ 56 | $choices = factory(\SON\Models\QuestionChoice::class, 4)->create([ 57 | 'question_id' => $question->id 58 | ]); 59 | $choiceFirst = $choices->first(); 60 | $choiceFirst->true = true; 61 | $choiceFirst->save(); 62 | }); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /database/seeds/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | call(UsersTableSeeder::class); 15 | $this->call(SubjectsTableSeeder::class); 16 | $this->call(ClassInformationsTableSeeder::class); 17 | $this->call(ClassTestsTableSeeder::class); 18 | $this->call(StudentClassTestTableSeeder::class); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /database/seeds/StudentClassTestTableSeeder.php: -------------------------------------------------------------------------------- 1 | get(); 15 | 16 | foreach ($classTests as $classTest){ 17 | $classTeaching = $classTest->classTeaching; 18 | $classInformation = $classTeaching->classInformation; 19 | $students = $classInformation->students; 20 | $totalStudents = (int)($students->count() * 0.7); 21 | $studentsRandom = $students->random($totalStudents); 22 | $halfStudents = $studentsRandom->count()/2; 23 | $studentsRandom100 = $studentsRandom->slice(0,$halfStudents); 24 | $self = $this; 25 | $studentsRandom100->each(function($student) use($self,$classTest){ 26 | $self->makeResults($student,$classTest,1); 27 | }); 28 | $studentsRandom60 = $studentsRandom->slice($halfStudents,$studentsRandom->count()); 29 | $studentsRandom60->each(function($student) use($self,$classTest){ 30 | $self->makeResults($student,$classTest,0.6); 31 | }); 32 | } 33 | } 34 | 35 | public function makeResults($student,$classTest, $perc){ 36 | $questions = $classTest->questions; 37 | $numQuestionsCorrect = (int)($questions->count() * $perc); 38 | $questionsCorrect = $questions->slice(0,$numQuestionsCorrect); 39 | $questionsIncorrect = $questions->slice($numQuestionsCorrect,$questions->count()); 40 | $choices = []; 41 | foreach ($questionsCorrect as $question){ 42 | $choices[] = [ 43 | 'question_id' => $question->id, 44 | 'question_choice_id' => $question->choices->first()->id 45 | ]; 46 | } 47 | 48 | foreach ($questionsIncorrect as $question){ 49 | $choices[] = [ 50 | 'question_id' => $question->id, 51 | 'question_choice_id' => $question->choices->last()->id 52 | ]; 53 | } 54 | 55 | \Illuminate\Database\Eloquent\Model::reguard(); 56 | \SON\Models\StudentClassTest::createFully([ 57 | 'class_test_id' => $classTest->id, 58 | 'student_id' => $student->id, 59 | 'choices' => $choices 60 | ]); 61 | \Illuminate\Database\Eloquent\Model::unguard(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /database/seeds/SubjectsTableSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /database/seeds/UsersTableSeeder.php: -------------------------------------------------------------------------------- 1 | create([ 17 | 'email' => 'admin@user.com', 18 | 'enrolment' => 100000 19 | ])->each(function(User $user){ 20 | $profile = factory(UserProfile::class)->make(); 21 | $user->profile()->create($profile->toArray()); 22 | User::assingRole($user, User::ROLE_ADMIN); 23 | $user->save(); 24 | }); 25 | 26 | factory(User::class)->create([ 27 | 'email' => 'teacher@user.com', 28 | 'enrolment' => 400000 29 | ])->each(function(User $user){ 30 | if(!$user->userable) { 31 | $profile = factory(UserProfile::class)->make(); 32 | $user->profile()->create($profile->toArray()); 33 | User::assingRole($user, User::ROLE_TEACHER); 34 | $user->save(); 35 | } 36 | }); 37 | 38 | factory(User::class)->create([ 39 | 'email' => 'student@user.com', 40 | 'enrolment' => 700000 41 | ])->each(function(User $user){ 42 | if(!$user->userable) { 43 | $profile = factory(UserProfile::class)->make(); 44 | $user->profile()->create($profile->toArray()); 45 | User::assingRole($user, User::ROLE_STUDENT); 46 | $user->save(); 47 | } 48 | }); 49 | 50 | factory(User::class,100)->create()->each(function(User $user){ 51 | if(!$user->userable) { 52 | $profile = factory(UserProfile::class)->make(); 53 | $user->profile()->create($profile->toArray()); 54 | User::assingRole($user, User::ROLE_TEACHER); 55 | User::assignEnrolment(new User(), User::ROLE_TEACHER); 56 | $user->save(); 57 | } 58 | }); 59 | 60 | factory(User::class,100)->create()->each(function(User $user){ 61 | if(!$user->userable) { 62 | $profile = factory(UserProfile::class)->make(); 63 | $user->profile()->create($profile->toArray()); 64 | User::assingRole($user, User::ROLE_STUDENT); 65 | User::assignEnrolment(new User(), User::ROLE_STUDENT); 66 | $user->save(); 67 | } 68 | }); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "axios": "^0.16.2", 14 | "bootstrap-sass": "^3.3.7", 15 | "browser-sync": "^2.18.13", 16 | "browser-sync-webpack-plugin": "^1.2.0", 17 | "buffer": "^5.0.7", 18 | "cross-env": "^5.0.1", 19 | "jquery": "^3.1.1", 20 | "laravel-mix": "^1.0", 21 | "lodash": "^4.17.4", 22 | "moment": "^2.18.1", 23 | "pnotify": "^3.2.0", 24 | "scriptjs": "^2.5.8", 25 | "select2": "^4.0.3", 26 | "vue": "^2.1.10", 27 | "vue-deepset": "^0.5.1", 28 | "vue-resource": "^1.3.4", 29 | "vue-router": "^2.7.0", 30 | "vuex": "^2.3.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests/Feature 14 | 15 | 16 | 17 | ./tests/Unit 18 | 19 | 20 | 21 | 22 | ./app 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Redirect Trailing Slashes If Not A Folder... 9 | RewriteCond %{REQUEST_FILENAME} !-d 10 | RewriteRule ^(.*)/$ /$1 [L,R=301] 11 | 12 | # Handle Front Controller... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_FILENAME} !-f 15 | RewriteRule ^ index.php [L] 16 | 17 | # Handle Authorization Header 18 | RewriteCond %{HTTP:Authorization} . 19 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 20 | 21 | -------------------------------------------------------------------------------- /public/css/admin.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"\\css\\admin.css","sources":[],"mappings":";;;;;;;;;;;;;;A","sourceRoot":""} -------------------------------------------------------------------------------- /public/css/spa.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"\\css\\spa.css","sources":[],"mappings":";;;;;;;;;;;;;;A","sourceRoot":""} -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schoolofnetcom/pp-laravel54-vuejs-edu/75ddf0d675eefdeb8f12b50183b9d591d462acc1/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schoolofnetcom/pp-laravel54-vuejs-edu/75ddf0d675eefdeb8f12b50183b9d591d462acc1/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schoolofnetcom/pp-laravel54-vuejs-edu/75ddf0d675eefdeb8f12b50183b9d591d462acc1/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schoolofnetcom/pp-laravel54-vuejs-edu/75ddf0d675eefdeb8f12b50183b9d591d462acc1/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/schoolofnetcom/pp-laravel54-vuejs-edu/75ddf0d675eefdeb8f12b50183b9d591d462acc1/public/fonts/vendor/bootstrap-sass/bootstrap/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | /* 11 | |-------------------------------------------------------------------------- 12 | | Register The Auto Loader 13 | |-------------------------------------------------------------------------- 14 | | 15 | | Composer provides a convenient, automatically generated class loader for 16 | | our application. We just need to utilize it! We'll simply require it 17 | | into the script here so that we don't have to worry about manual 18 | | loading any of our classes later on. It feels great to relax. 19 | | 20 | */ 21 | 22 | require __DIR__.'/../bootstrap/autoload.php'; 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Turn On The Lights 27 | |-------------------------------------------------------------------------- 28 | | 29 | | We need to illuminate PHP development, so let us turn on the lights. 30 | | This bootstraps the framework and gets it ready for use, then it 31 | | will load up this application so that we can run it and send 32 | | the responses back to the browser and delight our users. 33 | | 34 | */ 35 | 36 | $app = require_once __DIR__.'/../bootstrap/app.php'; 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Run The Application 41 | |-------------------------------------------------------------------------- 42 | | 43 | | Once we have the application, we can handle the incoming request 44 | | through the kernel, and send the associated response back to 45 | | the client's browser allowing them to enjoy the creative 46 | | and wonderful application we have prepared for them. 47 | | 48 | */ 49 | 50 | $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); 51 | 52 | $response = $kernel->handle( 53 | $request = Illuminate\Http\Request::capture() 54 | ); 55 | 56 | $response->send(); 57 | 58 | $kernel->terminate($request, $response); 59 | -------------------------------------------------------------------------------- /public/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/spa.js": "/js/spa.js", 3 | "/js/admin.js": "/js/admin.js", 4 | "/css/admin.css": "/css/admin.css", 5 | "/css/spa.css": "/css/spa.css" 6 | } -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /resources/assets/admin/js/admin.js: -------------------------------------------------------------------------------- 1 | 2 | require('./bootstrap'); 3 | 4 | window.Vue = require('vue'); 5 | 6 | Vue.component('example', require('./components/Example.vue')); 7 | Vue.component('class-student', require('./components/class_information/ClassStudent.vue')); 8 | Vue.component('class-teaching', require('./components/class_information/ClassTeaching.vue')); 9 | 10 | const app = new Vue({ 11 | el: '#app' 12 | }); -------------------------------------------------------------------------------- /resources/assets/admin/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | 2 | try { 3 | window.$ = window.jQuery = require('jquery'); 4 | 5 | require('bootstrap-sass'); 6 | window.PNotify = require('pnotify'); 7 | require('pnotify/src/pnotify.buttons'); 8 | } catch (e) {} -------------------------------------------------------------------------------- /resources/assets/admin/js/components/Example.vue: -------------------------------------------------------------------------------- 1 | 16 | 17 | 24 | -------------------------------------------------------------------------------- /resources/assets/admin/js/services/adminConfig.js: -------------------------------------------------------------------------------- 1 | const location = window.location; 2 | 3 | export default { 4 | HOST: `${location.protocol}//${location.hostname}:${location.port}`, 5 | //HOST: 'http://br326.teste.website/~devol190', 6 | get API_URL(){ //students,te 7 | return `${this.HOST}/admin/api`; 8 | }, 9 | get ADMIN_URL(){ //students da turma, 10 | return `${this.HOST}/admin`; 11 | } 12 | }; -------------------------------------------------------------------------------- /resources/assets/admin/js/services/resources.js: -------------------------------------------------------------------------------- 1 | import 'vue-resource'; 2 | import ADMIN_CONFIG from './adminConfig'; 3 | import Vue from 'vue'; 4 | 5 | Vue.http.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content'); 6 | 7 | let ClassStudent = Vue.resource(`${ADMIN_CONFIG.ADMIN_URL}/class_informations/{class_information}/students/{student}`); 8 | let ClassTeaching = Vue.resource(`${ADMIN_CONFIG.ADMIN_URL}/class_informations/{class_information}/teachings/{teaching}`); 9 | 10 | export { 11 | ClassStudent, ClassTeaching 12 | }; -------------------------------------------------------------------------------- /resources/assets/admin/js/store/class_student.js: -------------------------------------------------------------------------------- 1 | import {ClassStudent} from '../services/resources'; 2 | import Vue from 'vue'; 3 | import ADMIN_CONFIG from '../services/adminConfig'; 4 | 5 | const state = { 6 | students: [] 7 | }; 8 | 9 | const mutations = { 10 | add(state, student){ 11 | state.students.push(student); 12 | }, 13 | set(state,students){ 14 | state.students = students; 15 | }, 16 | destroy(state,studentId){ 17 | let index = state.students.findIndex((item) => { 18 | return item.id == studentId; 19 | }); 20 | if(index!=-1){ 21 | state.students.splice(index,1); 22 | } 23 | } 24 | }; 25 | 26 | const actions = { 27 | query(context,classInformationId){ 28 | return Vue.http.get(`${ADMIN_CONFIG.ADMIN_URL}/class_informations/${classInformationId}/students`) 29 | .then(response => { 30 | context.commit('set',response.data); 31 | }) 32 | }, 33 | store(context, {studentId, classInformationId}){ 34 | return ClassStudent.save({class_information: classInformationId},{student_id: studentId}) 35 | .then(response => { 36 | context.commit('add',response.data) 37 | }) 38 | }, 39 | destroy(context,{studentId, classInformationId}){ 40 | return ClassStudent.delete({class_information: classInformationId,student: studentId}) 41 | .then(response => { 42 | context.commit('destroy',studentId) 43 | }); 44 | } 45 | }; 46 | 47 | const module = { 48 | namespaced: true, 49 | state,mutations,actions 50 | }; 51 | 52 | export default module; -------------------------------------------------------------------------------- /resources/assets/admin/js/store/class_teaching.js: -------------------------------------------------------------------------------- 1 | import {ClassTeaching} from '../services/resources'; 2 | import Vue from 'vue'; 3 | import ADMIN_CONFIG from '../services/adminConfig'; 4 | 5 | const state = { 6 | teachings: [] 7 | }; 8 | 9 | const mutations = { 10 | add(state, student){ 11 | state.teachings.push(student); 12 | }, 13 | set(state,teachings){ 14 | state.teachings = teachings; 15 | }, 16 | destroy(state,teachingId){ 17 | let index = state.teachings.findIndex((item) => { 18 | return item.id == teachingId; 19 | }); 20 | if(index!=-1){ 21 | state.teachings.splice(index,1); 22 | } 23 | } 24 | }; 25 | 26 | const actions = { 27 | query(context,classInformationId){ 28 | return Vue.http.get(`${ADMIN_CONFIG.ADMIN_URL}/class_informations/${classInformationId}/teachings`) 29 | .then(response => { 30 | context.commit('set',response.data); 31 | }) 32 | }, 33 | store(context, {teacherId,subjectId, classInformationId}){ 34 | return ClassTeaching.save({class_information: classInformationId}, 35 | {teacher_id: teacherId,subject_id: subjectId} 36 | ) 37 | .then(response => { 38 | context.commit('add',response.data) 39 | }); 40 | }, 41 | destroy(context,{teachingId, classInformationId}){ 42 | return ClassTeaching.delete({class_information: classInformationId,teaching: teachingId}) 43 | .then(response => { 44 | context.commit('destroy',teachingId) 45 | }); 46 | } 47 | }; 48 | 49 | const module = { 50 | namespaced: true, 51 | state,mutations,actions 52 | }; 53 | 54 | export default module; -------------------------------------------------------------------------------- /resources/assets/admin/js/store/store.js: -------------------------------------------------------------------------------- 1 | import Vuex from 'vuex'; 2 | import classStudent from './class_student'; 3 | import classTeaching from './class_teaching'; 4 | 5 | export default new Vuex.Store({ 6 | modules: { 7 | classStudent, classTeaching 8 | } 9 | }); -------------------------------------------------------------------------------- /resources/assets/admin/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | // Body 3 | $body-bg: #f5f8fa; 4 | 5 | // Borders 6 | $laravel-border-color: darken($body-bg, 10%); 7 | $list-group-border: $laravel-border-color; 8 | $navbar-default-border: $laravel-border-color; 9 | $panel-default-border: $laravel-border-color; 10 | $panel-inner-border: $laravel-border-color; 11 | 12 | // Brands 13 | $brand-primary: #3097D1; 14 | $brand-info: #8eb4cb; 15 | $brand-success: #2ab27b; 16 | $brand-warning: #cbb956; 17 | $brand-danger: #bf5329; 18 | 19 | // Typography 20 | $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/"; 21 | $font-family-sans-serif: "Raleway", sans-serif; 22 | $font-size-base: 14px; 23 | $line-height-base: 1.6; 24 | $text-color: #636b6f; 25 | 26 | // Navbar 27 | $navbar-default-bg: #fff; 28 | 29 | // Buttons 30 | $btn-default-color: $text-color; 31 | 32 | // Inputs 33 | $input-border: lighten($text-color, 40%); 34 | $input-border-focus: lighten($brand-primary, 25%); 35 | $input-color-placeholder: lighten($text-color, 30%); 36 | 37 | // Panels 38 | $panel-default-heading-bg: #fff; 39 | -------------------------------------------------------------------------------- /resources/assets/admin/sass/admin.scss: -------------------------------------------------------------------------------- 1 | 2 | // Fonts 3 | @import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600"); 4 | 5 | // Variables 6 | @import "variables"; 7 | 8 | @import "node_modules/pnotify/src/pnotify"; 9 | @import "node_modules/pnotify/src/pnotify.brighttheme"; 10 | @import "node_modules/pnotify/src/pnotify.buttons"; 11 | @import "node_modules/select2/src/scss/core"; 12 | // Bootstrap 13 | @import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap"; -------------------------------------------------------------------------------- /resources/assets/spa/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | 2 | try { 3 | window.$ = window.jQuery = require('jquery'); 4 | 5 | require('bootstrap-sass'); 6 | window.PNotify = require('pnotify'); 7 | require('pnotify/src/pnotify.buttons'); 8 | } catch (e) {} -------------------------------------------------------------------------------- /resources/assets/spa/js/components/App.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/Login.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/Logout.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/student/StudentClassInformationList.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/student/StudentClassTeachingList.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/student/StudentMenu.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/student/class_test/StudentClassTestQuestion.vue: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/teacher/TeacherClassInformationList.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/teacher/TeacherClassTeachingList.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/teacher/TeacherMenu.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/teacher/class_test/TeacherClassTestQuestionForm.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/teacher/class_test/TeacherClassTestQuestionList.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | -------------------------------------------------------------------------------- /resources/assets/spa/js/components/templates/menu.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /resources/assets/spa/js/filters.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | Vue.filter('dateBr', function (value) { //0000-00-00 4 | if (value && value.length >= 10) { 5 | let dateArray = value.substring(0, 10).split('-'); 6 | if (dateArray.length === 3) { 7 | return dateArray.reverse().join('/'); 8 | } 9 | } 10 | return value; 11 | }); 12 | 13 | Vue.filter('dateTimeBr', function (value) { //0000-00-00 14 | if (value && value.length >= 16) { 15 | let dateArray = value.substring(0, 10).split('-'); 16 | if (dateArray.length === 3) { 17 | return dateArray.reverse().join('/').replace('T',''); 18 | } 19 | } 20 | return value; 21 | }); 22 | 23 | Vue.filter('classInformationAlias', function(classInformation){ 24 | return `${classInformation.cycle}.${classInformation.subdivision}.${classInformation.semester}.${classInformation.year}`; 25 | }) -------------------------------------------------------------------------------- /resources/assets/spa/js/mixins/auth.mixin.js: -------------------------------------------------------------------------------- 1 | import store from '../store/store'; 2 | 3 | export default { 4 | computed: { 5 | isAuth(){ 6 | return store.state.auth.check; 7 | }, 8 | user(){ 9 | return store.state.auth.user; 10 | }, 11 | username(){ 12 | return this.isAuth?store.state.auth.user.name:null; 13 | }, 14 | isTeacher(){ 15 | return store.getters['auth/isTeacher']; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/mixins/class_information.mixin.js: -------------------------------------------------------------------------------- 1 | import store from '../store/store'; 2 | 3 | export default { 4 | computed: { 5 | classTeaching() { 6 | return store.state[this.storeType].classTeaching.classTeaching; 7 | }, 8 | classInformation() { 9 | return !this.classTeaching ? null : this.classTeaching.class_information; 10 | }, 11 | classInformationName() { 12 | if(this.classInformation){ 13 | let classInformationAlias = this.$options.filters.classInformationAlias(this.classInformation); 14 | return `${classInformationAlias} - ${this.classTeaching.subject.name}`; 15 | } 16 | 17 | return ''; 18 | }, 19 | } 20 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/mixins/menu.mixin.js: -------------------------------------------------------------------------------- 1 | import LogoutComponent from '../components/Logout.vue'; 2 | import authMixin from './auth.mixin'; 3 | 4 | export default { 5 | components: { 6 | 'logout': LogoutComponent 7 | }, 8 | mixins: [authMixin], 9 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/router.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import VueRouter from 'vue-router'; 3 | import routes from './router.map'; 4 | import AppComponent from './components/App.vue'; 5 | import store from './store/store'; 6 | 7 | const router = new VueRouter({ 8 | routes 9 | }); 10 | 11 | router.beforeEach((to, from, next) => { 12 | if (to.meta.auth && !store.state.auth.check) { 13 | return router.push({name: 'login'}); 14 | } 15 | next(); 16 | }); 17 | 18 | router.beforeEach((to, from, next) => { 19 | if(store.state.auth.user){ 20 | if(store.getters['auth/isTeacher'] && to.name.startsWith('student')){ 21 | return router.push({name: 'teacher.class_teachings.list'}); 22 | } 23 | if(store.getters['auth/isStudent'] && to.name.startsWith('teacher')){ 24 | return router.push({name: 'student.class_informations.list'}); 25 | } 26 | } 27 | next(); 28 | }); 29 | 30 | new Vue({ 31 | store, 32 | router, 33 | el: '#app', 34 | components: { 35 | 'app': AppComponent 36 | } 37 | }); 38 | 39 | export default router; -------------------------------------------------------------------------------- /resources/assets/spa/js/services/jwt-token.js: -------------------------------------------------------------------------------- 1 | import {Jwt} from './resources'; 2 | import LocalStorage from './localstorage'; 3 | import {Buffer} from 'buffer/'; 4 | 5 | const payloadToObject = (token) => { 6 | let payload = token.split('.')[1]; 7 | //return JSON.parse(atob(payload)); 8 | return JSON.parse(Buffer.from(payload,'base64').toString()); 9 | }; 10 | 11 | const TOKEN = 'token' 12 | 13 | export default { 14 | get token(){ 15 | return LocalStorage.get(TOKEN); 16 | }, 17 | set token(value){ 18 | value ? LocalStorage.set(TOKEN,value):LocalStorage.remove(TOKEN); 19 | }, 20 | get payload(){ 21 | return this.token!=null?payloadToObject(this.token):null; 22 | }, 23 | accessToken(username, password){ 24 | return Jwt.accessToken(username,password) 25 | .then((response) => { 26 | this.token = response.data.token; 27 | }) 28 | }, 29 | revokeToken(){ 30 | let afterRevokeToken = () => { 31 | this.token = null; 32 | }; 33 | return Jwt.logout() 34 | .then(afterRevokeToken) 35 | .catch(afterRevokeToken); 36 | }, 37 | getAuthorizationHeader(){ 38 | return `Bearer ${LocalStorage.get(TOKEN)}`; 39 | } 40 | }; -------------------------------------------------------------------------------- /resources/assets/spa/js/services/localstorage.js: -------------------------------------------------------------------------------- 1 | export default { 2 | set(key, value){ //string, inteiro, boolean 3 | window.localStorage[key] = value; 4 | return window.localStorage[key]; 5 | }, 6 | get(key, defaultValue = null){ //string, inteiro, boolean 7 | return window.localStorage[key] || defaultValue; 8 | }, 9 | setObject(key, value){ 10 | window.localStorage[key] = JSON.stringify(value); 11 | return this.getObject(key); 12 | }, 13 | getObject(key){ 14 | return JSON.parse(window.localStorage[key] || null); 15 | }, 16 | remove(key){ 17 | window.localStorage.removeItem(key); 18 | } 19 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/services/resources.js: -------------------------------------------------------------------------------- 1 | import 'vue-resource'; 2 | import SPA_CONFIG from './spaConfig'; 3 | import Vue from 'vue'; 4 | import JwtToken from './jwt-token'; 5 | import store from '../store/store'; 6 | import router from '../router'; 7 | 8 | Vue.http.options.root = SPA_CONFIG.API_URL; 9 | 10 | Vue.http.interceptors.push((request,next) => { 11 | if(JwtToken.token) { 12 | request.headers.set('Authorization', JwtToken.getAuthorizationHeader()); 13 | } 14 | next(); 15 | }); 16 | 17 | Vue.http.interceptors.push((request,next) => { 18 | next((response) => { 19 | let authorization = response.headers.get('Authorization'); 20 | if(authorization){ 21 | JwtToken.token = authorization.split(' ')[1]; 22 | } 23 | switch (response.status){ 24 | case 401: 25 | JwtToken.token = null; 26 | store.commit('auth/unauthenticated'); 27 | return router.push({name: 'login'}); 28 | } 29 | }) 30 | }); 31 | 32 | export class Jwt{ 33 | static accessToken(username, password){ 34 | return Vue.http.post('access_token',{username,password}); 35 | } 36 | 37 | static logout(){ 38 | return Vue.http.post('logout'); 39 | } 40 | } 41 | 42 | const Teacher = { 43 | classInformation: Vue.resource('teacher/class_informations/{class_information}'), 44 | classTeaching: Vue.resource('teacher/class_teachings/{class_teaching}'), 45 | classTest: Vue.resource('teacher/class_teachings/{class_teaching}/class_tests/{class_test}') 46 | }; 47 | 48 | const Student = { 49 | classInformation: Vue.resource('student/class_informations/{class_information}'), 50 | classTeaching: Vue.resource('student/class_informations/{class_information}/class_teachings/{class_teaching}'), 51 | classTest: Vue.resource('student/class_teachings/{class_teaching}/class_tests/{class_test}'), 52 | studentClassTest: Vue.resource('student/class_tests/{class_test}/do/{student_class_test}'), 53 | classTestResult: Vue.resource('',{},{ 54 | perSubject: { 55 | method: 'GET', 56 | url: 'student/class_tests/results/per_subject?class_teaching={class_teaching}' 57 | } 58 | }) 59 | }; 60 | 61 | export { 62 | Teacher, Student 63 | }; -------------------------------------------------------------------------------- /resources/assets/spa/js/services/spaConfig.js: -------------------------------------------------------------------------------- 1 | const location = window.location; 2 | 3 | export default { 4 | HOST: `${location.protocol}//${location.hostname}:${location.port}`, 5 | //HOST: 'http://br326.teste.website/~devol190', 6 | get API_URL(){ 7 | return `${this.HOST}/api`; 8 | }, 9 | }; -------------------------------------------------------------------------------- /resources/assets/spa/js/spa.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * First we will load all of this project's JavaScript dependencies which 4 | * includes Vue and other libraries. It is a great starting point when 5 | * building robust, powerful web applications using Vue and Laravel. 6 | */ 7 | 8 | require('./bootstrap'); 9 | 10 | window.Vue = require('vue'); 11 | require('./filters'); 12 | require('./router'); -------------------------------------------------------------------------------- /resources/assets/spa/js/store/auth.js: -------------------------------------------------------------------------------- 1 | import JwtToken from '../services/jwt-token'; 2 | 3 | const ROLE_TEACHER = 2; 4 | const ROLE_STUDENT = 3; 5 | 6 | const state = { 7 | user: JwtToken.payload != null ? JwtToken.payload.user : null, 8 | check: JwtToken.token != null 9 | }; 10 | 11 | const mutations = { 12 | authenticated(state){ 13 | state.check = true; 14 | state.user = JwtToken.payload.user; 15 | }, 16 | unauthenticated(state){ 17 | state.check = false; 18 | state.user = null; 19 | } 20 | }; 21 | 22 | const actions = { 23 | login(context, {username, password}){ 24 | return JwtToken.accessToken(username, password) 25 | .then(() => { 26 | context.commit('authenticated'); 27 | }); 28 | }, 29 | logout(context){ 30 | let afterLogout = () => { 31 | context.commit('unauthenticated'); 32 | }; 33 | return JwtToken.revokeToken() 34 | .then(afterLogout) 35 | .catch(afterLogout); 36 | } 37 | }; 38 | 39 | const getters = { 40 | isTeacher(state){ 41 | return state.user && state.user.role == ROLE_TEACHER; 42 | }, 43 | isStudent(state){ 44 | return state.user && state.user.role == ROLE_STUDENT; 45 | } 46 | } 47 | 48 | const module = { 49 | namespaced: true, 50 | state, mutations, actions, getters 51 | }; 52 | 53 | export default module; -------------------------------------------------------------------------------- /resources/assets/spa/js/store/store.js: -------------------------------------------------------------------------------- 1 | import Vuex from 'vuex'; 2 | import Vue from 'vue'; 3 | import auth from './auth'; 4 | import teacher from './teacher'; 5 | import student from './student'; 6 | import * as VueDeepSet from 'vue-deepset'; 7 | 8 | Vue.use(VueDeepSet); 9 | 10 | export default new Vuex.Store({ 11 | mutations: VueDeepSet.extendMutation(), 12 | modules: { 13 | auth, teacher, student 14 | } 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /resources/assets/spa/js/store/student.js: -------------------------------------------------------------------------------- 1 | import classInformation from './student/class_information'; 2 | import classTeaching from './student/class_teaching'; 3 | import classTest from './student/class_test'; 4 | import studentClassTest from './student/student_class_test'; 5 | 6 | const module = { 7 | namespaced: true, 8 | modules: { 9 | classInformation, classTeaching, classTest,studentClassTest 10 | } 11 | }; 12 | 13 | export default module; -------------------------------------------------------------------------------- /resources/assets/spa/js/store/student/class_information.js: -------------------------------------------------------------------------------- 1 | import {Student} from '../../services/resources'; 2 | 3 | const state = { 4 | classInformations: [], 5 | classInformation: null 6 | }; 7 | 8 | const mutations = { 9 | setClassInformations(state,classInformations){ 10 | state.classInformations = classInformations; 11 | }, 12 | setClassInformation(state, classInformation){ 13 | state.classInformation = classInformation; 14 | } 15 | }; 16 | 17 | const actions = { 18 | query(context){ 19 | Student.classInformation.query() 20 | .then(response => { 21 | context.commit('setClassInformations',response.data); 22 | }); 23 | }, 24 | get(context, classInformationId){ 25 | Student.classInformation.get({class_information: classInformationId}) 26 | .then(response => { 27 | context.commit('setClassInformation',response.data); 28 | }) 29 | } 30 | }; 31 | 32 | export default { 33 | namespaced: true, 34 | state, mutations,actions 35 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/store/student/class_teaching.js: -------------------------------------------------------------------------------- 1 | import {Student} from '../../services/resources'; 2 | 3 | const state = { 4 | classTeachings: [], 5 | classTeaching: null 6 | }; 7 | 8 | const mutations = { 9 | setClassTeachings(state,classTeachings){ 10 | state.classTeachings = classTeachings; 11 | }, 12 | setClassTeaching(state, classTeaching){ 13 | state.classTeaching = classTeaching; 14 | } 15 | }; 16 | 17 | const actions = { 18 | query(context,classInformationId){ 19 | return Student.classTeaching.query({class_information: classInformationId}) 20 | .then(response => { 21 | context.commit('setClassTeachings',response.data); 22 | }); 23 | }, 24 | get(context, {classInformationId, classTeachingId}){ 25 | return Student.classTeaching.get({class_information: classInformationId,class_teaching: classTeachingId}) 26 | .then(response => { 27 | context.commit('setClassTeaching',response.data); 28 | }) 29 | } 30 | }; 31 | 32 | export default { 33 | namespaced: true, 34 | state, mutations,actions 35 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/store/student/class_test.js: -------------------------------------------------------------------------------- 1 | import {Student} from '../../services/resources'; 2 | 3 | const state = { 4 | classTests: [], 5 | classTest: null, 6 | question: null, 7 | questionIndex: 0 8 | }; 9 | 10 | const mutations = { 11 | setClassTest(state, classTest) { 12 | state.classTest = classTest; 13 | }, 14 | setClassTests(state, classTests) { 15 | state.classTests = classTests; 16 | }, 17 | setQuestion(state, question) { 18 | state.question = question; 19 | let index = state.classTest.questions.findIndex((item) => { 20 | return item.id == question.id; 21 | }); 22 | state.questionIndex = index; 23 | 24 | }, 25 | }; 26 | 27 | const actions = { 28 | query(context, classTeachingId) { 29 | return Student.classTest.query({class_teaching: classTeachingId}) 30 | .then(response => { 31 | context.commit('setClassTests', response.data); 32 | }); 33 | }, 34 | get (context, {classTeachingId, classTestId}) { 35 | return Student.classTest.get({class_teaching: classTeachingId, class_test: classTestId}) 36 | .then(response => { 37 | context.commit('setClassTest', response.data); 38 | }) 39 | }, 40 | }; 41 | 42 | const getters = { 43 | isTrue: (state, getters) => (question, choiceId) => { 44 | return question.choices.some((choice) => { 45 | return choice.true && choice.id == choiceId; 46 | }); 47 | } 48 | } 49 | 50 | export default { 51 | namespaced: true, 52 | state, mutations, actions, getters 53 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/store/student/student_class_test.js: -------------------------------------------------------------------------------- 1 | import {Student} from '../../services/resources'; 2 | import Vue from 'vue'; 3 | 4 | const state = { 5 | studentClassTest: { 6 | choices: {} 7 | } 8 | }; 9 | 10 | const mutations = { 11 | setStudentClassTest(state, studentClassTest) { 12 | state.studentClassTest = studentClassTest; 13 | }, 14 | setChoiceTrue(state,{choiceId,question}){ 15 | if(!state.studentClassTest.choices.hasOwnProperty(question.id)){ 16 | Vue.set(state.studentClassTest.choices,question.id,choiceId); 17 | } 18 | state.studentClassTest.choices[question.id] = choiceId; 19 | } 20 | }; 21 | 22 | const actions = { 23 | get (context, {studentClassTestId, classTestId}) { 24 | return Student.studentClassTest.get({student_class_test: studentClassTestId, class_test: classTestId}) 25 | .then(response => { 26 | context.commit('setStudentClassTest', response.data); 27 | }) 28 | }, 29 | create(context, classTestId){ 30 | return Student.studentClassTest.save({class_test: classTestId},context.state.studentClassTest) 31 | } 32 | }; 33 | 34 | export default { 35 | namespaced: true, 36 | state, mutations, actions 37 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/store/teacher.js: -------------------------------------------------------------------------------- 1 | import classInformation from './teacher/class_information'; 2 | import classTeaching from './teacher/class_teaching'; 3 | import classTest from './teacher/class_test'; 4 | 5 | const module = { 6 | namespaced: true, 7 | modules: { 8 | classInformation, classTeaching, classTest 9 | } 10 | }; 11 | 12 | export default module; -------------------------------------------------------------------------------- /resources/assets/spa/js/store/teacher/class_information.js: -------------------------------------------------------------------------------- 1 | import {Teacher} from '../../services/resources'; 2 | 3 | const state = { 4 | classInformations: [], 5 | classInformation: null 6 | }; 7 | 8 | const mutations = { 9 | setClassInformations(state,classInformations){ 10 | state.classInformations = classInformations; 11 | }, 12 | setClassInformation(state, classInformation){ 13 | state.classInformation = classInformation; 14 | } 15 | }; 16 | 17 | const actions = { 18 | query(context){ 19 | Teacher.classInformation.query() 20 | .then(response => { 21 | context.commit('setClassInformations',response.data); 22 | }); 23 | }, 24 | get(context, classInformationId){ 25 | Teacher.classInformation.get({class_information: classInformationId}) 26 | .then(response => { 27 | context.commit('setClassInformation',response.data); 28 | }) 29 | } 30 | }; 31 | 32 | export default { 33 | namespaced: true, 34 | state, mutations,actions 35 | } -------------------------------------------------------------------------------- /resources/assets/spa/js/store/teacher/class_teaching.js: -------------------------------------------------------------------------------- 1 | import {Teacher} from '../../services/resources'; 2 | 3 | const state = { 4 | classTeachings: [], 5 | classTeaching: null 6 | }; 7 | 8 | const mutations = { 9 | setClassTeachings(state,classTeachings){ 10 | state.classTeachings = classTeachings; 11 | }, 12 | setClassTeaching(state, classTeaching){ 13 | state.classTeaching = classTeaching; 14 | } 15 | }; 16 | 17 | const actions = { 18 | query(context){ 19 | return Teacher.classTeaching.query() 20 | .then(response => { 21 | context.commit('setClassTeachings',response.data); 22 | }); 23 | }, 24 | get(context, classTeachingId){ 25 | return Teacher.classTeaching.get({class_teaching: classTeachingId}) 26 | .then(response => { 27 | context.commit('setClassTeaching',response.data); 28 | }) 29 | } 30 | }; 31 | 32 | export default { 33 | namespaced: true, 34 | state, mutations,actions 35 | } -------------------------------------------------------------------------------- /resources/assets/spa/sass/_variables.scss: -------------------------------------------------------------------------------- 1 | 2 | // Body 3 | $body-bg: #f5f8fa; 4 | 5 | // Borders 6 | $laravel-border-color: darken($body-bg, 10%); 7 | $list-group-border: $laravel-border-color; 8 | $navbar-default-border: $laravel-border-color; 9 | $panel-default-border: $laravel-border-color; 10 | $panel-inner-border: $laravel-border-color; 11 | 12 | // Brands 13 | $brand-primary: #3097D1; 14 | $brand-info: #8eb4cb; 15 | $brand-success: #2ab27b; 16 | $brand-warning: #cbb956; 17 | $brand-danger: #bf5329; 18 | 19 | // Typography 20 | $icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/"; 21 | $font-family-sans-serif: "Raleway", sans-serif; 22 | $font-size-base: 14px; 23 | $line-height-base: 1.6; 24 | $text-color: #636b6f; 25 | 26 | // Navbar 27 | $navbar-default-bg: #fff; 28 | 29 | // Buttons 30 | $btn-default-color: $text-color; 31 | 32 | // Inputs 33 | $input-border: lighten($text-color, 40%); 34 | $input-border-focus: lighten($brand-primary, 25%); 35 | $input-color-placeholder: lighten($text-color, 30%); 36 | 37 | // Panels 38 | $panel-default-heading-bg: #fff; 39 | -------------------------------------------------------------------------------- /resources/assets/spa/sass/spa.scss: -------------------------------------------------------------------------------- 1 | 2 | // Fonts 3 | @import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600"); 4 | 5 | // Variables 6 | @import "variables"; 7 | 8 | @import "node_modules/pnotify/src/pnotify"; 9 | @import "node_modules/pnotify/src/pnotify.brighttheme"; 10 | @import "node_modules/pnotify/src/pnotify.buttons"; 11 | @import "node_modules/select2/src/scss/core"; 12 | // Bootstrap 13 | @import "node_modules/bootstrap-sass/assets/stylesheets/bootstrap"; 14 | -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Passwords must be at least six characters and match the confirmation.', 17 | 'reset' => 'Your password has been reset!', 18 | 'sent' => 'We have e-mailed your password reset link!', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that e-mail address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /resources/views/admin/class_informations/class_student.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Administração de alunos na turma

7 | 8 |
9 |
10 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/class_informations/class_teaching.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Adicionar disciplina e professor na turma

7 | 8 |

9 |
10 |
11 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/class_informations/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Nova turma

7 | {!! 8 | form($form->add('insert','submit', [ 9 | 'attr' => ['class' => 'btn btn-primary btn-block'], 10 | 'label' => Icon::create('floppy-disk').'  Inserir' 11 | ])) 12 | !!} 13 |
14 |
15 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/class_informations/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Editar turma

7 | {!! 8 | form($form->add('edit','submit', [ 9 | 'attr' => ['class' => 'btn btn-primary btn-block'], 10 | 'label' => Icon::create('floppy-disk').'  Editar' 11 | ])) 12 | !!} 13 |
14 |
15 | 16 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/class_informations/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Listagem de turmas

7 | {!! Button::primary('Nova turma')->asLinkTo(route('admin.class_informations.create')) !!} 8 |
9 |
10 | {!! 11 | Table::withContents($class_informations->items()) 12 | ->striped() 13 | ->callback('Ações', function($field,$model){ 14 | $linkEdit = route('admin.class_informations.edit',['class_information' => $model->id]); 15 | $linkShow = route('admin.class_informations.show',['class_information' => $model->id]); 16 | $linkStudents = route('admin.class_informations.students.index',['class_information' => $model->id]); 17 | $linkTeachings = route('admin.class_informations.teachings.index',['class_information' => $model->id]); 18 | return Button::link(Icon::create('pencil').' Editar')->asLinkTo($linkEdit).'|'. 19 | Button::link(Icon::create('folder-open').'  Ver')->asLinkTo($linkShow).'|'. 20 | Button::link(Icon::create('home').'  Alunos')->asLinkTo($linkStudents).'|'. 21 | Button::link(Icon::create('blackboard').'  Ensino')->asLinkTo($linkTeachings); 22 | }) 23 | !!} 24 |
25 | 26 | {!! $class_informations->links() !!} 27 |
28 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/class_informations/show.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Ver turma

7 | @php 8 | $linkEdit = route('admin.class_students.edit',['class_students' => $class_information->id]); 9 | $linkDelete = route('admin.class_students.destroy',['class_students' => $class_information->id]); 10 | @endphp 11 | {!! Button::primary(Icon::pencil().' Editar')->asLinkTo($linkEdit) !!} 12 | {!! 13 | Button::danger(Icon::remove().' Excluir')->asLinkTo($linkDelete) 14 | ->addAttributes([ 15 | 'onclick' => "event.preventDefault();document.getElementById(\"form-delete\").submit();" 16 | ]) 17 | !!} 18 | @php 19 | $formDelete = FormBuilder::plain([ 20 | 'id' => 'form-delete', 21 | 'url' => $linkDelete, 22 | 'method' => 'DELETE', 23 | 'style' => 'display:none' 24 | ]) 25 | @endphp 26 | {!! form($formDelete) !!} 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 |
ID{{$class_information->id}}
Data Início{{$class_information->date_start->format('d/m/Y')}}
Data Fim{{$class_information->date_start->format('d/m/Y')}}
Ciclo{{$class_information->cycle}}
Subdivisão{{$class_information->subdivision}}
Semester{{$class_information->year}}
56 |
57 |
58 | @endsection 59 | -------------------------------------------------------------------------------- /resources/views/admin/subjects/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Nova disciplina

7 | {!! 8 | form($form->add('insert','submit', [ 9 | 'attr' => ['class' => 'btn btn-primary btn-block'], 10 | 'label' => Icon::create('floppy-disk').'  Inserir' 11 | ])) 12 | !!} 13 |
14 |
15 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/subjects/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Editar disciplina

7 | {!! 8 | form($form->add('edit','submit', [ 9 | 'attr' => ['class' => 'btn btn-primary btn-block'], 10 | 'label' => Icon::create('floppy-disk').'  Editar' 11 | ])) 12 | !!} 13 |
14 |
15 | 16 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/subjects/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Listagem de disciplinas

7 | {!! Button::primary('Nova disciplina')->asLinkTo(route('admin.subjects.create')) !!} 8 |
9 |
10 | {!! 11 | Table::withContents($subjects->items()) 12 | ->striped() 13 | ->callback('Ações', function($field,$model){ 14 | $linkEdit = route('admin.subjects.edit',['subject' => $model->id]); 15 | $linkShow = route('admin.subjects.show',['subject' => $model->id]); 16 | return Button::link(Icon::create('pencil').' Editar')->asLinkTo($linkEdit).'|'. 17 | Button::link(Icon::create('folder-open').'  Ver')->asLinkTo($linkShow); 18 | }) 19 | !!} 20 |
21 | 22 | {!! $subjects->links() !!} 23 |
24 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/subjects/show.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Ver disciplina

7 | @php 8 | $linkEdit = route('admin.subjects.edit',['subject' => $subject->id]); 9 | $linkDelete = route('admin.subjects.destroy',['subject' => $subject->id]); 10 | @endphp 11 | {!! Button::primary(Icon::pencil().' Editar')->asLinkTo($linkEdit) !!} 12 | {!! 13 | Button::danger(Icon::remove().' Excluir')->asLinkTo($linkDelete) 14 | ->addAttributes([ 15 | 'onclick' => "event.preventDefault();document.getElementById(\"form-delete\").submit();" 16 | ]) 17 | !!} 18 | @php 19 | $formDelete = FormBuilder::plain([ 20 | 'id' => 'form-delete', 21 | 'url' => $linkDelete, 22 | 'method' => 'DELETE', 23 | 'style' => 'display:none' 24 | ]) 25 | @endphp 26 | {!! form($formDelete) !!} 27 |

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
ID{{$subject->id}}
Nome{{$subject->name}}
40 |
41 |
42 | @endsection 43 | -------------------------------------------------------------------------------- /resources/views/admin/users/create.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Novo usuário

7 | {!! 8 | form($form->add('insert','submit', [ 9 | 'attr' => ['class' => 'btn btn-primary btn-block'], 10 | 'label' => Icon::create('floppy-disk').'  Inserir' 11 | ])) 12 | !!} 13 |
14 |
15 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/users/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 | @component('admin.users.tabs-component',['user' => $form->getModel()]) 7 |
8 |

Editar usuário

9 | {!! 10 | form($form->add('edit','submit', [ 11 | 'attr' => ['class' => 'btn btn-primary btn-block'], 12 | 'label' => Icon::create('floppy-disk').'  Editar' 13 | ])) 14 | !!} 15 |
16 | @endcomponent 17 |
18 |
19 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/users/index.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Listagem de usuários

7 | {!! Button::primary('Novo usuário')->asLinkTo(route('admin.users.create')) !!} 8 |
9 |
10 | {!! 11 | Table::withContents($users->items()) 12 | ->striped() 13 | ->callback('Ações', function($field,$model){ 14 | $linkEdit = route('admin.users.edit',['user' => $model->id]); 15 | $linkShow = route('admin.users.show',['user' => $model->id]); 16 | return Button::link(Icon::create('pencil').' Editar')->asLinkTo($linkEdit).'|'. 17 | Button::link(Icon::create('folder-open').'  Ver')->asLinkTo($linkShow); 18 | }) 19 | !!} 20 |
21 | 22 | {!! $users->links() !!} 23 |
24 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/users/profile/edit.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 | @component('admin.users.tabs-component',['user' => $form->getModel()]) 7 |
8 |

Editar perfil

9 | 10 | {!! 11 | form($form->add('salve', 'submit', [ 12 | 'attr' => ['class' => 'btn btn-primary btn-block'], 13 | 'label' => $icon 14 | ])) 15 | !!} 16 |
17 | @endcomponent 18 |
19 |
20 | @endsection 21 | -------------------------------------------------------------------------------- /resources/views/admin/users/settings.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Editar meu perfil de usuário

7 | {!! 8 | form($form->add('insert','submit', [ 9 | 'attr' => ['class' => 'btn btn-primary btn-block'], 10 | 'label' => Icon::create('floppy-disk').'  Salvar' 11 | ])) 12 | !!} 13 |
14 |
15 | @endsection -------------------------------------------------------------------------------- /resources/views/admin/users/show.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Ver usuário

7 | @php 8 | $linkEdit = route('admin.users.edit',['user' => $user->id]); 9 | $linkDelete = route('admin.users.destroy',['user' => $user->id]); 10 | @endphp 11 | {!! Button::primary(Icon::pencil().' Editar')->asLinkTo($linkEdit) !!} 12 | {!! 13 | Button::danger(Icon::remove().' Excluir')->asLinkTo($linkDelete) 14 | ->addAttributes([ 15 | 'onclick' => "event.preventDefault();document.getElementById(\"form-delete\").submit();" 16 | ]) 17 | !!} 18 | @php 19 | $formDelete = FormBuilder::plain([ 20 | 'id' => 'form-delete', 21 | 'url' => $linkDelete, 22 | 'method' => 'DELETE', 23 | 'style' => 'display:none' 24 | ]) 25 | @endphp 26 | {!! form($formDelete) !!} 27 |

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
ID{{$user->id}}
Nome{{$user->name}}
E-mail{{$user->email}}
44 |
45 |
46 | @endsection 47 | -------------------------------------------------------------------------------- /resources/views/admin/users/show_details.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |

Usuário - {{$user->name}}

7 | {!! Button 8 | ::normal('Listar usuários') 9 | ->appendIcon(Icon::thList()) 10 | ->asLinkTo(route('admin.users.index')) 11 | ->addAttributes([ 12 | 'class' => 'hidden-print' 13 | ]) 14 | !!} 15 |

16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
#{{$user->id}}
Nome{{$user->name}}
E-mail{{$user->email}}
Password{!! Badge::withContents($user->password)!!}
36 | 37 |
38 |
39 | @endsection 40 | -------------------------------------------------------------------------------- /resources/views/admin/users/tabs-component.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | $tabs = [ 3 | ['title' => 'Informações','link' => route('admin.users.edit',['user' => $user->id])], 4 | ['title' => 'Perfil','link' => route('admin.users.profile.edit',['user' => $user->id])], 5 | ] 6 | @endphp 7 | 8 |

Gerenciar usuário

9 |
10 | {!! Button::link('Listar usuários')->asLinkTo(route('admin.users.index')) !!} 11 |
12 | {!! \Navigation::tabs($tabs) !!} 13 |
14 | {!! $slot !!} 15 |
-------------------------------------------------------------------------------- /resources/views/auth/passwords/email.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
Reset Password
9 |
10 | @if (session('status')) 11 |
12 | {{ session('status') }} 13 |
14 | @endif 15 | 16 |
17 | {{ csrf_field() }} 18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 | @if ($errors->has('email')) 26 | 27 | {{ $errors->first('email') }} 28 | 29 | @endif 30 |
31 |
32 | 33 |
34 |
35 | 38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | @endsection 47 | -------------------------------------------------------------------------------- /resources/views/home.blade.php: -------------------------------------------------------------------------------- 1 | @extends('layouts.app') 2 | 3 | @section('content') 4 |
5 |
6 |
7 |
8 |
Dashboard
9 | 10 |
11 | You are logged in! 12 |
13 |
14 |
15 |
16 |
17 | @endsection 18 | -------------------------------------------------------------------------------- /resources/views/layouts/app.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {{ config('app.name', 'Laravel') }} 12 | 13 | 14 | 15 | 16 | 17 |
18 | @php 19 | $navbar = Navbar::withBrand(config('app.name'), route('admin.dashboard'))->inverse(); 20 | if(Auth::check()){ 21 | if(\Gate::allows('admin')){ 22 | $arrayLinks = [ 23 | ['link' => route('admin.users.index'), 'title' => 'Usuário'], 24 | ['link' => route('admin.subjects.index'), 'title' => 'Disciplina'], 25 | ['link' => route('admin.class_informations.index'), 'title' => 'Turma'], 26 | ]; 27 | $navbar->withContent(Navigation::links($arrayLinks)); 28 | } 29 | 30 | $arrayLinksRight = [ 31 | [ 32 | Auth::user()->name, 33 | [ 34 | [ 35 | 'link' => route('admin.users.settings.edit'), 36 | 'title' => 'Configurações' 37 | ], 38 | [ 39 | 'link' => route('logout'), 40 | 'title' => 'Logout', 41 | 'linkAttributes' => [ 42 | 'onclick' => "event.preventDefault();document.getElementById(\"form-logout\").submit();" 43 | ] 44 | ] 45 | ] 46 | ] 47 | ]; 48 | $navbar->withContent(Navigation::links($arrayLinksRight)->right()); 49 | 50 | $formLogout = FormBuilder::plain([ 51 | 'id' => 'form-logout', 52 | 'url' => route('logout'), 53 | 'method' => 'POST', 54 | 'style' => 'display:none' 55 | ]); 56 | } 57 | @endphp 58 | {!! $navbar !!} 59 | 60 | @if(Auth::check()) 61 | {!! form($formLogout) !!} 62 | @endif 63 | 64 | @if(Session::has('message')) 65 |
66 | {!! Alert::success(Session::get('message'))->close() !!} 67 |
68 | @endif 69 | @yield('content') 70 |
71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /resources/views/layouts/spa.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {{ config('app.name', 'Laravel') }} 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /resources/views/welcome.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Laravel 9 | 10 | 11 | 12 | 13 | 14 | 66 | 67 | 68 |
69 | @if (Route::has('login')) 70 | 78 | @endif 79 | 80 |
81 |
82 | Laravel 83 |
84 | 85 | 92 |
93 |
94 | 95 | 96 | -------------------------------------------------------------------------------- /routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 16 | }); 17 | -------------------------------------------------------------------------------- /routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 18 | })->describe('Display an inspiring quote'); 19 | -------------------------------------------------------------------------------- /routes/web.php: -------------------------------------------------------------------------------- 1 | group(function () { 23 | Auth::routes(); 24 | 25 | Route::group(['prefix' => 'users', 'as' => 'admin.users.'], function () { 26 | Route::name('settings.edit')->get('settings', 'Admin\UserSettingsController@edit'); 27 | Route::name('settings.update')->put('settings', 'Admin\UserSettingsController@update'); 28 | }); 29 | 30 | Route::group([ 31 | 'namespace' => 'Admin\\', 32 | 'as' => 'admin.', 33 | 'middleware' => ['auth', 'can:admin'] 34 | ], function () { 35 | Route::name('dashboard')->get('/dashboard', function () { 36 | return "Estou no dashboard"; 37 | }); 38 | Route::group(['prefix' => 'users', 'as' => 'users.'], function () { 39 | Route::name('show_details')->get('show_details', 'UsersController@showDetails'); 40 | Route::group(['prefix' => '/{user}/profile'], function () { 41 | Route::name('profile.edit')->get('', 'UserProfileController@edit'); 42 | Route::name('profile.update')->put('', 'UserProfileController@update'); 43 | }); 44 | }); 45 | Route::resource('users', 'UsersController'); 46 | Route::resource('subjects', 'SubjectsController'); 47 | Route::group(['prefix' => 'class_informations/{class_information}', 'as' => 'class_informations.'], 48 | function () { 49 | Route::resource('students', 'ClassStudentsController', ['only' => ['index', 'store', 'destroy']]); 50 | Route::resource('teachings', 'ClassTeachingsController',['only' => ['index','store','destroy']]); 51 | }); 52 | Route::resource('class_informations', 'ClassInformationsController'); 53 | }); 54 | 55 | Route::group([ 56 | 'namespace' => 'Api\\', 57 | 'as' => 'admin.api.', 58 | 'middleware' => ['auth', 'can:admin'], 59 | 'prefix' => 'api' 60 | ], function () { 61 | Route::name('students.index')->get('students','StudentsController@index'); 62 | Route::name('subjects.index')->get('subjects', 'SubjectsController@index'); 63 | Route::name('teachers.index')->get('teachers', 'TeachersController@index'); 64 | }); 65 | }); 66 | 67 | Route::get('/home', 'HomeController@index')->name('home'); 68 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | 8 | */ 9 | 10 | $uri = urldecode( 11 | parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) 12 | ); 13 | 14 | // This file allows us to emulate Apache's "mod_rewrite" functionality from the 15 | // built-in PHP web server. This provides a convenient way to test a Laravel 16 | // application without having installed a "real" web server software here. 17 | if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { 18 | return false; 19 | } 20 | 21 | require_once __DIR__.'/public/index.php'; 22 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | config.php 2 | routes.php 3 | schedule-* 4 | compiled.php 5 | services.json 6 | events.scanned.php 7 | routes.scanned.php 8 | down 9 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 20 | 21 | $response->assertStatus(200); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel application. By default, we are compiling the Sass 10 | | file for the application as well as bundling up all the JS files. 11 | | 12 | */ 13 | 14 | mix.js('resources/assets/admin/js/admin.js', 'public/js') 15 | .sass('resources/assets/admin/sass/admin.scss', 'public/css') 16 | .sourceMaps(); 17 | 18 | mix.js('resources/assets/spa/js/spa.js', 'public/js') 19 | .sass('resources/assets/spa/sass/spa.scss', 'public/css') 20 | .sourceMaps(); 21 | 22 | 23 | mix.browserSync('localhost:8000'); //:3000 24 | //8000 - Laravel 25 | 26 | --------------------------------------------------------------------------------