Просмотр исходного кода

Fixes to dashboard functions; missing filter by faculty

jquino 4 лет назад
Родитель
Сommit
571f7116a4

+ 1
- 1
app/Course.php Просмотреть файл

@@ -20,7 +20,7 @@ class Course extends Model
20 20
     public $timestamps = false;
21 21
 
22 22
     public function dept() {
23
-        return $this->belongsTo(Dept::class);
23
+        return $this->belongsTo(Department::class);
24 24
     }
25 25
 
26 26
     public function semesters() {

+ 9
- 0
app/Department.php Просмотреть файл

@@ -7,4 +7,13 @@ use Illuminate\Database\Eloquent\Model;
7 7
 class Department extends Model
8 8
 {
9 9
     public $timestamps = false;
10
+
11
+
12
+    public function courses() {
13
+        return $this->hasMany(Course::class);
14
+    }
15
+
16
+    public function faculty() {
17
+        return $this->belongsTo(Faculty::class);
18
+    }
10 19
 }

+ 14
- 0
app/Faculty.php Просмотреть файл

@@ -0,0 +1,14 @@
1
+<?php
2
+
3
+namespace App;
4
+
5
+use Illuminate\Database\Eloquent\Model;
6
+
7
+class Faculty extends Model
8
+{
9
+    public $timestamps = false;
10
+
11
+    public function departments() {
12
+        return $this->hasMany(Department::class);
13
+    }
14
+}

+ 4
- 4
app/Http/Controllers/Auth/LoginController.php Просмотреть файл

@@ -62,10 +62,10 @@ class LoginController extends Controller
62 62
         } catch (Exception $e) {
63 63
             return redirect('/login');
64 64
         }
65
-        // only allow people with @company.com to login
66
-        // if(explode("@", $google_user->email)[1] !== 'upr.edu'){
67
-        //     return redirect()->to('/');
68
-        // }
65
+        // only allow people with @upr.edu to login
66
+        if(explode("@", $google_user->email)[1] !== 'upr.edu'){
67
+            return redirect()->to('/');
68
+        }
69 69
 
70 70
         // check if they're in the database
71 71
         $user = \App\User::where('email', $google_user->email)->first();

+ 2
- 0
app/Http/Controllers/CourseController.php Просмотреть файл

@@ -19,6 +19,8 @@ class CourseController extends Controller
19 19
      */
20 20
     public function index(Request $request)
