mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-31 02:57:57 +00:00 
			
		
		
		
	Feature: Rewamp super admin dashboard (#882)
This commit is contained in:
		| @@ -177,6 +177,8 @@ linters: | |||||||
|     allow_element_with_attribute: false |     allow_element_with_attribute: false | ||||||
|     allow_element_with_class: false |     allow_element_with_class: false | ||||||
|     allow_element_with_id: false |     allow_element_with_id: false | ||||||
|  |     exclude: | ||||||
|  |       - 'app/assets/stylesheets/administrate/components/_buttons.scss' | ||||||
|  |  | ||||||
|   SelectorDepth: |   SelectorDepth: | ||||||
|     enabled: true |     enabled: true | ||||||
| @@ -279,3 +281,4 @@ linters: | |||||||
| exclude: | exclude: | ||||||
|   - 'app/javascript/widget/assets/scss/_reset.scss' |   - 'app/javascript/widget/assets/scss/_reset.scss' | ||||||
|   - 'app/javascript/widget/assets/scss/sdk.css' |   - 'app/javascript/widget/assets/scss/sdk.css' | ||||||
|  |   - 'app/assets/stylesheets/administrate/reset/_normalize.scss' | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
| //= link_tree ../images | //= link_tree ../images | ||||||
| //= link administrate/application.css | //= link administrate/application.css | ||||||
| //= link administrate/application.js | //= link administrate/application.js | ||||||
|  | //= link dashboardChart.js | ||||||
|   | |||||||
							
								
								
									
										55
									
								
								app/assets/javascripts/dashboardChart.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								app/assets/javascripts/dashboardChart.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | // eslint-disable-next-line | ||||||
|  | function prepareData(data) { | ||||||
|  |   var labels = []; | ||||||
|  |   var dataSet = []; | ||||||
|  |   data.forEach(item => { | ||||||
|  |     labels.push(item[0]); | ||||||
|  |     dataSet.push(item[1]); | ||||||
|  |   }); | ||||||
|  |   return { labels, dataSet }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getChartOptions() { | ||||||
|  |   var fontFamily = | ||||||
|  |     'Inter,-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif'; | ||||||
|  |   return { | ||||||
|  |     responsive: true, | ||||||
|  |     legend: { labels: { fontFamily } }, | ||||||
|  |     scales: { | ||||||
|  |       xAxes: [ | ||||||
|  |         { | ||||||
|  |           barPercentage: 1.26, | ||||||
|  |           ticks: { fontFamily }, | ||||||
|  |           gridLines: { display: false }, | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |       yAxes: [ | ||||||
|  |         { | ||||||
|  |           ticks: { fontFamily }, | ||||||
|  |           gridLines: { display: false }, | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |     }, | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // eslint-disable-next-line | ||||||
|  | function drawSuperAdminDashboard(data) { | ||||||
|  |   var ctx = document.getElementById('dashboard-chart').getContext('2d'); | ||||||
|  |   var chartData = prepareData(data); | ||||||
|  |   // eslint-disable-next-line | ||||||
|  |   new Chart(ctx, { | ||||||
|  |     type: 'bar', | ||||||
|  |     data: { | ||||||
|  |       labels: chartData.labels, | ||||||
|  |       datasets: [ | ||||||
|  |         { | ||||||
|  |           label: 'Conversations', | ||||||
|  |           data: chartData.dataSet, | ||||||
|  |           backgroundColor: '#1f93ff', | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |     }, | ||||||
|  |     options: getChartOptions(), | ||||||
|  |   }); | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								app/assets/stylesheets/administrate/application.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								app/assets/stylesheets/administrate/application.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | @charset 'utf-8'; | ||||||
|  |  | ||||||
|  | @import 'reset/normalize'; | ||||||
|  |  | ||||||
|  | @import 'utilities/variables'; | ||||||
|  | @import 'utilities/text-color'; | ||||||
|  |  | ||||||
|  | @import 'selectize'; | ||||||
|  | @import 'datetime_picker'; | ||||||
|  |  | ||||||
|  | @import 'library/clearfix'; | ||||||
|  | @import 'library/data-label'; | ||||||
|  | @import 'library/variables'; | ||||||
|  |  | ||||||
|  | @import 'base/forms'; | ||||||
|  | @import 'base/layout'; | ||||||
|  | @import 'base/lists'; | ||||||
|  | @import 'base/tables'; | ||||||
|  | @import 'base/typography'; | ||||||
|  |  | ||||||
|  | @import 'components/app-container'; | ||||||
|  | @import 'components/attributes'; | ||||||
|  | @import 'components/buttons'; | ||||||
|  | @import 'components/cells'; | ||||||
|  | @import 'components/field-unit'; | ||||||
|  | @import 'components/flashes'; | ||||||
|  | @import 'components/form-actions'; | ||||||
|  | @import 'components/main-content'; | ||||||
|  | @import 'components/navigation'; | ||||||
|  | @import 'components/pagination'; | ||||||
|  | @import 'components/search'; | ||||||
|  | @import 'components/reports'; | ||||||
							
								
								
									
										103
									
								
								app/assets/stylesheets/administrate/base/_forms.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								app/assets/stylesheets/administrate/base/_forms.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | fieldset { | ||||||
|  |   background-color: transparent; | ||||||
|  |   border: 0; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | legend { | ||||||
|  |   font-weight: $font-weight-medium; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | label { | ||||||
|  |   display: block; | ||||||
|  |   font-weight: $font-weight-medium; | ||||||
|  |   margin: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input, | ||||||
|  | select { | ||||||
|  |   display: block; | ||||||
|  |   font-family: $base-font-family; | ||||||
|  |   font-size: $base-font-size; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | input, | ||||||
|  | select, | ||||||
|  | textarea { | ||||||
|  |   display: block; | ||||||
|  |   font-family: $base-font-family; | ||||||
|  |   font-size: 16px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | [type="color"], | ||||||
|  | [type="date"], | ||||||
|  | [type="datetime-local"], | ||||||
|  | [type="email"], | ||||||
|  | [type="month"], | ||||||
|  | [type="number"], | ||||||
|  | [type="password"], | ||||||
|  | [type="search"], | ||||||
|  | [type="tel"], | ||||||
|  | [type="text"], | ||||||
|  | [type="time"], | ||||||
|  | [type="url"], | ||||||
|  | [type="week"], | ||||||
|  | input:not([type]), | ||||||
|  | textarea { | ||||||
|  |   appearance: none; | ||||||
|  |   background-color: $white; | ||||||
|  |   border: $base-border; | ||||||
|  |   border-radius: $base-border-radius; | ||||||
|  |   padding: 0.5em; | ||||||
|  |   transition: border-color $base-duration $base-timing; | ||||||
|  |   width: 100%; | ||||||
|  |  | ||||||
|  |   &:hover { | ||||||
|  |     border-color: mix($black, $base-border-color, 20%); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   &:focus { | ||||||
|  |     border-color: $action-color; | ||||||
|  |     outline: none; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   &:disabled { | ||||||
|  |     background-color: mix($black, $white, 5%); | ||||||
|  |     cursor: not-allowed; | ||||||
|  |  | ||||||
|  |     &:hover { | ||||||
|  |       border: $base-border; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | textarea { | ||||||
|  |   resize: vertical; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | [type="checkbox"], | ||||||
|  | [type="radio"] { | ||||||
|  |   display: inline; | ||||||
|  |   margin-right: $small-spacing / 2; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | [type="file"] { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | select { | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | [type="checkbox"], | ||||||
|  | [type="radio"], | ||||||
|  | [type="file"], | ||||||
|  | select { | ||||||
|  |   &:focus { | ||||||
|  |     outline: $focus-outline; | ||||||
|  |     outline-offset: $focus-outline-offset; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								app/assets/stylesheets/administrate/base/_layout.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/assets/stylesheets/administrate/base/_layout.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | html { | ||||||
|  |   background-color: $color-white; | ||||||
|  |   box-sizing: border-box; | ||||||
|  |   font-size: 10px; | ||||||
|  |   -webkit-font-smoothing: antialiased; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | *, | ||||||
|  | *::before, | ||||||
|  | *::after { | ||||||
|  |   box-sizing: inherit; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | figure { | ||||||
|  |   margin: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | img, | ||||||
|  | picture { | ||||||
|  |   margin: 0; | ||||||
|  |   max-width: 100%; | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								app/assets/stylesheets/administrate/base/_lists.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								app/assets/stylesheets/administrate/base/_lists.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | |||||||
|  | ul, | ||||||
|  | ol { | ||||||
|  |   list-style-type: none; | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | dl { | ||||||
|  |   margin-bottom: $small-spacing; | ||||||
|  |  | ||||||
|  |   dt { | ||||||
|  |     font-weight: $font-weight-medium; | ||||||
|  |     margin-top: $small-spacing; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   dd { | ||||||
|  |     margin: 0; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										71
									
								
								app/assets/stylesheets/administrate/base/_tables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								app/assets/stylesheets/administrate/base/_tables.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | table { | ||||||
|  |   border-collapse: collapse; | ||||||
|  |   font-size: $font-size-default; | ||||||
|  |   text-align: left; | ||||||
|  |   width: 100%; | ||||||
|  |  | ||||||
|  |   a { | ||||||
|  |     color: inherit; | ||||||
|  |     text-decoration: none; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | tr { | ||||||
|  |   border-bottom: $base-border; | ||||||
|  |  | ||||||
|  |   th { | ||||||
|  |     font-weight: $font-weight-medium; | ||||||
|  |  | ||||||
|  |     &.cell-label--avatar-field { | ||||||
|  |       a { | ||||||
|  |         display: none; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | tbody tr { | ||||||
|  |   &:hover { | ||||||
|  |     background-color: $base-background-color; | ||||||
|  |     cursor: pointer; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   &:focus { | ||||||
|  |     outline: $focus-outline; | ||||||
|  |     outline-offset: -($focus-outline-width); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   td { | ||||||
|  |     &.cell-data--avatar-field { | ||||||
|  |       line-height: 1; | ||||||
|  |       text-align: center; | ||||||
|  |  | ||||||
|  |       img { | ||||||
|  |         border-radius: 50%; | ||||||
|  |         height: $space-large; | ||||||
|  |         max-height: $space-large; | ||||||
|  |         width: $space-large; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | td, | ||||||
|  | th { | ||||||
|  |   padding: $space-slab; | ||||||
|  |   vertical-align: middle; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | td:first-child, | ||||||
|  | th:first-child { | ||||||
|  |   padding-left: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | td:last-child, | ||||||
|  | th:last-child { | ||||||
|  |   padding-right: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | td img { | ||||||
|  |   max-height: 2rem; | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								app/assets/stylesheets/administrate/base/_typography.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/assets/stylesheets/administrate/base/_typography.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | body { | ||||||
|  |   color: $base-font-color; | ||||||
|  |   font-family: $base-font-family; | ||||||
|  |   font-size: $base-font-size; | ||||||
|  |   line-height: $base-line-height; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | h1, | ||||||
|  | h2, | ||||||
|  | h3, | ||||||
|  | h4, | ||||||
|  | h5, | ||||||
|  | h6 { | ||||||
|  |   font-family: $heading-font-family; | ||||||
|  |   font-size: $base-font-size; | ||||||
|  |   line-height: $heading-line-height; | ||||||
|  |   margin: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | p { | ||||||
|  |   margin: 0 0 $small-spacing; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | a { | ||||||
|  |   color: $action-color; | ||||||
|  |   transition: color $base-duration $base-timing; | ||||||
|  |  | ||||||
|  |   &:hover { | ||||||
|  |     color: mix($black, $action-color, 25%); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   &:focus { | ||||||
|  |     outline: $focus-outline; | ||||||
|  |     outline-offset: $focus-outline-offset; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | hr { | ||||||
|  |   border-bottom: $base-border; | ||||||
|  |   border-left: 0; | ||||||
|  |   border-right: 0; | ||||||
|  |   border-top: 0; | ||||||
|  |   margin: $base-spacing 0; | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | .app-container { | ||||||
|  |   align-items: stretch; | ||||||
|  |   display: flex; | ||||||
|  |   margin-left: auto; | ||||||
|  |   margin-right: auto; | ||||||
|  |   max-width: 100rem; | ||||||
|  |   min-height: 100vh; | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | .attribute-label { | ||||||
|  |   @include data-label; | ||||||
|  |   clear: left; | ||||||
|  |   float: left; | ||||||
|  |   margin-bottom: $base-spacing; | ||||||
|  |   margin-top: 0.25em; | ||||||
|  |   text-align: right; | ||||||
|  |   width: calc(15% - 1rem); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .preserve-whitespace { | ||||||
|  |   white-space: pre-wrap; | ||||||
|  |   word-wrap: break-word; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .attribute-data { | ||||||
|  |   float: left; | ||||||
|  |   margin-bottom: $base-spacing; | ||||||
|  |   margin-left: 2rem; | ||||||
|  |   width: calc(85% - 1rem); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .attribute--nested { | ||||||
|  |   border: $base-border; | ||||||
|  |   padding: $small-spacing; | ||||||
|  | } | ||||||
							
								
								
									
										50
									
								
								app/assets/stylesheets/administrate/components/_buttons.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								app/assets/stylesheets/administrate/components/_buttons.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | button, | ||||||
|  | input[type="button"], | ||||||
|  | input[type="reset"], | ||||||
|  | input[type="submit"], | ||||||
|  | .button { | ||||||
|  |   appearance: none; | ||||||
|  |   background-color: $color-woot; | ||||||
|  |   border: 0; | ||||||
|  |   border-radius: $base-border-radius; | ||||||
|  |   color: $white; | ||||||
|  |   cursor: pointer; | ||||||
|  |   display: inline-block; | ||||||
|  |   font-size: $font-size-default; | ||||||
|  |   -webkit-font-smoothing: antialiased; | ||||||
|  |   font-weight: $font-weight-medium; | ||||||
|  |   line-height: 1; | ||||||
|  |   padding: $space-one $space-two; | ||||||
|  |   text-decoration: none; | ||||||
|  |   transition: background-color $base-duration $base-timing; | ||||||
|  |   user-select: none; | ||||||
|  |   vertical-align: middle; | ||||||
|  |   white-space: nowrap; | ||||||
|  |  | ||||||
|  |   &:hover { | ||||||
|  |     background-color: mix($black, $color-woot, 20%); | ||||||
|  |     color: $white; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   &:focus { | ||||||
|  |     outline: $focus-outline; | ||||||
|  |     outline-offset: $focus-outline-offset; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   &:disabled { | ||||||
|  |     cursor: not-allowed; | ||||||
|  |     opacity: 0.5; | ||||||
|  |  | ||||||
|  |     &:hover { | ||||||
|  |       background-color: $color-woot; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .button--alt { | ||||||
|  |   background-color: transparent; | ||||||
|  |   border: $base-border; | ||||||
|  |   border-color: $blue; | ||||||
|  |   color: $blue; | ||||||
|  |   margin-bottom: $base-spacing; | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								app/assets/stylesheets/administrate/components/_cells.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								app/assets/stylesheets/administrate/components/_cells.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | .cell-label { | ||||||
|  |   &:hover { | ||||||
|  |     a { | ||||||
|  |       color: $action-color; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     svg { | ||||||
|  |       fill: $action-color; | ||||||
|  |       transform: rotate(180deg); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   a { | ||||||
|  |     color: inherit; | ||||||
|  |     display: inline-block; | ||||||
|  |     transition: color $base-duration $base-timing; | ||||||
|  |     width: 100%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .cell-label--asc, | ||||||
|  | .cell-label--desc { | ||||||
|  |   font-weight: $font-weight-medium; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .cell-label__sort-indicator { | ||||||
|  |   float: right; | ||||||
|  |   margin-left: 5px; | ||||||
|  |  | ||||||
|  |   svg { | ||||||
|  |     fill: $hint-grey; | ||||||
|  |     height: 13px; | ||||||
|  |     transition: transform $base-duration $base-timing; | ||||||
|  |     width: 13px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .cell-label__sort-indicator--desc { | ||||||
|  |   transform: rotate(180deg); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .cell-data--number, | ||||||
|  | .cell-label--number { | ||||||
|  |   text-align: right; | ||||||
|  | } | ||||||
| @@ -0,0 +1,54 @@ | |||||||
|  | .field-unit { | ||||||
|  |   @include administrate-clearfix; | ||||||
|  |   align-items: center; | ||||||
|  |   display: flex; | ||||||
|  |   margin-bottom: $base-spacing; | ||||||
|  |   position: relative; | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .field-unit__label { | ||||||
|  |   float: left; | ||||||
|  |   margin-left: 1rem; | ||||||
|  |   text-align: right; | ||||||
|  |   width: calc(15% - 1rem); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .field-unit__field { | ||||||
|  |   float: left; | ||||||
|  |   margin-left: 2rem; | ||||||
|  |   max-width: 50rem; | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .field-unit--nested { | ||||||
|  |   border: $base-border; | ||||||
|  |   margin-left: 7.5%; | ||||||
|  |   max-width: 60rem; | ||||||
|  |   padding: $small-spacing; | ||||||
|  |   width: 100%; | ||||||
|  |  | ||||||
|  |   .field-unit__field { | ||||||
|  |     width: 100%; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .field-unit__label { | ||||||
|  |     width: 10rem; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .field-unit--required { | ||||||
|  |   label::after { | ||||||
|  |     color: $red; | ||||||
|  |     content: ' *'; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .attribute-data--avatar-field { | ||||||
|  |   height: $space-larger; | ||||||
|  |   width: $space-larger; | ||||||
|  |  | ||||||
|  |   img { | ||||||
|  |     border-radius: 50%; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										28
									
								
								app/assets/stylesheets/administrate/components/_flashes.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/assets/stylesheets/administrate/components/_flashes.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | $base-spacing: 1.5em !default; | ||||||
|  | $flashes: ( | ||||||
|  |   "alert": #fff6bf, | ||||||
|  |   "error": #fbe3e4, | ||||||
|  |   "notice": #e5edf8, | ||||||
|  |   "success": #e6efc2, | ||||||
|  | ) !default; | ||||||
|  |  | ||||||
|  | @each $flash-type, $color in $flashes { | ||||||
|  |   .flash-#{$flash-type} { | ||||||
|  |     background-color: $color; | ||||||
|  |     color: mix($black, $color, 60%); | ||||||
|  |     display: block; | ||||||
|  |     margin-bottom: $base-spacing / 2; | ||||||
|  |     padding: $base-spacing / 2; | ||||||
|  |     text-align: center; | ||||||
|  |  | ||||||
|  |     a { | ||||||
|  |       color: mix($black, $color, 70%); | ||||||
|  |       text-decoration: underline; | ||||||
|  |  | ||||||
|  |       &:focus, | ||||||
|  |       &:hover { | ||||||
|  |         color: mix($black, $color, 90%); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | .form-actions { | ||||||
|  |   margin-left: calc(15% + 2rem); | ||||||
|  | } | ||||||
| @@ -0,0 +1,26 @@ | |||||||
|  | .main-content { | ||||||
|  |   font-size: $font-size-default; | ||||||
|  |   left: 23rem; | ||||||
|  |   position: absolute; | ||||||
|  |   right: 0; | ||||||
|  |   top: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .main-content__body { | ||||||
|  |   padding: $space-two; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .main-content__header { | ||||||
|  |   align-items: center; | ||||||
|  |   background-color: $color-white; | ||||||
|  |   border-bottom: 1px solid $color-border; | ||||||
|  |   display: flex; | ||||||
|  |   min-height: 5.6rem; | ||||||
|  |   padding: $space-small $space-normal; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .main-content__page-title { | ||||||
|  |   font-size: $font-size-large; | ||||||
|  |   font-weight: $font-weight-medium; | ||||||
|  |   margin-right: auto; | ||||||
|  | } | ||||||
| @@ -0,0 +1,72 @@ | |||||||
|  | .logo-brand { | ||||||
|  |   margin-bottom: $space-normal; | ||||||
|  |   padding: $space-normal $space-smaller; | ||||||
|  |   text-align: center; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .navigation { | ||||||
|  |   background: $white; | ||||||
|  |   border-right: 1px solid $color-border; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   font-size: $font-size-default; | ||||||
|  |   font-weight: $font-weight-medium; | ||||||
|  |   height: 100%; | ||||||
|  |   justify-content: flex-start; | ||||||
|  |   left: 0; | ||||||
|  |   margin: 0; | ||||||
|  |   overflow: auto; | ||||||
|  |   padding: $space-normal; | ||||||
|  |   position: fixed; | ||||||
|  |   top: 0; | ||||||
|  |   width: 23rem; | ||||||
|  |   z-index: 1023; | ||||||
|  |  | ||||||
|  |   li { | ||||||
|  |     align-items: center; | ||||||
|  |     display: flex; | ||||||
|  |  | ||||||
|  |     a { | ||||||
|  |       color: $color-gray; | ||||||
|  |       text-decoration: none; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     i { | ||||||
|  |       min-width: $space-medium; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .navigation__link { | ||||||
|  |   background-color: transparent; | ||||||
|  |   color: $color-gray; | ||||||
|  |   display: block; | ||||||
|  |   line-height: 1; | ||||||
|  |   margin-bottom: $space-smaller; | ||||||
|  |   padding: $space-one; | ||||||
|  |  | ||||||
|  |   &:hover { | ||||||
|  |     color: $blue; | ||||||
|  |  | ||||||
|  |     a { | ||||||
|  |       color: $blue; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   &.navigation__link--active { | ||||||
|  |     background-color: $color-background; | ||||||
|  |     border-radius: $base-border-radius; | ||||||
|  |     color: $blue; | ||||||
|  |  | ||||||
|  |     a { | ||||||
|  |       color: $blue; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .logout { | ||||||
|  |   bottom: $space-normal; | ||||||
|  |   left: $space-normal; | ||||||
|  |   position: fixed; | ||||||
|  | } | ||||||
| @@ -0,0 +1,19 @@ | |||||||
|  | .pagination { | ||||||
|  |   font-size: $font-size-default; | ||||||
|  |   margin-top: $base-spacing; | ||||||
|  |   padding-left: $base-spacing; | ||||||
|  |   padding-right: $base-spacing; | ||||||
|  |   text-align: center; | ||||||
|  |  | ||||||
|  |   .first, | ||||||
|  |   .prev, | ||||||
|  |   .page, | ||||||
|  |   .next, | ||||||
|  |   .last { | ||||||
|  |     margin: $small-spacing; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .current { | ||||||
|  |     font-weight: $font-weight-medium; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								app/assets/stylesheets/administrate/components/_reports.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/assets/stylesheets/administrate/components/_reports.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | .report--list { | ||||||
|  |   display: flex; | ||||||
|  |   padding: 0 $space-two $space-larger; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .report-card { | ||||||
|  |   flex: 1; | ||||||
|  |   font-size: $font-size-small; | ||||||
|  |   text-align: center; | ||||||
|  |  | ||||||
|  |   .metric { | ||||||
|  |     font-size: $font-size-bigger; | ||||||
|  |     font-weight: 200; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								app/assets/stylesheets/administrate/components/_search.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/assets/stylesheets/administrate/components/_search.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | .search { | ||||||
|  |   margin-left: auto; | ||||||
|  |   margin-right: 2rem; | ||||||
|  |   max-width: 24rem; | ||||||
|  |   position: relative; | ||||||
|  |   width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .search__input { | ||||||
|  |   background: $grey-1; | ||||||
|  |   padding-left: $space-normal * 2.5; | ||||||
|  |   padding-right: $space-normal * 2.5; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .search__eyeglass-icon { | ||||||
|  |   fill: $grey-7; | ||||||
|  |   height: $space-normal; | ||||||
|  |   left: $space-normal; | ||||||
|  |   position: absolute; | ||||||
|  |   top: 50%; | ||||||
|  |   transform: translateY(-50%); | ||||||
|  |   width: $space-normal; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .search__clear-link { | ||||||
|  |   height: $space-normal; | ||||||
|  |   position: absolute; | ||||||
|  |   right: $space-normal * 0.75; | ||||||
|  |   top: 50%; | ||||||
|  |   transform: translateY(-50%); | ||||||
|  |   width: $space-normal; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .search__clear-icon { | ||||||
|  |   fill: $grey-5; | ||||||
|  |   height: $space-normal; | ||||||
|  |   position: absolute; | ||||||
|  |   transition: fill $base-duration $base-timing; | ||||||
|  |   width: $space-normal; | ||||||
|  |  | ||||||
|  |   &:hover { | ||||||
|  |     fill: $action-color; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | @mixin administrate-clearfix { | ||||||
|  |   &::after { | ||||||
|  |     clear: both; | ||||||
|  |     content: ''; | ||||||
|  |     display: block; | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -0,0 +1,8 @@ | |||||||
|  | @mixin data-label { | ||||||
|  |   color: $hint-grey; | ||||||
|  |   font-size: 0.8em; | ||||||
|  |   font-weight: 400; | ||||||
|  |   letter-spacing: 0.0357em; | ||||||
|  |   position: relative; | ||||||
|  |   text-transform: uppercase; | ||||||
|  | } | ||||||
							
								
								
									
										61
									
								
								app/assets/stylesheets/administrate/library/_variables.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								app/assets/stylesheets/administrate/library/_variables.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | // Typography | ||||||
|  | $base-font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", | ||||||
|  |   "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", | ||||||
|  |   sans-serif !default; | ||||||
|  | $heading-font-family: $base-font-family !default; | ||||||
|  |  | ||||||
|  | $base-font-size: 10px !default; | ||||||
|  |  | ||||||
|  | $base-line-height: 1.5 !default; | ||||||
|  | $heading-line-height: 1.2 !default; | ||||||
|  |  | ||||||
|  | // Other Sizes | ||||||
|  | $base-border-radius: 4px !default; | ||||||
|  | $base-spacing: $base-line-height * 1em !default; | ||||||
|  | $small-spacing: $base-spacing / 2 !default; | ||||||
|  |  | ||||||
|  | // Colors | ||||||
|  | $white: #fff !default; | ||||||
|  | $black: #000 !default; | ||||||
|  |  | ||||||
|  | $blue: #1f93ff !default; | ||||||
|  | $red: #ff382d !default; | ||||||
|  | $light-yellow: #ffc532 !default; | ||||||
|  | $light-green: #44ce4b !default; | ||||||
|  |  | ||||||
|  | $grey-0: #f6f7f7 !default; | ||||||
|  | $grey-1: #f0f4f5 !default; | ||||||
|  | $grey-2: #cfd8dc !default; | ||||||
|  | $grey-5: #adb5bd !default; | ||||||
|  | $grey-7: #293f54 !default; | ||||||
|  |  | ||||||
|  | $hint-grey: #7b808c !default; | ||||||
|  |  | ||||||
|  | // Font Colors | ||||||
|  | $base-font-color: $grey-7 !default; | ||||||
|  | $action-color: $blue !default; | ||||||
|  |  | ||||||
|  | // Background Colors | ||||||
|  | $base-background-color: $grey-0 !default; | ||||||
|  |  | ||||||
|  | // Focus | ||||||
|  | $focus-outline-color: transparentize($action-color, 0.4); | ||||||
|  | $focus-outline-width: 3px; | ||||||
|  | $focus-outline: $focus-outline-width solid $focus-outline-color; | ||||||
|  | $focus-outline-offset: 1px; | ||||||
|  |  | ||||||
|  | // Flash Colors | ||||||
|  | $flash-colors: ( | ||||||
|  |   alert: $light-yellow, | ||||||
|  |   error: $red, | ||||||
|  |   notice: mix($white, $blue, 50%), | ||||||
|  |   success: $light-green | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | // Border | ||||||
|  | $base-border-color: $grey-1 !default; | ||||||
|  | $base-border: 1px solid $base-border-color !default; | ||||||
|  |  | ||||||
|  | // Transitions | ||||||
|  | $base-duration: 250ms !default; | ||||||
|  | $base-timing: ease-in-out !default; | ||||||
							
								
								
									
										447
									
								
								app/assets/stylesheets/administrate/reset/_normalize.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										447
									
								
								app/assets/stylesheets/administrate/reset/_normalize.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,447 @@ | |||||||
|  | /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */ | ||||||
|  |  | ||||||
|  | /* Document | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Correct the line height in all browsers. | ||||||
|  |  * 2. Prevent adjustments of font size after orientation changes in | ||||||
|  |  *    IE on Windows Phone and in iOS. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | html { | ||||||
|  |   line-height: 1.15; /* 1 */ | ||||||
|  |   -ms-text-size-adjust: 100%; /* 2 */ | ||||||
|  |   -webkit-text-size-adjust: 100%; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Sections | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Remove the margin in all browsers (opinionated). | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | body { | ||||||
|  |   margin: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct display in IE 9-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | article, | ||||||
|  | aside, | ||||||
|  | footer, | ||||||
|  | header, | ||||||
|  | nav, | ||||||
|  | section { | ||||||
|  |   display: block; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Correct the font size and margin on `h1` elements within `section` and | ||||||
|  |  * `article` contexts in Chrome, Firefox, and Safari. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | h1 { | ||||||
|  |   font-size: 2em; | ||||||
|  |   margin: 0.67em 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Grouping content | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct display in IE 9-. | ||||||
|  |  * 1. Add the correct display in IE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | figcaption, | ||||||
|  | figure, | ||||||
|  | main { /* 1 */ | ||||||
|  |   display: block; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct margin in IE 8. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | figure { | ||||||
|  |   margin: 1em 40px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Add the correct box sizing in Firefox. | ||||||
|  |  * 2. Show the overflow in Edge and IE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | hr { | ||||||
|  |   box-sizing: content-box; /* 1 */ | ||||||
|  |   height: 0; /* 1 */ | ||||||
|  |   overflow: visible; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Correct the inheritance and scaling of font size in all browsers. | ||||||
|  |  * 2. Correct the odd `em` font sizing in all browsers. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | pre { | ||||||
|  |   font-family: monospace, monospace; /* 1 */ | ||||||
|  |   font-size: 1em; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Text-level semantics | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Remove the gray background on active links in IE 10. | ||||||
|  |  * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | a { | ||||||
|  |   background-color: transparent; /* 1 */ | ||||||
|  |   -webkit-text-decoration-skip: objects; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Remove the bottom border in Chrome 57- and Firefox 39-. | ||||||
|  |  * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | abbr[title] { | ||||||
|  |   border-bottom: none; /* 1 */ | ||||||
|  |   text-decoration: underline; /* 2 */ | ||||||
|  |   text-decoration: underline dotted; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Prevent the duplicate application of `bolder` by the next rule in Safari 6. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | b, | ||||||
|  | strong { | ||||||
|  |   font-weight: inherit; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct font weight in Chrome, Edge, and Safari. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | b, | ||||||
|  | strong { | ||||||
|  |   font-weight: bolder; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Correct the inheritance and scaling of font size in all browsers. | ||||||
|  |  * 2. Correct the odd `em` font sizing in all browsers. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | code, | ||||||
|  | kbd, | ||||||
|  | samp { | ||||||
|  |   font-family: monospace, monospace; /* 1 */ | ||||||
|  |   font-size: 1em; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct font style in Android 4.3-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | dfn { | ||||||
|  |   font-style: italic; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct background and color in IE 9-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | mark { | ||||||
|  |   background-color: #ff0; | ||||||
|  |   color: #000; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct font size in all browsers. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | small { | ||||||
|  |   font-size: 80%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Prevent `sub` and `sup` elements from affecting the line height in | ||||||
|  |  * all browsers. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | sub, | ||||||
|  | sup { | ||||||
|  |   font-size: 75%; | ||||||
|  |   line-height: 0; | ||||||
|  |   position: relative; | ||||||
|  |   vertical-align: baseline; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub { | ||||||
|  |   bottom: -0.25em; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sup { | ||||||
|  |   top: -0.5em; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Embedded content | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct display in IE 9-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | audio, | ||||||
|  | video { | ||||||
|  |   display: inline-block; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct display in iOS 4-7. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | audio:not([controls]) { | ||||||
|  |   display: none; | ||||||
|  |   height: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Remove the border on images inside links in IE 10-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | img { | ||||||
|  |   border-style: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Hide the overflow in IE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | svg:not(:root) { | ||||||
|  |   overflow: hidden; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Forms | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Change the font styles in all browsers (opinionated). | ||||||
|  |  * 2. Remove the margin in Firefox and Safari. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | button, | ||||||
|  | input, | ||||||
|  | optgroup, | ||||||
|  | select, | ||||||
|  | textarea { | ||||||
|  |   font-family: sans-serif; /* 1 */ | ||||||
|  |   font-size: 100%; /* 1 */ | ||||||
|  |   line-height: 1.15; /* 1 */ | ||||||
|  |   margin: 0; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Show the overflow in IE. | ||||||
|  |  * 1. Show the overflow in Edge. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | button, | ||||||
|  | input { /* 1 */ | ||||||
|  |   overflow: visible; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Remove the inheritance of text transform in Edge, Firefox, and IE. | ||||||
|  |  * 1. Remove the inheritance of text transform in Firefox. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | button, | ||||||
|  | select { /* 1 */ | ||||||
|  |   text-transform: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` | ||||||
|  |  *    controls in Android 4. | ||||||
|  |  * 2. Correct the inability to style clickable types in iOS and Safari. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | button, | ||||||
|  | html [type="button"], /* 1 */ | ||||||
|  | [type="reset"], | ||||||
|  | [type="submit"] { | ||||||
|  |   -webkit-appearance: button; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Remove the inner border and padding in Firefox. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | button::-moz-focus-inner, | ||||||
|  | [type="button"]::-moz-focus-inner, | ||||||
|  | [type="reset"]::-moz-focus-inner, | ||||||
|  | [type="submit"]::-moz-focus-inner { | ||||||
|  |   border-style: none; | ||||||
|  |   padding: 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Restore the focus styles unset by the previous rule. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | button:-moz-focusring, | ||||||
|  | [type="button"]:-moz-focusring, | ||||||
|  | [type="reset"]:-moz-focusring, | ||||||
|  | [type="submit"]:-moz-focusring { | ||||||
|  |   outline: 1px dotted ButtonText; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Correct the padding in Firefox. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | fieldset { | ||||||
|  |   padding: 0.35em 0.75em 0.625em; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Correct the text wrapping in Edge and IE. | ||||||
|  |  * 2. Correct the color inheritance from `fieldset` elements in IE. | ||||||
|  |  * 3. Remove the padding so developers are not caught out when they zero out | ||||||
|  |  *    `fieldset` elements in all browsers. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | legend { | ||||||
|  |   box-sizing: border-box; /* 1 */ | ||||||
|  |   color: inherit; /* 2 */ | ||||||
|  |   display: table; /* 1 */ | ||||||
|  |   max-width: 100%; /* 1 */ | ||||||
|  |   padding: 0; /* 3 */ | ||||||
|  |   white-space: normal; /* 1 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Add the correct display in IE 9-. | ||||||
|  |  * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | progress { | ||||||
|  |   display: inline-block; /* 1 */ | ||||||
|  |   vertical-align: baseline; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Remove the default vertical scrollbar in IE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | textarea { | ||||||
|  |   overflow: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Add the correct box sizing in IE 10-. | ||||||
|  |  * 2. Remove the padding in IE 10-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | [type="checkbox"], | ||||||
|  | [type="radio"] { | ||||||
|  |   box-sizing: border-box; /* 1 */ | ||||||
|  |   padding: 0; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Correct the cursor style of increment and decrement buttons in Chrome. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | [type="number"]::-webkit-inner-spin-button, | ||||||
|  | [type="number"]::-webkit-outer-spin-button { | ||||||
|  |   height: auto; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Correct the odd appearance in Chrome and Safari. | ||||||
|  |  * 2. Correct the outline style in Safari. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | [type="search"] { | ||||||
|  |   -webkit-appearance: textfield; /* 1 */ | ||||||
|  |   outline-offset: -2px; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | [type="search"]::-webkit-search-cancel-button, | ||||||
|  | [type="search"]::-webkit-search-decoration { | ||||||
|  |   -webkit-appearance: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 1. Correct the inability to style clickable types in iOS and Safari. | ||||||
|  |  * 2. Change font properties to `inherit` in Safari. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | ::-webkit-file-upload-button { | ||||||
|  |   -webkit-appearance: button; /* 1 */ | ||||||
|  |   font: inherit; /* 2 */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Interactive | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Add the correct display in IE 9-. | ||||||
|  |  * 1. Add the correct display in Edge, IE, and Firefox. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | details, /* 1 */ | ||||||
|  | menu { | ||||||
|  |   display: block; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Add the correct display in all browsers. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | summary { | ||||||
|  |   display: list-item; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Scripting | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct display in IE 9-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | canvas { | ||||||
|  |   display: inline-block; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct display in IE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | template { | ||||||
|  |   display: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Hidden | ||||||
|  |    ========================================================================== */ | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Add the correct display in IE 10-. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | [hidden] { | ||||||
|  |   display: none; | ||||||
|  | } | ||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | .text-color-red { | ||||||
|  |   color: $alert-color; | ||||||
|  | } | ||||||
| @@ -0,0 +1,98 @@ | |||||||
|  | // Font sizes | ||||||
|  | $font-size-nano: 0.8rem; | ||||||
|  | $font-size-micro: 1.0rem; | ||||||
|  | $font-size-mini: 1.2rem; | ||||||
|  | $font-size-small: 1.4rem; | ||||||
|  | $font-size-default: 1.6rem; | ||||||
|  | $font-size-medium: 1.8rem; | ||||||
|  | $font-size-large: 2.2rem; | ||||||
|  | $font-size-big: 2.4rem; | ||||||
|  | $font-size-bigger: 3.0rem; | ||||||
|  | $font-size-mega: 3.4rem; | ||||||
|  | $font-size-giga: 4.0rem; | ||||||
|  |  | ||||||
|  | // spaces | ||||||
|  | $zero: 0; | ||||||
|  | $space-micro: 0.2rem; | ||||||
|  | $space-smaller: 0.4rem; | ||||||
|  | $space-small: 0.8rem; | ||||||
|  | $space-one: 1rem; | ||||||
|  | $space-slab: 1.2rem; | ||||||
|  | $space-normal: 1.6rem; | ||||||
|  | $space-two: 2.0rem; | ||||||
|  | $space-medium: 2.4rem; | ||||||
|  | $space-large: 3.2rem; | ||||||
|  | $space-larger: 4.8rem; | ||||||
|  | $space-jumbo: 6.4rem; | ||||||
|  | $space-mega: 10.0rem; | ||||||
|  |  | ||||||
|  | // font-weight | ||||||
|  | $font-weight-feather: 100; | ||||||
|  | $font-weight-light: 300; | ||||||
|  | $font-weight-normal: 400; | ||||||
|  | $font-weight-medium: 500; | ||||||
|  | $font-weight-bold: 600; | ||||||
|  | $font-weight-black: 700; | ||||||
|  |  | ||||||
|  | //Navbar | ||||||
|  | $nav-bar-width: 23rem; | ||||||
|  | $header-height: 5.6rem; | ||||||
|  |  | ||||||
|  | $woot-logo-padding: $space-large $space-two; | ||||||
|  |  | ||||||
|  | // Colors | ||||||
|  | $color-woot: #1f93ff; | ||||||
|  | $color-gray: #6e6f73; | ||||||
|  | $color-light-gray: #999a9b; | ||||||
|  | $color-border: #e0e6ed; | ||||||
|  | $color-border-light: #f0f4f5; | ||||||
|  | $color-background: #f4f6fb; | ||||||
|  | $color-border-dark: #cad0d4; | ||||||
|  | $color-background-light: #f9fafc; | ||||||
|  | $color-white: #fff; | ||||||
|  | $color-body: #3c4858; | ||||||
|  | $color-heading: #1f2d3d; | ||||||
|  | $color-extra-light-blue: #f5f7f9; | ||||||
|  |  | ||||||
|  | $primary-color: $color-woot; | ||||||
|  | $secondary-color: #35c5ff; | ||||||
|  | $success-color: #44ce4b; | ||||||
|  | $warning-color: #ffc532; | ||||||
|  | $alert-color: #ff382d; | ||||||
|  |  | ||||||
|  | $masked-bg: rgba(0, 0, 0, .4); | ||||||
|  |  | ||||||
|  | // Color-palettes | ||||||
|  |  | ||||||
|  | $color-primary-light: #c7e3ff; | ||||||
|  | $color-primary-dark: darken($color-woot, 20%); | ||||||
|  |  | ||||||
|  | // Thumbnail | ||||||
|  | $thumbnail-radius: 4rem; | ||||||
|  |  | ||||||
|  | // chat-header | ||||||
|  | $conv-header-height: 4rem; | ||||||
|  |  | ||||||
|  | // Inbox List | ||||||
|  |  | ||||||
|  | $inbox-thumb-size: 4.8rem; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Spinner | ||||||
|  | $spinkit-spinner-color: $color-white !default; | ||||||
|  | $spinkit-spinner-margin: 0 0 0 1.6rem !default; | ||||||
|  | $spinkit-size: 1.6rem !default; | ||||||
|  |  | ||||||
|  | // Snackbar default | ||||||
|  | $woot-snackbar-bg: #323232; | ||||||
|  | $woot-snackbar-button: #ffeb3b; | ||||||
|  |  | ||||||
|  | $swift-ease-out-duration: .4s !default; | ||||||
|  | $swift-ease-out-timing-function: cubic-bezier(.25, .8, .25, 1) !default; | ||||||
|  | $swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default; | ||||||
|  |  | ||||||
|  | // Ionicons | ||||||
|  | $ionicons-font-path: '~ionicons/fonts'; | ||||||
|  |  | ||||||
|  | // Transitions | ||||||
|  | $transition-ease-in: all 0.250s ease-in; | ||||||
| @@ -2,10 +2,32 @@ class SuperAdmin::AccountUsersController < SuperAdmin::ApplicationController | |||||||
|   # Overwrite any of the RESTful controller actions to implement custom behavior |   # Overwrite any of the RESTful controller actions to implement custom behavior | ||||||
|   # For example, you may want to send an email after a foo is updated. |   # For example, you may want to send an email after a foo is updated. | ||||||
|   # |   # | ||||||
|   # def update |   def create | ||||||
|   #   super |     resource = resource_class.new(resource_params) | ||||||
|   #   send_foo_updated_email(requested_resource) |     authorize_resource(resource) | ||||||
|   # end |  | ||||||
|  |     redirect_resource = params[:redirect_to] == 'user' ? resource.user : resource.account | ||||||
|  |     if resource.save | ||||||
|  |       redirect_to( | ||||||
|  |         [namespace, redirect_resource], | ||||||
|  |         notice: translate_with_resource('create.success') | ||||||
|  |       ) | ||||||
|  |     else | ||||||
|  |       redirect_to( | ||||||
|  |         [namespace, redirect_resource], | ||||||
|  |         notice: resource.errors.full_messages.first | ||||||
|  |       ) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def destroy | ||||||
|  |     if requested_resource.destroy | ||||||
|  |       flash[:notice] = translate_with_resource('destroy.success') | ||||||
|  |     else | ||||||
|  |       flash[:error] = requested_resource.errors.full_messages.join('<br/>') | ||||||
|  |     end | ||||||
|  |     redirect_to([namespace, requested_resource.account]) | ||||||
|  |   end | ||||||
|  |  | ||||||
|   # Override this method to specify custom lookup behavior. |   # Override this method to specify custom lookup behavior. | ||||||
|   # This will be used to set the resource for the `show`, `edit`, and `update` |   # This will be used to set the resource for the `show`, `edit`, and `update` | ||||||
|   | |||||||
| @@ -13,4 +13,11 @@ class SuperAdmin::ApplicationController < Administrate::ApplicationController | |||||||
|   # def records_per_page |   # def records_per_page | ||||||
|   #   params[:per_page] || 20 |   #   params[:per_page] || 20 | ||||||
|   # end |   # end | ||||||
|  |  | ||||||
|  |   def order | ||||||
|  |     @order ||= Administrate::Order.new( | ||||||
|  |       params.fetch(resource_name, {}).fetch(:order, 'id'), | ||||||
|  |       params.fetch(resource_name, {}).fetch(:direction, 'desc') | ||||||
|  |     ) | ||||||
|  |   end | ||||||
| end | end | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								app/controllers/super_admin/dashboard_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								app/controllers/super_admin/dashboard_controller.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | class SuperAdmin::DashboardController < SuperAdmin::ApplicationController | ||||||
|  |   include ActionView::Helpers::NumberHelper | ||||||
|  |  | ||||||
|  |   def index | ||||||
|  |     @data = Conversation.unscoped.group_by_day(:created_at, range: 30.days.ago..2.seconds.ago).count.to_a | ||||||
|  |     @accounts_count = number_with_delimiter(Account.all.length) | ||||||
|  |     @users_count = number_with_delimiter(User.all.length) | ||||||
|  |     @inboxes_count = number_with_delimiter(Inbox.all.length) | ||||||
|  |     @conversations_count = number_with_delimiter(Conversation.all.length) | ||||||
|  |     @messages_count = number_with_delimiter(Message.all.length) | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -12,7 +12,10 @@ class AccountDashboard < Administrate::BaseDashboard | |||||||
|     name: Field::String, |     name: Field::String, | ||||||
|     created_at: Field::DateTime, |     created_at: Field::DateTime, | ||||||
|     updated_at: Field::DateTime, |     updated_at: Field::DateTime, | ||||||
|     locale: Field::String.with_options(searchable: false) |     users: CountField, | ||||||
|  |     conversations: CountField, | ||||||
|  |     locale: Field::Select.with_options(collection: LANGUAGES_CONFIG.map { |_x, y| y[:iso_639_1_code] }), | ||||||
|  |     account_users: Field::HasMany | ||||||
|   }.freeze |   }.freeze | ||||||
|  |  | ||||||
|   # COLLECTION_ATTRIBUTES |   # COLLECTION_ATTRIBUTES | ||||||
| @@ -21,8 +24,11 @@ class AccountDashboard < Administrate::BaseDashboard | |||||||
|   # By default, it's limited to four items to reduce clutter on index pages. |   # By default, it's limited to four items to reduce clutter on index pages. | ||||||
|   # Feel free to add, remove, or rearrange items. |   # Feel free to add, remove, or rearrange items. | ||||||
|   COLLECTION_ATTRIBUTES = %i[ |   COLLECTION_ATTRIBUTES = %i[ | ||||||
|  |     id | ||||||
|     name |     name | ||||||
|     locale |     locale | ||||||
|  |     users | ||||||
|  |     conversations | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # SHOW_PAGE_ATTRIBUTES |   # SHOW_PAGE_ATTRIBUTES | ||||||
| @@ -33,6 +39,8 @@ class AccountDashboard < Administrate::BaseDashboard | |||||||
|     created_at |     created_at | ||||||
|     updated_at |     updated_at | ||||||
|     locale |     locale | ||||||
|  |     conversations | ||||||
|  |     account_users | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # FORM_ATTRIBUTES |   # FORM_ATTRIBUTES | ||||||
| @@ -58,7 +66,7 @@ class AccountDashboard < Administrate::BaseDashboard | |||||||
|   # Overwrite this method to customize how accounts are displayed |   # Overwrite this method to customize how accounts are displayed | ||||||
|   # across all pages of the admin dashboard. |   # across all pages of the admin dashboard. | ||||||
|   # |   # | ||||||
|   # def display_resource(account) |   def display_resource(account) | ||||||
|   #   "Account ##{account.id}" |     "##{account.id} #{account.name}" | ||||||
|   # end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -8,12 +8,11 @@ class AccountUserDashboard < Administrate::BaseDashboard | |||||||
|   # which determines how the attribute is displayed |   # which determines how the attribute is displayed | ||||||
|   # on pages throughout the dashboard. |   # on pages throughout the dashboard. | ||||||
|   ATTRIBUTE_TYPES = { |   ATTRIBUTE_TYPES = { | ||||||
|     account: Field::BelongsTo, |     account: Field::BelongsTo.with_options(searchable: true, searchable_field: 'name'), | ||||||
|     user: Field::BelongsTo, |     user: Field::BelongsTo.with_options(searchable: true, searchable_field: 'name'), | ||||||
|     inviter: Field::BelongsTo.with_options(class_name: 'User'), |     inviter: Field::BelongsTo.with_options(class_name: 'User', searchable: true, searchable_field: 'name'), | ||||||
|     id: Field::Number, |     id: Field::Number, | ||||||
|     role: Field::String.with_options(searchable: false), |     role: Field::Select.with_options(collection: AccountUser.roles.keys), | ||||||
|     inviter_id: Field::Number, |  | ||||||
|     created_at: Field::DateTime, |     created_at: Field::DateTime, | ||||||
|     updated_at: Field::DateTime |     updated_at: Field::DateTime | ||||||
|   }.freeze |   }.freeze | ||||||
| @@ -27,7 +26,7 @@ class AccountUserDashboard < Administrate::BaseDashboard | |||||||
|     account |     account | ||||||
|     user |     user | ||||||
|     inviter |     inviter | ||||||
|     id |     role | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # SHOW_PAGE_ATTRIBUTES |   # SHOW_PAGE_ATTRIBUTES | ||||||
| @@ -38,7 +37,6 @@ class AccountUserDashboard < Administrate::BaseDashboard | |||||||
|     inviter |     inviter | ||||||
|     id |     id | ||||||
|     role |     role | ||||||
|     inviter_id |  | ||||||
|     created_at |     created_at | ||||||
|     updated_at |     updated_at | ||||||
|   ].freeze |   ].freeze | ||||||
| @@ -49,9 +47,7 @@ class AccountUserDashboard < Administrate::BaseDashboard | |||||||
|   FORM_ATTRIBUTES = %i[ |   FORM_ATTRIBUTES = %i[ | ||||||
|     account |     account | ||||||
|     user |     user | ||||||
|     inviter |  | ||||||
|     role |     role | ||||||
|     inviter_id |  | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # COLLECTION_FILTERS |   # COLLECTION_FILTERS | ||||||
| @@ -69,7 +65,7 @@ class AccountUserDashboard < Administrate::BaseDashboard | |||||||
|   # Overwrite this method to customize how account users are displayed |   # Overwrite this method to customize how account users are displayed | ||||||
|   # across all pages of the admin dashboard. |   # across all pages of the admin dashboard. | ||||||
|   # |   # | ||||||
|   # def display_resource(account_user) |   def display_resource(account_user) | ||||||
|   #   "AccountUser ##{account_user.id}" |     "AccountUser ##{account_user.id}" | ||||||
|   # end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ class SuperAdminDashboard < Administrate::BaseDashboard | |||||||
|   ATTRIBUTE_TYPES = { |   ATTRIBUTE_TYPES = { | ||||||
|     id: Field::Number, |     id: Field::Number, | ||||||
|     email: Field::String, |     email: Field::String, | ||||||
|  |     password: Field::Password, | ||||||
|     access_token: Field::HasOne, |     access_token: Field::HasOne, | ||||||
|     remember_created_at: Field::DateTime, |     remember_created_at: Field::DateTime, | ||||||
|     sign_in_count: Field::Number, |     sign_in_count: Field::Number, | ||||||
| @@ -52,12 +53,7 @@ class SuperAdminDashboard < Administrate::BaseDashboard | |||||||
|   # on the model's form (`new` and `edit`) pages. |   # on the model's form (`new` and `edit`) pages. | ||||||
|   FORM_ATTRIBUTES = %i[ |   FORM_ATTRIBUTES = %i[ | ||||||
|     email |     email | ||||||
|     remember_created_at |     password | ||||||
|     sign_in_count |  | ||||||
|     current_sign_in_at |  | ||||||
|     last_sign_in_at |  | ||||||
|     current_sign_in_ip |  | ||||||
|     last_sign_in_ip |  | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # COLLECTION_FILTERS |   # COLLECTION_FILTERS | ||||||
|   | |||||||
| @@ -9,14 +9,11 @@ class UserDashboard < Administrate::BaseDashboard | |||||||
|   # on pages throughout the dashboard. |   # on pages throughout the dashboard. | ||||||
|   ATTRIBUTE_TYPES = { |   ATTRIBUTE_TYPES = { | ||||||
|     account_users: Field::HasMany, |     account_users: Field::HasMany, | ||||||
|     accounts: Field::HasMany, |  | ||||||
|     invitees: Field::HasMany.with_options(class_name: 'User'), |  | ||||||
|     id: Field::Number, |     id: Field::Number, | ||||||
|  |     avatar_url: AvatarField, | ||||||
|     provider: Field::String, |     provider: Field::String, | ||||||
|     uid: Field::String, |     uid: Field::String, | ||||||
|     reset_password_token: Field::String, |     password: Field::Password, | ||||||
|     reset_password_sent_at: Field::DateTime, |  | ||||||
|     remember_created_at: Field::DateTime, |  | ||||||
|     sign_in_count: Field::Number, |     sign_in_count: Field::Number, | ||||||
|     current_sign_in_at: Field::DateTime, |     current_sign_in_at: Field::DateTime, | ||||||
|     last_sign_in_at: Field::DateTime, |     last_sign_in_at: Field::DateTime, | ||||||
| @@ -32,7 +29,8 @@ class UserDashboard < Administrate::BaseDashboard | |||||||
|     tokens: Field::String.with_options(searchable: false), |     tokens: Field::String.with_options(searchable: false), | ||||||
|     created_at: Field::DateTime, |     created_at: Field::DateTime, | ||||||
|     updated_at: Field::DateTime, |     updated_at: Field::DateTime, | ||||||
|     pubsub_token: Field::String |     pubsub_token: Field::String, | ||||||
|  |     accounts: CountField | ||||||
|   }.freeze |   }.freeze | ||||||
|  |  | ||||||
|   # COLLECTION_ATTRIBUTES |   # COLLECTION_ATTRIBUTES | ||||||
| @@ -41,21 +39,25 @@ class UserDashboard < Administrate::BaseDashboard | |||||||
|   # By default, it's limited to four items to reduce clutter on index pages. |   # By default, it's limited to four items to reduce clutter on index pages. | ||||||
|   # Feel free to add, remove, or rearrange items. |   # Feel free to add, remove, or rearrange items. | ||||||
|   COLLECTION_ATTRIBUTES = %i[ |   COLLECTION_ATTRIBUTES = %i[ | ||||||
|  |     id | ||||||
|  |     avatar_url | ||||||
|     name |     name | ||||||
|     email |     email | ||||||
|  |     accounts | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # SHOW_PAGE_ATTRIBUTES |   # SHOW_PAGE_ATTRIBUTES | ||||||
|   # an array of attributes that will be displayed on the model's show page. |   # an array of attributes that will be displayed on the model's show page. | ||||||
|   SHOW_PAGE_ATTRIBUTES = %i[ |   SHOW_PAGE_ATTRIBUTES = %i[ | ||||||
|     accounts |  | ||||||
|     id |     id | ||||||
|  |     avatar_url | ||||||
|     unconfirmed_email |     unconfirmed_email | ||||||
|     name |     name | ||||||
|     nickname |     nickname | ||||||
|     email |     email | ||||||
|     created_at |     created_at | ||||||
|     updated_at |     updated_at | ||||||
|  |     account_users | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # FORM_ATTRIBUTES |   # FORM_ATTRIBUTES | ||||||
| @@ -65,6 +67,7 @@ class UserDashboard < Administrate::BaseDashboard | |||||||
|     name |     name | ||||||
|     nickname |     nickname | ||||||
|     email |     email | ||||||
|  |     password | ||||||
|   ].freeze |   ].freeze | ||||||
|  |  | ||||||
|   # COLLECTION_FILTERS |   # COLLECTION_FILTERS | ||||||
| @@ -82,7 +85,7 @@ class UserDashboard < Administrate::BaseDashboard | |||||||
|   # Overwrite this method to customize how users are displayed |   # Overwrite this method to customize how users are displayed | ||||||
|   # across all pages of the admin dashboard. |   # across all pages of the admin dashboard. | ||||||
|   # |   # | ||||||
|   # def display_resource(user) |   def display_resource(user) | ||||||
|   #   "User ##{user.id}" |     "##{user.id} #{user.name}" | ||||||
|   # end |   end | ||||||
| end | end | ||||||
|   | |||||||
							
								
								
									
										7
									
								
								app/fields/avatar_field.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/fields/avatar_field.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | require 'administrate/field/base' | ||||||
|  |  | ||||||
|  | class AvatarField < Administrate::Field::Base | ||||||
|  |   def avatar_url | ||||||
|  |     data.presence || '/admin/avatar.png' | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										7
									
								
								app/fields/count_field.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/fields/count_field.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | require 'administrate/field/base' | ||||||
|  |  | ||||||
|  | class CountField < Administrate::Field::Base | ||||||
|  |   def to_s | ||||||
|  |     data.count | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -1,13 +1,3 @@ | |||||||
| @import 'shared/assets/fonts/inter'; | @import 'shared/assets/fonts/inter'; | ||||||
| @import '../variables'; | @import '../variables'; | ||||||
|  | @import '~ionicons/scss/ionicons'; | ||||||
| body { |  | ||||||
|   background-color: $color-background; |  | ||||||
|   font-family: Inter; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .button { |  | ||||||
|   background-color: $color-woot; |  | ||||||
|   border-radius: 1px solid $color-woot; |  | ||||||
|   color: $color-white; |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ const runSDK = ({ baseUrl, websiteToken }) => { | |||||||
|     isOpen: false, |     isOpen: false, | ||||||
|     position: chatwootSettings.position === 'left' ? 'left' : 'right', |     position: chatwootSettings.position === 'left' ? 'left' : 'right', | ||||||
|     websiteToken, |     websiteToken, | ||||||
|     locale: chatwootSettings.locale || 'en', |     locale: chatwootSettings.locale, | ||||||
|  |  | ||||||
|     toggle() { |     toggle() { | ||||||
|       IFrameHelper.events.toggleBubble(); |       IFrameHelper.events.toggleBubble(); | ||||||
|   | |||||||
| @@ -1 +1,2 @@ | |||||||
| import '../dashboard/assets/scss/super_admin/pages.scss'; | import '../dashboard/assets/scss/super_admin/pages.scss'; | ||||||
|  | import 'chart.js'; | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ class AccountUser < ApplicationRecord | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   def destroy_notification_setting |   def destroy_notification_setting | ||||||
|     setting = user.notification_settings.new(account_id: account.id) |     setting = user.notification_settings.find_by(account_id: account.id) | ||||||
|     setting.destroy! |     setting.destroy! | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								app/views/fields/avatar_field/_index.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/views/fields/avatar_field/_index.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <%= image_tag field.avatar_url %> | ||||||
							
								
								
									
										1
									
								
								app/views/fields/avatar_field/_show.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/views/fields/avatar_field/_show.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <%= image_tag field.avatar_url %> | ||||||
							
								
								
									
										1
									
								
								app/views/fields/count_field/_index.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/views/fields/count_field/_index.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <%= field.to_s %> | ||||||
							
								
								
									
										1
									
								
								app/views/fields/count_field/_show.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								app/views/fields/count_field/_show.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <%= field.to_s %> | ||||||
							
								
								
									
										41
									
								
								app/views/layouts/super_admin/application.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/views/layouts/super_admin/application.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | <%# | ||||||
|  | # Application Layout | ||||||
|  |  | ||||||
|  | This view template is used as the layout | ||||||
|  | for every page that Administrate generates. | ||||||
|  |  | ||||||
|  | By default, it renders: | ||||||
|  | - Navigation | ||||||
|  | - Content for a search bar | ||||||
|  |   (if provided by a `content_for` block in a nested page) | ||||||
|  | - Flashes | ||||||
|  | - Links to stylesheets and JavaScripts | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="<%= I18n.locale %>"> | ||||||
|  | <head> | ||||||
|  |   <meta charset="utf-8"> | ||||||
|  |   <meta name="ROBOTS" content="NOODP"> | ||||||
|  |   <meta name="viewport" content="initial-scale=1"> | ||||||
|  |   <title> | ||||||
|  |     <%= content_for(:title) %> - <%= application_title %> | ||||||
|  |   </title> | ||||||
|  |   <%= render "stylesheet" %> | ||||||
|  |   <%= csrf_meta_tags %> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  |   <%= render "icons" %> | ||||||
|  |  | ||||||
|  |   <div class="app-container super-admin"> | ||||||
|  |     <%= render "navigation" -%> | ||||||
|  |  | ||||||
|  |     <main class="main-content" role="main"> | ||||||
|  |       <%= render "flashes" -%> | ||||||
|  |       <%= yield %> | ||||||
|  |     </main> | ||||||
|  |   </div> | ||||||
|  |  | ||||||
|  |   <%= render "javascript" %> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										88
									
								
								app/views/super_admin/accounts/show.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/views/super_admin/accounts/show.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | <%# | ||||||
|  | # Show | ||||||
|  |  | ||||||
|  | This view is the template for the show page. | ||||||
|  | It renders the attributes of a resource, | ||||||
|  | as well as a link to its edit page. | ||||||
|  |  | ||||||
|  | ## Local variables: | ||||||
|  |  | ||||||
|  | - `page`: | ||||||
|  |   An instance of [Administrate::Page::Show][1]. | ||||||
|  |   Contains methods for accessing the resource to be displayed on the page, | ||||||
|  |   as well as helpers for describing how each attribute of the resource | ||||||
|  |   should be displayed. | ||||||
|  |  | ||||||
|  | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <% content_for(:title) { t("administrate.actions.show_resource", name: page.page_title) } %> | ||||||
|  |  | ||||||
|  | <header class="main-content__header" role="banner"> | ||||||
|  |   <h1 class="main-content__page-title"> | ||||||
|  |     <%= content_for(:title) %> | ||||||
|  |   </h1> | ||||||
|  |  | ||||||
|  |   <div> | ||||||
|  |     <%= link_to( | ||||||
|  |       t("administrate.actions.edit_resource", name: page.page_title), | ||||||
|  |       [:edit, namespace, page.resource], | ||||||
|  |       class: "button", | ||||||
|  |     ) if valid_action?(:edit) && show_action?(:edit, page.resource) %> | ||||||
|  |   </div> | ||||||
|  | </header> | ||||||
|  |  | ||||||
|  | <section class="main-content__body"> | ||||||
|  |   <dl> | ||||||
|  |     <% page.attributes.each do |attribute| %> | ||||||
|  |       <dt class="attribute-label" id="<%= attribute.name %>"> | ||||||
|  |       <%= t( | ||||||
|  |         "helpers.label.#{resource_name}.#{attribute.name}", | ||||||
|  |         default: attribute.name.titleize, | ||||||
|  |       ) %> | ||||||
|  |       </dt> | ||||||
|  |  | ||||||
|  |       <dd class="attribute-data attribute-data--<%=attribute.html_class%>" | ||||||
|  |           ><%= render_field attribute, page: page %></dd> | ||||||
|  |     <% end %> | ||||||
|  |   </dl> | ||||||
|  | </section> | ||||||
|  |  | ||||||
|  | <section class="main-content__body"> | ||||||
|  |   <% account_user_page = Administrate::Page::Form.new(AccountUserDashboard.new, AccountUser.new) %> | ||||||
|  |   <%= form_for([namespace, account_user_page.resource], html: { class: "form" }) do |f| %> | ||||||
|  |   <% if account_user_page.resource.errors.any? %> | ||||||
|  |     <div id="error_explanation"> | ||||||
|  |       <h2> | ||||||
|  |         <%= t( | ||||||
|  |           "administrate.form.errors", | ||||||
|  |           pluralized_errors: pluralize(account_user_page.resource.errors.count, t("administrate.form.error")), | ||||||
|  |           resource_name: display_resource_name(account_user_page.resource_name) | ||||||
|  |         ) %> | ||||||
|  |       </h2> | ||||||
|  |  | ||||||
|  |       <ul> | ||||||
|  |         <% account_user_page.resource.errors.full_messages.each do |message| %> | ||||||
|  |           <li class="flash-error"><%= message %></li> | ||||||
|  |         <% end %> | ||||||
|  |       </ul> | ||||||
|  |     </div> | ||||||
|  |   <% end %> | ||||||
|  |  | ||||||
|  |   <% account_user_page.attributes.each do |attribute| -%> | ||||||
|  |     <% if attribute.name == "account" %> | ||||||
|  |       <%= f.hidden_field('account_id', value: page.resource.id) %> | ||||||
|  |       <%= f.hidden_field('redirect_to', value: 'user') %> | ||||||
|  |     <% else %> | ||||||
|  |     <div class="field-unit field-unit--<%= attribute.html_class %> field-unit--<%= requireness(attribute) %>"> | ||||||
|  |       <%= render_field attribute, f: f %> | ||||||
|  |     </div> | ||||||
|  |     <% end %> | ||||||
|  |   <% end -%> | ||||||
|  |  | ||||||
|  |   <div class="form-actions"> | ||||||
|  |     <%= f.submit %> | ||||||
|  |   </div> | ||||||
|  | <% end %> | ||||||
|  |  | ||||||
|  | </section> | ||||||
							
								
								
									
										95
									
								
								app/views/super_admin/application/_collection.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								app/views/super_admin/application/_collection.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | <%# | ||||||
|  | # Collection | ||||||
|  |  | ||||||
|  | This partial is used on the `index` and `show` pages | ||||||
|  | to display a collection of resources in an HTML table. | ||||||
|  |  | ||||||
|  | ## Local variables: | ||||||
|  |  | ||||||
|  | - `collection_presenter`: | ||||||
|  |   An instance of [Administrate::Page::Collection][1]. | ||||||
|  |   The table presenter uses `ResourceDashboard::COLLECTION_ATTRIBUTES` to determine | ||||||
|  |   the columns displayed in the table | ||||||
|  | - `resources`: | ||||||
|  |   An ActiveModel::Relation collection of resources to be displayed in the table. | ||||||
|  |   By default, the number of resources is limited by pagination | ||||||
|  |   or by a hard limit to prevent excessive page load times | ||||||
|  |  | ||||||
|  | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <table aria-labelledby="<%= table_title %>"> | ||||||
|  |   <thead> | ||||||
|  |     <tr> | ||||||
|  |       <% collection_presenter.attribute_types.each do |attr_name, attr_type| %> | ||||||
|  |         <th class="cell-label | ||||||
|  |         cell-label--<%= attr_type.html_class %> | ||||||
|  |         cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>" | ||||||
|  |         scope="col" | ||||||
|  |         role="columnheader" | ||||||
|  |         aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>"> | ||||||
|  |         <%= link_to(sanitized_order_params(page, collection_field_name).merge( | ||||||
|  |           collection_presenter.order_params_for(attr_name, key: collection_field_name) | ||||||
|  |         )) do %> | ||||||
|  |         <%= t( | ||||||
|  |           "helpers.label.#{collection_presenter.resource_name}.#{attr_name}", | ||||||
|  |           default: attr_name.to_s, | ||||||
|  |         ).titleize %> | ||||||
|  |             <% if collection_presenter.ordered_by?(attr_name) %> | ||||||
|  |               <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>"> | ||||||
|  |                 <svg aria-hidden="true"> | ||||||
|  |                   <use xlink:href="#icon-up-caret" /> | ||||||
|  |                 </svg> | ||||||
|  |               </span> | ||||||
|  |             <% end %> | ||||||
|  |           <% end %> | ||||||
|  |         </th> | ||||||
|  |       <% end %> | ||||||
|  |       <% [valid_action?(:edit, collection_presenter.resource_name), | ||||||
|  |           valid_action?(:destroy, collection_presenter.resource_name)].count(true).times do %> | ||||||
|  |         <th scope="col"></th> | ||||||
|  |       <% end %> | ||||||
|  |     </tr> | ||||||
|  |   </thead> | ||||||
|  |  | ||||||
|  |   <tbody> | ||||||
|  |     <% resources.each do |resource| %> | ||||||
|  |       <tr class="js-table-row" | ||||||
|  |           tabindex="0" | ||||||
|  |           <% if valid_action? :show, collection_presenter.resource_name %> | ||||||
|  |             <%= %(role=link data-url=#{polymorphic_path([namespace, resource])}) %> | ||||||
|  |           <% end %> | ||||||
|  |           > | ||||||
|  |         <% collection_presenter.attributes_for(resource).each do |attribute| %> | ||||||
|  |           <td class="cell-data cell-data--<%= attribute.html_class %>"> | ||||||
|  |             <% if show_action? :show, resource -%> | ||||||
|  |               <a href="<%= polymorphic_path([namespace, resource]) -%>" | ||||||
|  |                  class="action-show" | ||||||
|  |                  > | ||||||
|  |                 <%= render_field attribute %> | ||||||
|  |               </a> | ||||||
|  |             <% end -%> | ||||||
|  |           </td> | ||||||
|  |         <% end %> | ||||||
|  |  | ||||||
|  |         <% if valid_action? :edit, collection_presenter.resource_name %> | ||||||
|  |           <td><%= link_to( | ||||||
|  |             t("administrate.actions.edit"), | ||||||
|  |             [:edit, namespace, resource], | ||||||
|  |             class: "action-edit", | ||||||
|  |           ) if show_action? :edit, resource%></td> | ||||||
|  |         <% end %> | ||||||
|  |  | ||||||
|  |         <% if valid_action? :destroy, collection_presenter.resource_name %> | ||||||
|  |           <td><%= link_to( | ||||||
|  |             t("administrate.actions.destroy"), | ||||||
|  |             [namespace, resource], | ||||||
|  |             class: "text-color-red", | ||||||
|  |             method: :delete, | ||||||
|  |             data: { confirm: t("administrate.actions.confirm") } | ||||||
|  |           ) if show_action? :destroy, resource %></td> | ||||||
|  |         <% end %> | ||||||
|  |       </tr> | ||||||
|  |     <% end %> | ||||||
|  |   </tbody> | ||||||
|  | </table> | ||||||
							
								
								
									
										20
									
								
								app/views/super_admin/application/_flashes.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/views/super_admin/application/_flashes.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | <%# | ||||||
|  | # Flash Partial | ||||||
|  |  | ||||||
|  | This partial renders flash messages on every page. | ||||||
|  |  | ||||||
|  | ## Relevant Helpers: | ||||||
|  |  | ||||||
|  | - `flash`: | ||||||
|  |   Returns a hash, | ||||||
|  |   where the keys are the type of flash (alert, error, notice, etc) | ||||||
|  |   and the values are the message to be displayed. | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <% if flash.any? %> | ||||||
|  |   <div class="flashes"> | ||||||
|  |     <% flash.each do |key, value| -%> | ||||||
|  |       <div class="flash flash-<%= key %>"><%= value.to_s.html_safe %></div> | ||||||
|  |     <% end -%> | ||||||
|  |   </div> | ||||||
|  | <% end %> | ||||||
							
								
								
									
										13
									
								
								app/views/super_admin/application/_icons.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/views/super_admin/application/_icons.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" style="display: none;"> | ||||||
|  |   <symbol id="icon-cancel" viewBox="0 0 48 48"> | ||||||
|  |     <path fill-rule="evenodd" d="M24 19.757l-8.485-8.485c-.784-.783-2.047-.782-2.827 0l-1.417 1.416c-.777.777-.78 2.046.002 2.827L19.757 24l-8.485 8.485c-.783.784-.782 2.047 0 2.827l1.416 1.417c.777.777 2.046.78 2.827-.002L24 28.243l8.485 8.485c.784.783 2.047.782 2.827 0l1.417-1.416c.777-.777.78-2.046-.002-2.827L28.243 24l8.485-8.485c.783-.784.782-2.047 0-2.827l-1.416-1.417c-.777-.777-2.046-.78-2.827.002L24 19.757zM24 47c12.703 0 23-10.297 23-23S36.703 1 24 1 1 11.297 1 24s10.297 23 23 23z" /> | ||||||
|  |   </symbol> | ||||||
|  |  | ||||||
|  |   <symbol id="icon-eyeglass" viewBox="0 0 48 48"> | ||||||
|  |     <path d="M27.885 32.515c-2.864 1.966-6.333 3.116-10.07 3.116C7.976 35.63 0 27.656 0 17.817 0 7.976 7.976 0 17.816 0S35.63 7.976 35.63 17.816c0 3.736-1.15 7.205-3.115 10.07l14.53 14.53c1.278 1.277 1.275 3.352 0 4.628-1.28 1.278-3.353 1.278-4.63 0l-14.53-14.53zm-10.07-3.736c6.056 0 10.964-4.91 10.964-10.964 0-6.055-4.91-10.964-10.964-10.964-6.055 0-10.964 4.91-10.964 10.964 0 6.055 4.91 10.963 10.964 10.963z" /> | ||||||
|  |   </symbol> | ||||||
|  |  | ||||||
|  |   <symbol id="icon-up-caret" viewBox="0 0 48 48"> | ||||||
|  |     <path d="M2.988 33.02c-1.66 0-1.943-.81-.618-1.824l20-15.28c.878-.672 2.31-.67 3.188 0l20.075 15.288c1.316 1.003 1.048 1.816-.62 1.816H2.987z" /> | ||||||
|  |   </symbol> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.3 KiB | 
							
								
								
									
										21
									
								
								app/views/super_admin/application/_javascript.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/views/super_admin/application/_javascript.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | <%# | ||||||
|  | # Javascript Partial | ||||||
|  |  | ||||||
|  | This partial imports the necessary javascript on each page. | ||||||
|  | By default, it includes the application JS, | ||||||
|  | but each page can define additional JS sources | ||||||
|  | by providing a `content_for(:javascript)` block. | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <% Administrate::Engine.javascripts.each do |js_path| %> | ||||||
|  |   <%= javascript_include_tag js_path %> | ||||||
|  | <% end %> | ||||||
|  |  | ||||||
|  | <%= yield :javascript %> | ||||||
|  |  | ||||||
|  | <% if Rails.env.test? %> | ||||||
|  |   <%= javascript_tag do %> | ||||||
|  |     $.fx.off = true; | ||||||
|  |     $.ajaxSetup({ async: false }); | ||||||
|  |   <% end %> | ||||||
|  | <% end %> | ||||||
| @@ -10,21 +10,43 @@ as defined by the routes in the `admin/` namespace | |||||||
| <%= javascript_pack_tag 'superadmin_pages' %> | <%= javascript_pack_tag 'superadmin_pages' %> | ||||||
| <%= stylesheet_pack_tag 'superadmin_pages' %> | <%= stylesheet_pack_tag 'superadmin_pages' %> | ||||||
|  |  | ||||||
|  | <% | ||||||
|  |   sidebar_icons = { | ||||||
|  |     accounts: 'ion ion-briefcase', | ||||||
|  |     users: 'ion ion-person-stalker', | ||||||
|  |     super_admins: 'ion ion-unlocked', | ||||||
|  |     access_tokens: 'ion-key' | ||||||
|  |   } | ||||||
|  | %> | ||||||
|  |  | ||||||
| <nav class="navigation" role="navigation"> | <div class="navigation" role="navigation"> | ||||||
|   <%= link_to "Dashboard", super_admin_root_url, class: "button button--alt" %> |   <div class="logo-brand"> | ||||||
|   |     <%= link_to image_tag('/brand-assets/logo.svg', alt: 'Chatwoot Admin Dashboard'), super_admin_root_url %> | ||||||
|   <% Administrate::Namespace.new(namespace).resources.each do |resource| %> |  | ||||||
|     <%= link_to( |  | ||||||
|       display_resource_name(resource), |  | ||||||
|       [namespace, resource_index_route_key(resource)], |  | ||||||
|       class: "navigation__link navigation__link--#{nav_link_state(resource)}" |  | ||||||
|     ) if valid_action? :index, resource  %> |  | ||||||
|   <% end %> |  | ||||||
|  |  | ||||||
|   <%= link_to "Sidekiq", sidekiq_web_url , class: "button" %> |  | ||||||
|    |  | ||||||
|   <div style="margin-top: 300px;"> |  | ||||||
|     <%= link_to "Logout", super_admin_logout_url , class: "button button--alt" %> |  | ||||||
|   </div> |   </div> | ||||||
| </nav> |  | ||||||
|  |   <ul> | ||||||
|  |     <li class="navigation__link"> | ||||||
|  |       <i class="ion ion-ios-keypad"></i> | ||||||
|  |       <%= link_to "Dashboard", super_admin_root_url %> | ||||||
|  |     </li> | ||||||
|  |     <% Administrate::Namespace.new(namespace).resources.each do |resource| %> | ||||||
|  |       <% next if ["account_users", "dashboard", "devise/sessions"].include?  resource.resource %> | ||||||
|  |       <li class="navigation__link navigation__link--<%= nav_link_state(resource) %>"> | ||||||
|  |         <i class="<%= sidebar_icons[resource.resource.to_sym] %>"></i> | ||||||
|  |         <%= link_to( | ||||||
|  |           display_resource_name(resource), | ||||||
|  |           [namespace, resource_index_route_key(resource)], | ||||||
|  |         ) if valid_action? :index, resource  %> | ||||||
|  |       </li> | ||||||
|  |     <% end %> | ||||||
|  |  | ||||||
|  |     <li class="navigation__link"> | ||||||
|  |       <i class="ion ion ion-network"></i> | ||||||
|  |       <%= link_to "Sidekiq", sidekiq_web_url %> | ||||||
|  |     </li> | ||||||
|  |   </ul> | ||||||
|  |   <li class="navigation__link logout"> | ||||||
|  |     <i class="ion ion-log-out"></i> | ||||||
|  |     <%= link_to "Logout", super_admin_logout_url %> | ||||||
|  |   </li> | ||||||
|  | </div> | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								app/views/super_admin/application/_stylesheet.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								app/views/super_admin/application/_stylesheet.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | <%# | ||||||
|  | # Stylesheet Partial | ||||||
|  |  | ||||||
|  | This partial imports the necessary stylesheets on each page. | ||||||
|  | By default, it includes the application CSS, | ||||||
|  | but each page can define additional CSS sources | ||||||
|  | by providing a `content_for(:stylesheet)` block. | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <% Administrate::Engine.stylesheets.each do |css_path| %> | ||||||
|  |   <%= stylesheet_link_tag css_path %> | ||||||
|  | <% end %> | ||||||
|  |  | ||||||
|  | <%= yield :stylesheet %> | ||||||
							
								
								
									
										66
									
								
								app/views/super_admin/application/index.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								app/views/super_admin/application/index.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | <%# | ||||||
|  | # Index | ||||||
|  |  | ||||||
|  | This view is the template for the index page. | ||||||
|  | It is responsible for rendering the search bar, header and pagination. | ||||||
|  | It renders the `_table` partial to display details about the resources. | ||||||
|  |  | ||||||
|  | ## Local variables: | ||||||
|  |  | ||||||
|  | - `page`: | ||||||
|  |   An instance of [Administrate::Page::Collection][1]. | ||||||
|  |   Contains helper methods to help display a table, | ||||||
|  |   and knows which attributes should be displayed in the resource's table. | ||||||
|  | - `resources`: | ||||||
|  |   An instance of `ActiveRecord::Relation` containing the resources | ||||||
|  |   that match the user's search criteria. | ||||||
|  |   By default, these resources are passed to the table partial to be displayed. | ||||||
|  | - `search_term`: | ||||||
|  |   A string containing the term the user has searched for, if any. | ||||||
|  | - `show_search_bar`: | ||||||
|  |   A boolean that determines if the search bar should be shown. | ||||||
|  |  | ||||||
|  | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <% content_for(:title) do %> | ||||||
|  |   <%= display_resource_name(page.resource_name) %> | ||||||
|  | <% end %> | ||||||
|  |  | ||||||
|  | <header class="main-content__header" role="banner"> | ||||||
|  |   <h1 class="main-content__page-title" id="page-title"> | ||||||
|  |     <%= content_for(:title) %> | ||||||
|  |   </h1> | ||||||
|  |  | ||||||
|  |   <% if show_search_bar %> | ||||||
|  |     <%= render( | ||||||
|  |       "search", | ||||||
|  |       search_term: search_term, | ||||||
|  |       resource_name: display_resource_name(page.resource_name) | ||||||
|  |     ) %> | ||||||
|  |   <% end %> | ||||||
|  |  | ||||||
|  |   <div> | ||||||
|  |     <%= link_to( | ||||||
|  |       t( | ||||||
|  |         "administrate.actions.new_resource", | ||||||
|  |         name: page.resource_name.titleize.downcase | ||||||
|  |       ), | ||||||
|  |       [:new, namespace, page.resource_path], | ||||||
|  |       class: "button", | ||||||
|  |     ) if valid_action?(:new) && show_action?(:new, new_resource) %> | ||||||
|  |   </div> | ||||||
|  | </header> | ||||||
|  |  | ||||||
|  | <section class="main-content__body main-content__body--flush"> | ||||||
|  |   <%= render( | ||||||
|  |     "collection", | ||||||
|  |     collection_presenter: page, | ||||||
|  |     collection_field_name: resource_name, | ||||||
|  |     page: page, | ||||||
|  |     resources: resources, | ||||||
|  |     table_title: "page-title" | ||||||
|  |   ) %> | ||||||
|  |  | ||||||
|  |   <%= paginate resources %> | ||||||
|  | </section> | ||||||
							
								
								
									
										69
									
								
								app/views/super_admin/dashboard/index.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								app/views/super_admin/dashboard/index.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | |||||||
|  | <%# | ||||||
|  | # Index | ||||||
|  |  | ||||||
|  | This view is the template for the index page. | ||||||
|  | It is responsible for rendering the search bar, header and pagination. | ||||||
|  | It renders the `_table` partial to display details about the resources. | ||||||
|  |  | ||||||
|  | ## Local variables: | ||||||
|  |  | ||||||
|  | - `page`: | ||||||
|  |   An instance of [Administrate::Page::Collection][1]. | ||||||
|  |   Contains helper methods to help display a table, | ||||||
|  |   and knows which attributes should be displayed in the resource's table. | ||||||
|  | - `resources`: | ||||||
|  |   An instance of `ActiveRecord::Relation` containing the resources | ||||||
|  |   that match the user's search criteria. | ||||||
|  |   By default, these resources are passed to the table partial to be displayed. | ||||||
|  | - `search_term`: | ||||||
|  |   A string containing the term the user has searched for, if any. | ||||||
|  | - `show_search_bar`: | ||||||
|  |   A boolean that determines if the search bar should be shown. | ||||||
|  |  | ||||||
|  | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection | ||||||
|  | %> | ||||||
|  | <%= javascript_include_tag "dashboardChart" %> | ||||||
|  |  | ||||||
|  | <% content_for(:title) do %> | ||||||
|  |   Admin Dashboard | ||||||
|  | <% end %> | ||||||
|  |  | ||||||
|  | <header class="main-content__header" role="banner"> | ||||||
|  |   <h1 class="main-content__page-title" id="page-title"> | ||||||
|  |     <%= content_for(:title) %> | ||||||
|  |   </h1> | ||||||
|  | </header> | ||||||
|  |  | ||||||
|  | <section class="main-content__body main-content__body--flush"> | ||||||
|  |  | ||||||
|  | <div class="report--list"> | ||||||
|  |   <div class="report-card"> | ||||||
|  |     <div class="metric"><%= @accounts_count %></div> | ||||||
|  |     <div>Accounts</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="report-card"> | ||||||
|  |     <div class="metric"><%= @users_count  %></div> | ||||||
|  |     <div>Users</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="report-card"> | ||||||
|  |     <div class="metric"><%= @inboxes_count  %></div> | ||||||
|  |     <div>Inboxes</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="report-card"> | ||||||
|  |     <div class="metric"><%= @conversations_count %></div> | ||||||
|  |     <div>Conversations</div> | ||||||
|  |   </div> | ||||||
|  |   <div class="report-card"> | ||||||
|  |     <div class="metric"><%= @messages_count %></div> | ||||||
|  |     <div>Messages</div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
|  |  | ||||||
|  | <div class="chart--container" style="height:500px"> | ||||||
|  |   <canvas id="dashboard-chart" width="500" height="250"></canvas> | ||||||
|  | </div> | ||||||
|  | <%= javascript_tag do -%> | ||||||
|  | drawSuperAdminDashboard(<%= @data.to_json.html_safe -%>) | ||||||
|  | <% end -%> | ||||||
|  |  | ||||||
|  | </section> | ||||||
							
								
								
									
										95
									
								
								app/views/super_admin/users/_collection.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								app/views/super_admin/users/_collection.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | <%# | ||||||
|  | # Collection | ||||||
|  |  | ||||||
|  | This partial is used on the `index` and `show` pages | ||||||
|  | to display a collection of resources in an HTML table. | ||||||
|  |  | ||||||
|  | ## Local variables: | ||||||
|  |  | ||||||
|  | - `collection_presenter`: | ||||||
|  |   An instance of [Administrate::Page::Collection][1]. | ||||||
|  |   The table presenter uses `ResourceDashboard::COLLECTION_ATTRIBUTES` to determine | ||||||
|  |   the columns displayed in the table | ||||||
|  | - `resources`: | ||||||
|  |   An ActiveModel::Relation collection of resources to be displayed in the table. | ||||||
|  |   By default, the number of resources is limited by pagination | ||||||
|  |   or by a hard limit to prevent excessive page load times | ||||||
|  |  | ||||||
|  | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <table aria-labelledby="<%= table_title %>"> | ||||||
|  |   <thead> | ||||||
|  |     <tr> | ||||||
|  |       <% collection_presenter.attribute_types.each do |attr_name, attr_type| %> | ||||||
|  |         <th class="cell-label | ||||||
|  |         cell-label--<%= attr_type.html_class %> | ||||||
|  |         cell-label--<%= collection_presenter.ordered_html_class(attr_name) %>" | ||||||
|  |         scope="col" | ||||||
|  |         role="columnheader" | ||||||
|  |         aria-sort="<%= sort_order(collection_presenter.ordered_html_class(attr_name)) %>"> | ||||||
|  |         <%= link_to(sanitized_order_params(page, collection_field_name).merge( | ||||||
|  |           collection_presenter.order_params_for(attr_name, key: collection_field_name) | ||||||
|  |         )) do %> | ||||||
|  |         <%= t( | ||||||
|  |           "helpers.label.#{collection_presenter.resource_name}.#{attr_name}", | ||||||
|  |           default: attr_name.to_s, | ||||||
|  |         ).titleize %> | ||||||
|  |             <% if collection_presenter.ordered_by?(attr_name) %> | ||||||
|  |               <span class="cell-label__sort-indicator cell-label__sort-indicator--<%= collection_presenter.ordered_html_class(attr_name) %>"> | ||||||
|  |                 <svg aria-hidden="true"> | ||||||
|  |                   <use xlink:href="#icon-up-caret" /> | ||||||
|  |                 </svg> | ||||||
|  |               </span> | ||||||
|  |             <% end %> | ||||||
|  |           <% end %> | ||||||
|  |         </th> | ||||||
|  |       <% end %> | ||||||
|  |       <% [valid_action?(:edit, collection_presenter.resource_name), | ||||||
|  |           valid_action?(:destroy, collection_presenter.resource_name)].count(true).times do %> | ||||||
|  |         <th scope="col"></th> | ||||||
|  |       <% end %> | ||||||
|  |     </tr> | ||||||
|  |   </thead> | ||||||
|  |  | ||||||
|  |   <tbody> | ||||||
|  |     <% resources.each do |resource| %> | ||||||
|  |       <tr class="js-table-row" | ||||||
|  |           tabindex="0" | ||||||
|  |           <% if valid_action? :show, collection_presenter.resource_name %> | ||||||
|  |             <%= %(role=link data-url=#{polymorphic_path([namespace, resource])}) %> | ||||||
|  |           <% end %> | ||||||
|  |           > | ||||||
|  |         <% collection_presenter.attributes_for(resource).each do |attribute| %> | ||||||
|  |           <td class="cell-data cell-data--<%= attribute.html_class %>"> | ||||||
|  |             <% if show_action? :show, resource -%> | ||||||
|  |               <a href="<%= polymorphic_path([namespace, resource]) -%>" | ||||||
|  |                  class="action-show" | ||||||
|  |                  > | ||||||
|  |                 <%= render_field attribute %> | ||||||
|  |               </a> | ||||||
|  |             <% end -%> | ||||||
|  |           </td> | ||||||
|  |         <% end %> | ||||||
|  |  | ||||||
|  |         <% if valid_action? :edit, collection_presenter.resource_name %> | ||||||
|  |           <td><%= link_to( | ||||||
|  |             t("administrate.actions.edit"), | ||||||
|  |             [:edit, namespace, resource], | ||||||
|  |             class: "action-edit", | ||||||
|  |           ) if show_action? :edit, resource%></td> | ||||||
|  |         <% end %> | ||||||
|  |  | ||||||
|  |         <% if valid_action? :destroy, collection_presenter.resource_name %> | ||||||
|  |           <td><%= link_to( | ||||||
|  |             t("administrate.actions.destroy"), | ||||||
|  |             [namespace, resource], | ||||||
|  |             class: "text-color-red", | ||||||
|  |             method: :delete, | ||||||
|  |             data: { confirm: t("administrate.actions.confirm") } | ||||||
|  |           ) if show_action? :destroy, resource %></td> | ||||||
|  |         <% end %> | ||||||
|  |       </tr> | ||||||
|  |     <% end %> | ||||||
|  |   </tbody> | ||||||
|  | </table> | ||||||
							
								
								
									
										66
									
								
								app/views/super_admin/users/index.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								app/views/super_admin/users/index.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | <%# | ||||||
|  | # Index | ||||||
|  |  | ||||||
|  | This view is the template for the index page. | ||||||
|  | It is responsible for rendering the search bar, header and pagination. | ||||||
|  | It renders the `_table` partial to display details about the resources. | ||||||
|  |  | ||||||
|  | ## Local variables: | ||||||
|  |  | ||||||
|  | - `page`: | ||||||
|  |   An instance of [Administrate::Page::Collection][1]. | ||||||
|  |   Contains helper methods to help display a table, | ||||||
|  |   and knows which attributes should be displayed in the resource's table. | ||||||
|  | - `resources`: | ||||||
|  |   An instance of `ActiveRecord::Relation` containing the resources | ||||||
|  |   that match the user's search criteria. | ||||||
|  |   By default, these resources are passed to the table partial to be displayed. | ||||||
|  | - `search_term`: | ||||||
|  |   A string containing the term the user has searched for, if any. | ||||||
|  | - `show_search_bar`: | ||||||
|  |   A boolean that determines if the search bar should be shown. | ||||||
|  |  | ||||||
|  | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Collection | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <% content_for(:title) do %> | ||||||
|  |   <%= display_resource_name(page.resource_name) %> | ||||||
|  | <% end %> | ||||||
|  |  | ||||||
|  | <header class="main-content__header" role="banner"> | ||||||
|  |   <h1 class="main-content__page-title" id="page-title"> | ||||||
|  |     <%= content_for(:title) %> | ||||||
|  |   </h1> | ||||||
|  |  | ||||||
|  |   <% if show_search_bar %> | ||||||
|  |     <%= render( | ||||||
|  |       "search", | ||||||
|  |       search_term: search_term, | ||||||
|  |       resource_name: display_resource_name(page.resource_name) | ||||||
|  |     ) %> | ||||||
|  |   <% end %> | ||||||
|  |  | ||||||
|  |   <div> | ||||||
|  |     <%= link_to( | ||||||
|  |       t( | ||||||
|  |         "administrate.actions.new_resource", | ||||||
|  |         name: page.resource_name.titleize.downcase | ||||||
|  |       ), | ||||||
|  |       [:new, namespace, page.resource_path], | ||||||
|  |       class: "button", | ||||||
|  |     ) if valid_action?(:new) && show_action?(:new, new_resource) %> | ||||||
|  |   </div> | ||||||
|  | </header> | ||||||
|  |  | ||||||
|  | <section class="main-content__body main-content__body--flush"> | ||||||
|  |   <%= render( | ||||||
|  |     "collection", | ||||||
|  |     collection_presenter: page, | ||||||
|  |     collection_field_name: resource_name, | ||||||
|  |     page: page, | ||||||
|  |     resources: resources, | ||||||
|  |     table_title: "page-title" | ||||||
|  |   ) %> | ||||||
|  |  | ||||||
|  |   <%= paginate resources %> | ||||||
|  | </section> | ||||||
							
								
								
									
										88
									
								
								app/views/super_admin/users/show.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								app/views/super_admin/users/show.html.erb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | <%# | ||||||
|  | # Show | ||||||
|  |  | ||||||
|  | This view is the template for the show page. | ||||||
|  | It renders the attributes of a resource, | ||||||
|  | as well as a link to its edit page. | ||||||
|  |  | ||||||
|  | ## Local variables: | ||||||
|  |  | ||||||
|  | - `page`: | ||||||
|  |   An instance of [Administrate::Page::Show][1]. | ||||||
|  |   Contains methods for accessing the resource to be displayed on the page, | ||||||
|  |   as well as helpers for describing how each attribute of the resource | ||||||
|  |   should be displayed. | ||||||
|  |  | ||||||
|  | [1]: http://www.rubydoc.info/gems/administrate/Administrate/Page/Show | ||||||
|  | %> | ||||||
|  |  | ||||||
|  | <% content_for(:title) { t("administrate.actions.show_resource", name: page.page_title) } %> | ||||||
|  |  | ||||||
|  | <header class="main-content__header" role="banner"> | ||||||
|  |   <h1 class="main-content__page-title"> | ||||||
|  |     <%= content_for(:title) %> | ||||||
|  |   </h1> | ||||||
|  |  | ||||||
|  |   <div> | ||||||
|  |     <%= link_to( | ||||||
|  |       t("administrate.actions.edit_resource", name: page.page_title), | ||||||
|  |       [:edit, namespace, page.resource], | ||||||
|  |       class: "button", | ||||||
|  |     ) if valid_action?(:edit) && show_action?(:edit, page.resource) %> | ||||||
|  |   </div> | ||||||
|  | </header> | ||||||
|  |  | ||||||
|  | <section class="main-content__body"> | ||||||
|  |   <dl> | ||||||
|  |     <% page.attributes.each do |attribute| %> | ||||||
|  |       <dt class="attribute-label" id="<%= attribute.name %>"> | ||||||
|  |       <%= t( | ||||||
|  |         "helpers.label.#{resource_name}.#{attribute.name}", | ||||||
|  |         default: attribute.name.titleize, | ||||||
|  |       ) %> | ||||||
|  |       </dt> | ||||||
|  |  | ||||||
|  |       <dd class="attribute-data attribute-data--<%=attribute.html_class%>" | ||||||
|  |           ><%= render_field attribute, page: page %></dd> | ||||||
|  |     <% end %> | ||||||
|  |   </dl> | ||||||
|  | </section> | ||||||
|  |  | ||||||
|  | <section class="main-content__body"> | ||||||
|  |   <% account_user_page = Administrate::Page::Form.new(AccountUserDashboard.new, AccountUser.new) %> | ||||||
|  |   <%= form_for([namespace, account_user_page.resource], html: { class: "form" }) do |f| %> | ||||||
|  |   <% if account_user_page.resource.errors.any? %> | ||||||
|  |     <div id="error_explanation"> | ||||||
|  |       <h2> | ||||||
|  |         <%= t( | ||||||
|  |           "administrate.form.errors", | ||||||
|  |           pluralized_errors: pluralize(account_user_page.resource.errors.count, t("administrate.form.error")), | ||||||
|  |           resource_name: display_resource_name(account_user_page.resource_name) | ||||||
|  |         ) %> | ||||||
|  |       </h2> | ||||||
|  |  | ||||||
|  |       <ul> | ||||||
|  |         <% account_user_page.resource.errors.full_messages.each do |message| %> | ||||||
|  |           <li class="flash-error"><%= message %></li> | ||||||
|  |         <% end %> | ||||||
|  |       </ul> | ||||||
|  |     </div> | ||||||
|  |   <% end %> | ||||||
|  |  | ||||||
|  |   <% account_user_page.attributes.each do |attribute| -%> | ||||||
|  |     <% if attribute.name == "user" %> | ||||||
|  |       <%= f.hidden_field('user_id', value: page.resource.id) %> | ||||||
|  |       <%= f.hidden_field('redirect_to', value: 'user') %> | ||||||
|  |     <% else %> | ||||||
|  |     <div class="field-unit field-unit--<%= attribute.html_class %> field-unit--<%= requireness(attribute) %>"> | ||||||
|  |       <%= render_field attribute, f: f %> | ||||||
|  |     </div> | ||||||
|  |     <% end %> | ||||||
|  |   <% end -%> | ||||||
|  |  | ||||||
|  |   <div class="form-actions"> | ||||||
|  |     <%= f.submit %> | ||||||
|  |   </div> | ||||||
|  | <% end %> | ||||||
|  |  | ||||||
|  | </section> | ||||||
| @@ -172,13 +172,13 @@ Rails.application.routes.draw do | |||||||
|   devise_scope :super_admin do |   devise_scope :super_admin do | ||||||
|     get 'super_admin/logout', to: 'super_admin/devise/sessions#destroy' |     get 'super_admin/logout', to: 'super_admin/devise/sessions#destroy' | ||||||
|     namespace :super_admin do |     namespace :super_admin do | ||||||
|       resources :users |  | ||||||
|       resources :accounts |       resources :accounts | ||||||
|       resources :account_users |       resources :account_users, only: [:new, :create, :destroy] | ||||||
|  |       resources :users | ||||||
|       resources :super_admins |       resources :super_admins | ||||||
|       resources :access_tokens |       resources :access_tokens, only: [:index, :show] | ||||||
|  |  | ||||||
|       root to: 'users#index' |       root to: 'dashboard#index' | ||||||
|     end |     end | ||||||
|     authenticated :super_admin do |     authenticated :super_admin do | ||||||
|       mount Sidekiq::Web => '/monitoring/sidekiq' |       mount Sidekiq::Web => '/monitoring/sidekiq' | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ | |||||||
| ActiveRecord::Schema.define(version: 2020_05_22_115645) do | ActiveRecord::Schema.define(version: 2020_05_22_115645) do | ||||||
|  |  | ||||||
|   # These are extensions that must be enabled in order to support this database |   # These are extensions that must be enabled in order to support this database | ||||||
|  |   enable_extension "pg_stat_statements" | ||||||
|   enable_extension "pgcrypto" |   enable_extension "pgcrypto" | ||||||
|   enable_extension "plpgsql" |   enable_extension "plpgsql" | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								public/admin/avatar.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/admin/avatar.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 8.3 KiB | 
| @@ -16,7 +16,6 @@ RSpec.describe 'Super Admin access tokens API', type: :request do | |||||||
|         sign_in super_admin |         sign_in super_admin | ||||||
|         get '/super_admin/access_tokens' |         get '/super_admin/access_tokens' | ||||||
|         expect(response).to have_http_status(:success) |         expect(response).to have_http_status(:success) | ||||||
|         expect(response.body).to include('New access token') |  | ||||||
|         expect(response.body).to include(super_admin.access_token.token) |         expect(response.body).to include(super_admin.access_token.token) | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -3,23 +3,19 @@ require 'rails_helper' | |||||||
| RSpec.describe 'Super Admin Account Users API', type: :request do | RSpec.describe 'Super Admin Account Users API', type: :request do | ||||||
|   let(:super_admin) { create(:super_admin) } |   let(:super_admin) { create(:super_admin) } | ||||||
|  |  | ||||||
|   describe 'GET /super_admin/account_users' do |   describe 'GET /super_admin/account_users/new' do | ||||||
|     context 'when it is an unauthenticated super admin' do |     context 'when it is an unauthenticated super admin' do | ||||||
|       it 'returns unauthorized' do |       it 'returns unauthorized' do | ||||||
|         get '/super_admin/account_users' |         get '/super_admin/account_users/new' | ||||||
|         expect(response).to have_http_status(:redirect) |         expect(response).to have_http_status(:redirect) | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     context 'when it is an authenticated super admin' do |     context 'when it is an authenticated super admin' do | ||||||
|       let!(:account_user) { create(:account_user) } |       it 'shows the account user create page' do | ||||||
|  |  | ||||||
|       it 'shows the list of account users' do |  | ||||||
|         sign_in super_admin |         sign_in super_admin | ||||||
|         get '/super_admin/account_users' |         get '/super_admin/account_users/new' | ||||||
|         expect(response).to have_http_status(:success) |         expect(response).to have_http_status(:success) | ||||||
|         expect(response.body).to include(account_user.account.id.to_s) |  | ||||||
|         expect(response.body).to include(account_user.user.id.to_s) |  | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|   | |||||||
| @@ -15,7 +15,7 @@ RSpec.describe 'Super Admin', type: :request do | |||||||
|         sign_in super_admin |         sign_in super_admin | ||||||
|         get '/super_admin' |         get '/super_admin' | ||||||
|         expect(response).to have_http_status(:success) |         expect(response).to have_http_status(:success) | ||||||
|         expect(response.body).to include('New user') |         expect(response.body).to include('Dashboard') | ||||||
|  |  | ||||||
|         sign_out super_admin |         sign_out super_admin | ||||||
|         get '/super_admin' |         get '/super_admin' | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Sojan Jose
					Sojan Jose