21 21
     {
22
+        // if ($request->session()->has('department'))
23
+        // $courses = Course::whereIn('dept_id')
22 24
         return view('courses.index', [
23 25
             'courses' => Course::where('dept_id', '=', $request->session()->get('department'))->with('sections:id,course_id,semester_code')->get()->sort('cmpCourseCode'),
24 26
             'semesters' => Semester::orderBy('code', 'asc')->get(),

+ 31
- 38
app/Http/Controllers/DashboardController.php Просмотреть файл

@@ -46,45 +46,38 @@ class DashboardController extends Controller
46 46
         $semester = Semester::findOrFail($semester_code);
47 47
         $data = (object)['alpha' => $semester->alpha];
48 48
         $data->dept = Department::find($request->session()->get('department'));
49
-        $data->courses = $semester->courses()->where('dept_id', '=', $data->dept->id)->distinct()->get();
50
-        // dd($data);
51
-        // $data->loadMissing(['courses.sections' => function ($query) use ($request, $semester_code) {
52
-        //     $query->where('semester_code', '=', $semester_code);
53
-        // }, 'courses.sections.professors:id,first_name,last_name', 'courses.sections.schedules']);
54
-        // return $data->toJson();
55
-        // $data->courses = $data->courses->sort('cmpCourseCode');
56
-        // dump($data->courses[0]->sections);
57
-        // foreach($data->courses as $course) {
58
-        //     $course->sections = $course->sections;
59
-        //     foreach($course->sections as $section) {
60
-        //         $section->professors = $section->professors;
61
-        //     }
62
-        // }
63
-        // dd($data);
64
-        dd(json_encode($data, JSON_PRETTY_PRINT));
65
-        // header('Content-Type: application/pdf');
66
-        // header(`Content-Disposition: attachment; filename="${semester_code}.pdf";`);
67
-        // return $data->toJson();
68
-
69
-        return '<script type="text/javascript">var data='.$data->toJson().';</script><script type="text/javascript" src="/js/createPDF.js"></script>';
49
+        $data->courses = $semester->courses()->where('dept_id', '=', $data->dept->id)->with([
50
+            'sections' => function ($query) use ($semester) {
51
+                $query->where('semester_code', '=', $semester->code);
52
+            },
53
+            'sections.schedules',
54
+            'sections.professors',
55
+        ])->distinct()->get()->sort('cmpCourseCode')->values();
56
+        // dump(json_encode($data, JSON_PRETTY_PRINT));
57
+        return '<script type="text/javascript">var data='.json_encode($data, JSON_UNESCAPED_UNICODE).';</script><script type="text/javascript" src="/js/createPDF.js"></script>';
70 58
     }
71 59
 
72 60
     public function export($semester_code) {
73 61
         $semester = Semester::findOrFail($semester_code);
74
-        $professors = Professor::with(['sections', 'semesters:code,admin_load,investigative_load'])->whereIn('id', function($query) use ($semester_code) {
75
-            $query->select('professor_id')
76
-            ->from('professor_semester')
77
-            ->where('semester_code', '=', $semester_code);
78
-        })->orWhereIn('id', function($query) use ($semester_code) {
79
-            $query->select('professor_id')
80
-            ->from('sections')
81
-            ->join('professor_section', 'sections.id', '=', 'professor_section.section_id')
82
-            ->where('semester_code', '=', $semester_code);
83
-        })->orderBy('last_name')->get();
62
+        $professors = Professor::with([
63
+                'sections' => function ($query) use ($semester_code) {
64
+                    $query->where('semester_code', '=', $semester_code);
65
+                },
66
+                'semesters:code,admin_load,investigative_load,other'
67
+            ])->whereIn('id', function($query) use ($semester_code) {
68
+                $query->select('professor_id')
69
+                    ->from('professor_semester')
70
+                    ->where('semester_code', '=', $semester_code);
71
+            })->orWhereIn('id', function($query) use ($semester_code) {
72
+                $query->select('professor_id')
73
+                    ->from('sections')
74
+                    ->join('professor_section', 'sections.id', '=', 'professor_section.section_id')
75
+                    ->where('semester_code', '=', $semester_code);
76
+            })->orderBy('last_name')->get();
84 77
         header('Content-Type: application/csv');
85 78
         header(`Content-Disposition: attachment; filename="${semester_code}.csv";`);
86 79
         if ($file = fopen('php://output', 'w+')) {
87
-            fputcsv($file, ['PROFESOR', 'CARGA ACADEMICA', 'CARGA ADMINISTRATIVA', 'CARGA INVESTIGATIVE', 'CARGA TOTAL']);
80
+            fputcsv($file, ['PROFESOR', 'CARGA ACADEMICA', 'CARGA ADMINISTRATIVA', 'CARGA INVESTIGATIVA', 'OTRAS CARGAS', 'CARGA TOTAL']);
88 81
             foreach ($professors as $professor) {
89 82
                 $professor->academic_load = $professor->getAcademicLoad($semester);
90 83
                 $prof_loads = $professor->semesters->find($semester);
@@ -94,7 +87,8 @@ class DashboardController extends Controller
94 87
                     $professor->academic_load,
95 88
                     $prof_loads->admin_load ?? 0,
96 89
                     $prof_loads->investigative_load ?? 0,
97
-                    $professor->academic_load + ($prof_loads->admin_load ?? 0) + ($prof_loads->investigative_load ?? 0),
90
+                    $prof_loads->other ?? 0,
91
+                    $professor->academic_load + ($prof_loads->admin_load ?? 0) + ($prof_loads->investigative_load ?? 0) + ($prof_loads->other ?? 0),
98 92
                 ]);
99 93
             }
100 94
             fclose($file);
@@ -125,11 +119,11 @@ class DashboardController extends Controller
125 119
         $semester = Semester::findOrFail($semester_code);
126 120
         // dd($semester->sections);
127 121
         $data = $request->validate([
128
-            'new_semester'  => 'required|unique:semesters,code|regex:/^[a-zA-Z][0-9][123]$/',
129
-            'new_alpha'     => 'required|unique:semesters,alpha'
122
+            'new_semester'  => 'required|regex:/^[a-zA-Z][0-9][123]$/',
123
+            'new_alpha'     => 'nullable'
130 124
         ]);
131 125
         try {
132
-            $semester->clone(strtoupper($data['new_semester']), strtoupper($data['new_alpha']));
126
+            $semester->clone(strtoupper($data['new_semester']), strtoupper($data['new_alpha']), $request->session()->get('department'));
133 127
         } catch (Exception $e) {
134 128
             echo $e->getMessage();
135 129
         }
@@ -137,10 +131,9 @@ class DashboardController extends Controller
137 131
     }
138 132
 
139 133
     /**
140
-     * TODO: Ability to add non-google users
141 134
      */
142 135
     public function addUser(Request $request) {
143
-        $data = $request->validate(['email' => ['required', 'email']]);
136
+        $data = $request->validate(['email' => ['required', 'email', 'regex:/.+@upr\.edu$/']]);
144 137
         User::create($data);
145 138
         return redirect()->back();
146 139
     }

+ 13
- 3
app/Http/Middleware/SetDept.php Просмотреть файл

@@ -15,15 +15,25 @@ class SetDept
15 15
      */
16 16
     public function handle($request, Closure $next)
17 17
     {
18
-        if ($request->has('setdept')) {
18
+        if ($request->has('f')) {
19
+            $data = $request->validate(['filter' => 'regex:/[df]/']);
20
+            $request->session()->put('filter', $data['filter']);
21
+        }
22
+        if ($request->has('fclt')) {
23
+            $data = $request->validate(['setfclt' => 'integer|exists:faculties,id']);
24
+            $request->session()->put('faculty', $data['setfclt']);
25
+        }
26
+        if ($request->has('dept')) {
19 27
             $data = $request->validate(['setdept' => 'integer|exists:departments,id']);
20 28
             $request->session()->put('department', $data['setdept']);
21 29
         }
30
+        if (!$request->session()->has('filter')) {
31
+            $request->session()->put('filter', 'd');
32
+        }
22 33
         if (!$request->session()->has('department')) {
23
-            $default_dept_id = \App\Department::whereNull('name')->first()->id;
34
+            $default_dept_id = \App\Department::where('name', '=', 'BIOL')->first()->id;
24 35
             $request->session()->put('department', $default_dept_id);
25 36
         }
26
-        // dump($request->session()->get('department'));
27 37
         return $next($request);
28 38
     }
29 39
 }

+ 32
- 16
app/Semester.php Просмотреть файл

@@ -40,34 +40,50 @@ class Semester extends Model
40 40
      *
41 41
      * @param string $newSemCode
42 42
      * @param string $newSemAlpha
43
+     * @param int $dept_id
43 44
      *
44 45
      * @return Semester
45 46
      */
46
-    public function clone(string $newSemCode, string $newSemAlpha) {
47
-        if (Semester::find($newSemCode)) {
48
-            throw new Exception('A semester with code ' . $newSemCode . ' already exists');
49
-        }
50
-        $newSem = Semester::create([
51
-            'code'  => $newSemCode,
52
-            'alpha' => $newSemAlpha,
53
-        ]);
47
+    public function clone(string $newSemCode, string $newSemAlpha, int $dept_id) {
48
+        // if (Semester::find($newSemCode)) {
49
+        //     throw new Exception('A semester with code ' . $newSemCode . ' already exists');
50
+        // }
51
+        $semClone = Semester::firstOrCreate(
52
+            ['code'  => $newSemCode],
53
+            ['alpha' => $newSemAlpha],
54
+        );
54 55
 
56
+        $this->loadMissing([
57
+            'sections' => function ($query) use ($dept_id) {
58
+                $query->select('sections.id', 'course_id', 'semester_code', 'sections.code', 'student_count', 'sections.syllabus', 'credits', 'quota')
59
+                    ->join('courses', 'courses.id', '=', 'sections.course_id')
60
+                    ->where('dept_id', '=', $dept_id);
61
+            },
62
+            'sections.professors',
63
+            'sections.schedules'
64
+        ]);
55 65
         // Copy all sections to new semester
56 66
         foreach($this->sections as $section) {
57 67
             $sectionClone = $section->replicate();
58
-            $sectionClone->semester_code = $newSem->code;
59
-            $sectionClone->save();
68
+            $sectionClone->semester_code = $semClone->code;
69
+            $existingSection = Section::where([['semester_code', '=', $sectionClone->semester_code], ['course_id', '=', $sectionClone->course_id], ['code', '=' , $sectionClone->code]])->first();
70
+            if (!$existingSection) {
71
+                $sectionClone->save();
60 72
 
61
-            foreach($section->professors as $professor) {
62
-                $sectionClone->professors()->attach($professor, ['percent' => $professor->pivot->percent]);
63
-            }
73
+                foreach($section->professors as $professor) {
74
+                    $sectionClone->professors()->attach($professor, ['percent' => $professor->pivot->percent]);
75
+                }
64 76
 
65
-            foreach($section->schedules as $schedule) {
66
-                $sectionClone->schedules()->save($schedule);
77
+                foreach($section->schedules as $schedule) {
78
+                    $scheduleClone = $schedule->replicate();
79
+                    $scheduleClone->section_id = $sectionClone->id;
80
+                    $scheduleClone->save();
81
+                    $sectionClone->schedules()->save($scheduleClone);
82
+                }
67 83
             }
68 84
         }
69 85
 
70
-        return $newSem;
86
+        return $semClone;
71 87
     }
72 88
 
73 89
 }

+ 31
- 0
database/migrations/2019_06_14_162008_create_faculties_table.php Просмотреть файл

@@ -0,0 +1,31 @@
1
+<?php
2
+
3
+use Illuminate\Support\Facades\Schema;
4
+use Illuminate\Database\Schema\Blueprint;
5
+use Illuminate\Database\Migrations\Migration;
6
+
7
+class CreateFacultiesTable extends Migration
8
+{
9
+    /**
10
+     * Run the migrations.
11
+     *
12
+     * @return void
13
+     */
14
+    public function up()
15
+    {
16
+        Schema::create('faculties', function (Blueprint $table) {
17
+            $table->bigIncrements('id');
18
+            $table->string('name');
19
+        });
20
+    }
21
+
22
+    /**
23
+     * Reverse the migrations.
24
+     *
25
+     * @return void
26
+     */
27
+    public function down()
28
+    {
29
+        Schema::dropIfExists('faculties');
30
+    }
31
+}

+ 4
- 1
database/migrations/2019_07_07_183013_create_departments_table.php Просмотреть файл

@@ -14,9 +14,12 @@ class CreateDepartmentsTable extends Migration
14 14
     public function up()
15 15
     {
16 16
         Schema::create('departments', function (Blueprint $table) {
17
-            $table->unsignedBigInteger('id')->primary();
17
+            $table->bigIncrements('id');
18 18
             $table->string('name')->nullable();
19 19
             $table->string('title')->nullable();
20
+            $table->unsignedBigInteger('faculty_id');
21
+
22
+            $table->foreign('faculty_id')->references('id')->on('faculties');
20 23
         });
21 24
 
22 25
         // DB::table('departments')->insert(

+ 53
- 30
resources/js/createPDF.js Просмотреть файл

@@ -1,41 +1,35 @@
1
-var fonts = {
2
-    Roboto: {
3
-        normal: 'fonts/Roboto-Regular.ttf',
4
-        bold: 'fonts/Roboto-Medium.ttf',
5
-        italics: 'fonts/Roboto-Italic.ttf',
6
-        bolditalics: 'fonts/Roboto-.ttf',
7
-    }
8
-};
9
-
10
-var pdfMake = require('pdfmake/build/pdfmake.js');
11
-var pdfFonts = require('pdfmake/build/vfs_fonts.js');
1
+const pdfMake = require('pdfmake/build/pdfmake.js');
2
+const pdfFonts = require('pdfmake/build/vfs_fonts.js');
12 3
 pdfMake.vfs = pdfFonts.pdfMake.vfs;
13 4
 
14 5
 function table(course) {
15 6
     return {
16
-        widths: [50, 100, 50, 50],
7
+        widths: [50, 200, 75, 50, 100],
17 8
         headerRows: 2,
18 9
         body: [
19
-            [{text: `${course.code} ${course.title}`, bold: true, colSpan: 4, alignment: 'center'}, {}, {}, {}],
20
-            ['Seccion', 'Profesor', 'Lugar', 'Horas'],
10
+            [{text: `${course.code}\n${course.title}`, bold: true, colSpan: 5, alignment: 'center'}, {}, {}, {}, {}],
11
+            [{text: 'Sección', bold: true}, {text: 'Profesor', bold: true}, {text: 'Lugar', bold: true}, {text: 'Días', bold: true}, {text: 'Horas', bold: true}],
21 12
         ].concat( course.sections.map( function(section) {
22 13
             var res = [section.code];
23
-            if (section.hasOwnProperty('professors') && !section.professors.length) {
14
+            if (section.hasOwnProperty('professors')) {
24 15
                 res = res.concat( section.professors.reduce( function (acc, professor) {
25
-                    return  acc + '\n' + professor.first_name + ' ' + professor.last_name;
26
-                }));
16
+                    return  ((acc === '') ? '' : acc + '\n') + professor.first_name + ' ' + professor.last_name;
17
+                }, ''));
27 18
             } else {
28 19
                 res = res.concat('');
29 20
             }
30
-            if (section.hasOwnProperty('schedules') && !section.professors.length) {
21
+            if (section.hasOwnProperty('schedules')) {
22
+                res = res.concat( section.schedules.reduce( function (acc, schedule) {
23
+                    return ((acc === '') ? '' : acc + '\n') + schedule.building + ' ' + schedule.room;
24
+                }, ''));
31 25
                 res = res.concat( section.schedules.reduce( function (acc, schedule) {
32
-                    return acc + '\n' + schedule.building + ' ' + schedule.room;
33
-                }));
26
+                    return ((acc === '') ? '' : acc + '\n') + schedule.days;
27
+                }, ''));
34 28
                 res = res.concat( section.schedules.reduce( function (acc, schedule) {
35
-                    return acc + '\n' + schedule.time_start + '-' + schedule.time_end;
36
-                }));
29
+                    return ((acc === '') ? '' : acc + '\n') + schedule.time_start + '-' + schedule.time_end;
30
+                }, ''));
37 31
             } else {
38
-                res = res.concat(['', '']);
32
+                res = res.concat(['', '', '']);
39 33
             }
40 34
             return res;
41 35
         }))
@@ -48,10 +42,17 @@ var docDef = {
48 42
         {text: 'sujeto a cambios', style: 'header', fontSize: 18},
49 43
     ].concat( data.courses.map( function(course) {
50 44
         return {
51
-            style: 'tableStyle',
52
-            alignment: 'center',
53
-            table: table(course)
54
-        }
45
+            columns: [
46
+                { width: '*', text: ''}, // Aligns table to center
47
+                {
48
+                    style: 'tableStyle',
49
+                    alignment: 'center',
50
+                    width: 'auto',
51
+                    table: table(course)
52
+                },
53
+                { width: '*', text: ''}  // Aligns table to center
54
+            ],
55
+        };
55 56
     })),
56 57
     styles: {
57 58
         header: {
@@ -60,12 +61,34 @@ var docDef = {
60 61
             alignment: 'center',
61 62
         },
62 63
         tableStyle: {
63
-            margin: [50,10,0,15]
64
+            margin: [0,20,0,20]
64 65
         },
66
+    },
67
+    pageBreakBefore: function(currentNode, followingNodesOnPage, nodesOnNextPage, previousNodesOnPage) {
68
+        var pageInnerHeight = currentNode.startPosition.pageInnerHeight;
69
+        var top = (currentNode.startPosition.top) ? currentNode.startPosition.top : 0;
70
+        var nodeHeight = 0; // Distance from top of table to top of next table
71
+        if (followingNodesOnPage && followingNodesOnPage.length) {
72
+            var nextTableNodeIndex = followingNodesOnPage.findIndex( function(n) { return n.table; })
73
+            if (nextTableNodeIndex !== -1 && nextTableNodeIndex < followingNodesOnPage.length) {
74
+                nodeHeight = followingNodesOnPage[nextTableNodeIndex].startPosition.top - top;
75
+            }
76
+        }
77
+        // if (currentNode.table) {
78
+        //     console.log(currentNode);
79
+        //     console.log(currentNode.pageNumbers)
80
+        //     console.log(currentNode.table.body[0][0].text);
81
+        //     console.log('t ' + top);
82
+        //     console.log('nh ' + nodeHeight);
83
+        //     console.log('pih ' + pageInnerHeight);
84
+        //     console.log((top + nodeHeight > pageInnerHeight));
85
+        // }
86
+        return (currentNode.table && (top + nodeHeight > pageInnerHeight))
87
+            || currentNode.startPosition.verticalRatio >= 0.90;
65 88
     }
66 89
 
67 90
 };
68 91
 
69
-console.log(docDef);
70
-pdfMake.createPdf(docDef).download();
92
+// console.log(docDef);
93
+pdfMake.createPdf(docDef).download(data.alpha + '.pdf', function () { window.location.replace('/dashboard')});
71 94
 // window.location.replace("/dashboard");

+ 0
- 6
resources/js/dashboard.js Просмотреть файл

@@ -3,10 +3,6 @@ import {MDCSelect} from '@material/select';
3 3
 import {MDCTextField} from '@material/textfield';
4 4
 import {MDCTextFieldHelperText} from '@material/textfield/helper-text';
5 5
 
6
-// const dialog = new MDCDialog(document.querySelector('.mdc-dialog'));
7
-// const semCloneSelect = new MDCSelect(document.querySelector('.mdc-select#sem-clone-select'));
8
-// const textfield = new MDCTextField(document.querySelector('.mdc-text-field'));
9
-
10 6
 $(document).ready( function() {
11 7
     $('#modal-semester').on('show.bs.modal', function (event) {
12 8
         var form = $(this).find('#modal-semester-form');
@@ -36,8 +32,6 @@ $(document).ready( function() {
36 32
 
37 33
         console.log($(this));
38 34
         const semCloneSelect = new MDCSelect($(this).find('#sem-clone-select')[0]);
39
-        // console.log(textfields);
40
-        // const t1 = new MDCTextField(document.querySelector('.mdc-text-field'));
41 35
 
42 36
         form.attr('method', 'GET');
43 37
         form.removeAttr('action');

+ 3
- 0
resources/sass/app.scss Просмотреть файл

@@ -182,3 +182,6 @@ h6 {
182 182
 button {
183 183
     @include mdc-typography(button)
184 184
 }
185
+p {
186
+    @include mdc-typography(body1)
187
+}

+ 11
- 11
resources/views/dashboard.blade.php Просмотреть файл

@@ -27,66 +27,66 @@
27 27
         @endif
28 28
         <div class="mdc-layout-grid__inner">
29 29
             {{-- <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-2-desktop"></div> --}}
30
-            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-4">
30
+            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-2">
31 31
                 <a data-toggle="modal" data-target="#modal-semester" data-action="export" data-title="Escoge un semestre">
32 32
                     <div class="mdc-card">
33 33
                         <div class="mdc-card__primary-action" tabindex="0">
34 34
                             <div id="dash-button-csv" class="mdc-card__media mdc-card__media--square"></div>
35 35
                             <hr>
36 36
                             <div>
37
-                                <h3>Generar informe de cargas</h3>
37
+                                <p>Informe de Cargas</p>
38 38
                             </div>
39 39
                         </div>
40 40
                     </div>
41 41
                 </a>
42 42
             </div>
43
-            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-4">
43
+            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-2">
44 44
                 <a data-toggle="modal" data-target="#modal-semester" data-action="schedule" data-title="Escoge un semestre">
45 45
                     <div class="mdc-card">
46 46
                         <div class="mdc-card__primary-action" tabindex="0">
47 47
                             <div id="dash-button-schedule" class="mdc-card__media mdc-card__media--square"></div>
48 48
                             <hr>
49 49
                             <div>
50
-                                <h3>Generar horario de semestre</h3>
50
+                                <p>Horario de Semestre</p>
51 51
                             </div>
52 52
                         </div>
53 53
                     </div>
54 54
                 </a>
55 55
             </div>
56
-            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-4">
56
+            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-2">
57 57
                 <a data-toggle="modal" data-target="#modal-user-add">
58 58
                     <div class="mdc-card">
59 59
                         <div class="mdc-card__primary-action" tabindex="0">
60 60
                             <div id="dash-button-schedule" class="mdc-card__media mdc-card__media--square"></div>
61 61
                             <hr>
62 62
                             <div>
63
-                                <h3>Anadir usuario</h3>
63
+                                <p>Añadir Usuario</p>
64 64
                             </div>
65 65
                         </div>
66 66
                     </div>
67 67
                 </a>
68 68
             </div>
69
-            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-4">
69
+            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-2">
70 70
                 <a data-toggle="modal" data-target="#modal-semester-clone" data-action="clone" data-title="Escoge un semestre">
71 71
                     <div class="mdc-card">
72 72
                         <div class="mdc-card__primary-action" tabindex="0">
73 73
                             <div id="dash-button-clone" class="mdc-card__media mdc-card__media--square"></div>
74 74
                             <hr>
75 75
                             <div>
76
-                                <h3>Copiar un semestre</h3>
76
+                                <p>Copiar un Semestre</p>
77 77
                             </div>
78 78
                         </div>
79 79
                     </div>
80 80
                 </a>
81 81
             </div>
82
-            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-4">
83
-                <a href="{{ route('exportCourses') }}">
82
+            <div class="mdc-layout-grid__cell mdc-layout-grid__cell--span-2">
83
+                <a href="{{ route('exportCourses') }}" style="text-decoration: none; color: inherit;">
84 84
                     <div class="mdc-card">
85 85
                         <div class="mdc-card__primary-action" tabindex="0">
86 86
                             <div id="dash-button-schedule" class="mdc-card__media mdc-card__media--square"></div>
87 87
                             <hr>
88 88
                             <div>
89
-                                <h3>Generar informe de cursos</h3>
89
+                                <p>Informe de Cursos</p>
90 90
                             </div>
91 91
                         </div>
92 92
                     </div>

+ 5
- 2
resources/views/layouts/app.blade.php Просмотреть файл

@@ -50,8 +50,11 @@
50 50
                             {{ $department->title ?: $department->name ?? 'Departamento' }} <span class="caret"></span>
51 51
                         </a>
52 52
                         <div class="dropdown-menu">
53
-                            @foreach (App\Department::whereNotNull('name')->orderBy('title')->get() as $dept)
54
-                                <a class="dropdown-item mdc-typography--body1" href="{{ url()->current() }}?setdept={{ $dept->id }}">{{ $dept->title ?: $dept->name }}</a>
53
+                            @foreach (App\Faculty::orderBy('name')->get() as $faculty)
54
+                                <a class="dropdown-item mdc-typography--body1" href="{{ url()->current() }}?setfac={{ $faculty->id }}">{{ $faculty->name }}</a>
55
+                                @foreach ($faculty->departments as $dept)
56
+                                    <a class="dropdown-item mdc-typography--body2" href="{{ url()->current() }}?setdept={{ $dept->id }}" style="padding-left:4em;">{{ $dept->title ?: $dept->name }}</a>
57
+                                @endforeach
55 58
                             @endforeach
56 59
                         </div>
57 60
                     </li>

+ 1
- 1
routes/web.php Просмотреть файл

@@ -30,9 +30,9 @@ Route::resource('section', 'SectionController')->only([
30 30
 Route::get('/dashboard', 'DashboardController@index')->name('dashboard');
31 31
 Route::post('/dashboard/schedule/{semester}', 'DashboardController@schedule')->name('schedule');
32 32
 Route::post('/dashboard/export/{semester}', 'DashboardController@export')->name('export');
33
-Route::post('/dashboard/export-courses', 'DashboardController@exportCourses')->name('exportCourses');
34 33
 Route::post('/dashboard/clone/{semester}', 'DashboardController@cloneSemester')->name('cloneSemester');
35 34
 Route::post('/dashboard/add-user', 'DashboardController@addUser')->name('addUser');
35
+Route::get('/dashboard/export-courses', 'DashboardController@exportCourses')->name('exportCourses');
36 36
 
37 37
 Route::get('/login', 'Auth\LoginController@redirectToProvider')->name('login');
38 38
 Route::get('/callback', 'Auth\LoginController@handleProviderCallback')->name('callback');