init dev-project
This commit is contained in:
commit
77f6bb2061
40
.env
Normal file
40
.env
Normal file
@ -0,0 +1,40 @@
|
||||
# In all environments, the following files are loaded if they exist,
|
||||
# the latter taking precedence over the former:
|
||||
#
|
||||
# * .env contains default values for the environment variables needed by the app
|
||||
# * .env.local uncommitted file with local overrides
|
||||
# * .env.$APP_ENV committed environment-specific defaults
|
||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
||||
#
|
||||
# Real environment variables win over .env files.
|
||||
#
|
||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
||||
# https://symfony.com/doc/current/configuration/secrets.html
|
||||
#
|
||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
APP_ENV=dev
|
||||
APP_SECRET=ab892a986d68cc476c3bcca606175c22
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> doctrine/doctrine-bundle ###
|
||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
||||
#
|
||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
|
||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8&charset=utf8mb4"
|
||||
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
###> symfony/messenger ###
|
||||
# Choose one of the transports below
|
||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
||||
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
||||
###< symfony/messenger ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
# MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
6
.env.test
Normal file
6
.env.test
Normal file
@ -0,0 +1,6 @@
|
||||
# define your env variables for the test env here
|
||||
KERNEL_CLASS='App\Kernel'
|
||||
APP_SECRET='$ecretf0rt3st'
|
||||
SYMFONY_DEPRECATIONS_HELPER=999999
|
||||
PANTHER_APP_ENV=panther
|
||||
PANTHER_ERROR_SCREENSHOT_DIR=./var/error-screenshots
|
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
###> symfony/framework-bundle ###
|
||||
/config/secrets/prod/prod.decrypt.private.php
|
||||
/public/bundles/
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
### php-storm
|
||||
.idea
|
||||
/.idea
|
||||
|
||||
###> phpunit/phpunit ###
|
||||
/phpunit.xml
|
||||
.phpunit.result.cache
|
||||
###< phpunit/phpunit ###
|
||||
/.idea
|
||||
.idea
|
||||
|
||||
###> symfony/phpunit-bridge ###
|
||||
.phpunit.result.cache
|
||||
/phpunit.xml
|
||||
###< symfony/phpunit-bridge ###
|
||||
###> liip/imagine-bundle ###
|
||||
/public/media/cache/
|
||||
###< liip/imagine-bundle ###
|
||||
=======
|
||||
|
||||
###> symfony/webpack-encore-bundle ###
|
||||
/node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
###< symfony/webpack-encore-bundle ###
|
||||
.env.local
|
||||
bin/5s-export
|
8
assets/app.js
Normal file
8
assets/app.js
Normal file
@ -0,0 +1,8 @@
|
||||
import {registerReactControllerComponents} from '@symfony/ux-react';
|
||||
registerReactControllerComponents(require.context('./react/controllers', true, /\.(j|t)sx?$/));
|
||||
|
||||
import './styles/app.scss';
|
||||
|
||||
import * as bootstrap from 'bootstrap';
|
||||
|
||||
import './bootstrap'
|
7
assets/bootstrap.js
vendored
Normal file
7
assets/bootstrap.js
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { startStimulusApp } from '@symfony/stimulus-bridge';
|
||||
|
||||
export const app = startStimulusApp(require.context(
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.(j|t)sx?$/
|
||||
));
|
17
assets/controllers.json
Normal file
17
assets/controllers.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"controllers": {
|
||||
"@symfony/ux-chartjs": {
|
||||
"chart": {
|
||||
"enabled": true,
|
||||
"fetch": "eager"
|
||||
}
|
||||
},
|
||||
"@symfony/ux-react": {
|
||||
"react": {
|
||||
"enabled": true,
|
||||
"fetch": "eager"
|
||||
}
|
||||
}
|
||||
},
|
||||
"entrypoints": []
|
||||
}
|
16
assets/controllers/hello_controller.js
Normal file
16
assets/controllers/hello_controller.js
Normal file
@ -0,0 +1,16 @@
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
/*
|
||||
* This is an example Stimulus controller!
|
||||
*
|
||||
* Any element with a data-controller="hello" attribute will cause
|
||||
* this controller to be executed. The name "hello" comes from the filename:
|
||||
* hello_controller.js -> "hello"
|
||||
*
|
||||
* Delete this file or adapt it for your use!
|
||||
*/
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
this.element.textContent = 'Hello Stimulus! Edit me in assets/controllers/hello_controller.js';
|
||||
}
|
||||
}
|
52
assets/startbootstrap-sb-admin-2/scss/_buttons.scss
Normal file
52
assets/startbootstrap-sb-admin-2/scss/_buttons.scss
Normal file
@ -0,0 +1,52 @@
|
||||
.btn-circle {
|
||||
border-radius: 100%;
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
font-size: 1rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
&.btn-sm {
|
||||
height: 1.8rem;
|
||||
width: 1.8rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
&.btn-lg {
|
||||
height: 3.5rem;
|
||||
width: 3.5rem;
|
||||
font-size: 1.35rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-icon-split {
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
display: inline-flex;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
.icon {
|
||||
background: fade-out($black, .85);
|
||||
display: inline-block;
|
||||
padding: $btn-padding-y $btn-padding-x;
|
||||
}
|
||||
.text {
|
||||
display: inline-block;
|
||||
padding: $btn-padding-y $btn-padding-x;
|
||||
}
|
||||
&.btn-sm {
|
||||
.icon {
|
||||
padding: $btn-padding-y-sm $btn-padding-x-sm;
|
||||
}
|
||||
.text {
|
||||
padding: $btn-padding-y-sm $btn-padding-x-sm;
|
||||
}
|
||||
}
|
||||
&.btn-lg {
|
||||
.icon {
|
||||
padding: $btn-padding-y-lg $btn-padding-x-lg;
|
||||
}
|
||||
.text {
|
||||
padding: $btn-padding-y-lg $btn-padding-x-lg;
|
||||
}
|
||||
}
|
||||
}
|
36
assets/startbootstrap-sb-admin-2/scss/_cards.scss
Normal file
36
assets/startbootstrap-sb-admin-2/scss/_cards.scss
Normal file
@ -0,0 +1,36 @@
|
||||
// Custom Card Styling
|
||||
|
||||
.card {
|
||||
.card-header {
|
||||
// Format Dropdowns in Card Headings
|
||||
.dropdown {
|
||||
line-height: 1;
|
||||
.dropdown-menu {
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Collapsable Card Styling
|
||||
.card-header[data-toggle="collapse"] {
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
padding: 0.75rem 3.25rem 0.75rem 1.25rem;
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
padding-right: 1.725rem;
|
||||
line-height: 51px;
|
||||
font-weight: 900;
|
||||
content: '\f107';
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
color: $gray-400;
|
||||
}
|
||||
&.collapsed {
|
||||
border-radius: $card-border-radius;
|
||||
&::after {
|
||||
content: '\f105';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
assets/startbootstrap-sb-admin-2/scss/_charts.scss
Normal file
29
assets/startbootstrap-sb-admin-2/scss/_charts.scss
Normal file
@ -0,0 +1,29 @@
|
||||
// Area Chart
|
||||
.chart-area {
|
||||
position: relative;
|
||||
height: 10rem;
|
||||
width: 100%;
|
||||
@include media-breakpoint-up(md) {
|
||||
height: 20rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Bar Chart
|
||||
.chart-bar {
|
||||
position: relative;
|
||||
height: 10rem;
|
||||
width: 100%;
|
||||
@include media-breakpoint-up(md) {
|
||||
height: 20rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Pie Chart
|
||||
.chart-pie {
|
||||
position: relative;
|
||||
height: 15rem;
|
||||
width: 100%;
|
||||
@include media-breakpoint-up(md) {
|
||||
height: calc(20rem - 43px) !important;
|
||||
}
|
||||
}
|
21
assets/startbootstrap-sb-admin-2/scss/_dropdowns.scss
Normal file
21
assets/startbootstrap-sb-admin-2/scss/_dropdowns.scss
Normal file
@ -0,0 +1,21 @@
|
||||
// Custom Dropdown Styling
|
||||
|
||||
.dropdown {
|
||||
.dropdown-menu {
|
||||
font-size: $dropdown-font-size;
|
||||
.dropdown-header {
|
||||
@extend .text-uppercase;
|
||||
font-weight: 800;
|
||||
font-size: 0.65rem;
|
||||
color: $gray-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Utility class to hide arrow from dropdown
|
||||
|
||||
.dropdown.no-arrow {
|
||||
.dropdown-toggle::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
53
assets/startbootstrap-sb-admin-2/scss/_error.scss
Normal file
53
assets/startbootstrap-sb-admin-2/scss/_error.scss
Normal file
@ -0,0 +1,53 @@
|
||||
@use "sass:math";
|
||||
// Lucas Bebber's Glitch Effect
|
||||
// Tutorial and CSS from CSS Tricks
|
||||
// https://css-tricks.com/glitch-effect-text-images-svg/
|
||||
|
||||
.error {
|
||||
color: $gray-800;
|
||||
font-size: 7rem;
|
||||
position: relative;
|
||||
line-height: 1;
|
||||
width: 12.5rem;
|
||||
}
|
||||
@keyframes noise-anim {
|
||||
$steps: 20;
|
||||
@for $i from 0 through $steps {
|
||||
#{percentage($i*math.div(1, $steps))} {
|
||||
clip: rect(random(100)+px,9999px,random(100)+px,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
.error:after {
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
text-shadow: -1px 0 $red;
|
||||
top: 0;
|
||||
color: $gray-800;
|
||||
background: $gray-100;
|
||||
overflow: hidden;
|
||||
clip: rect(0,900px,0,0);
|
||||
animation: noise-anim 2s infinite linear alternate-reverse;
|
||||
}
|
||||
|
||||
@keyframes noise-anim-2 {
|
||||
$steps: 20;
|
||||
@for $i from 0 through $steps {
|
||||
#{percentage($i*math.div(1, $steps))} {
|
||||
clip: rect(random(100)+px,9999px,random(100)+px,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
.error:before {
|
||||
content: attr(data-text);
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
text-shadow: 1px 0 $blue;
|
||||
top: 0;
|
||||
color: $gray-800;
|
||||
background: $gray-100;
|
||||
overflow: hidden;
|
||||
clip: rect(0,900px,0,0);
|
||||
animation: noise-anim-2 3s infinite linear alternate-reverse;
|
||||
}
|
14
assets/startbootstrap-sb-admin-2/scss/_footer.scss
Normal file
14
assets/startbootstrap-sb-admin-2/scss/_footer.scss
Normal file
@ -0,0 +1,14 @@
|
||||
footer.sticky-footer {
|
||||
padding: 2rem 0;
|
||||
flex-shrink: 0;
|
||||
.copyright {
|
||||
line-height: 1;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
body.sidebar-toggled {
|
||||
footer.sticky-footer {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
287
assets/startbootstrap-sb-admin-2/scss/_global.scss
Normal file
287
assets/startbootstrap-sb-admin-2/scss/_global.scss
Normal file
@ -0,0 +1,287 @@
|
||||
// Global component styles
|
||||
|
||||
html {
|
||||
position: relative;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.homeBlock i{
|
||||
font-size: 100px;
|
||||
color: #3F9464;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.homeBlock i:hover{
|
||||
opacity: 1;
|
||||
font-size: 110px;
|
||||
}
|
||||
|
||||
.homeBlock span{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.showWhenDone {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row.ip.deleted {
|
||||
background-color: rgba(234, 14, 14, 0.35);
|
||||
}
|
||||
|
||||
.row.ip.whitelisted {
|
||||
background-color: rgba(63, 191, 63, 0.35);
|
||||
}
|
||||
|
||||
.queueRow.whitelisted {
|
||||
background-color: rgba(63, 191, 63, 0.35);
|
||||
}
|
||||
|
||||
.whitelisted{
|
||||
background-color: rgba(63, 191, 63, 0.35);
|
||||
}
|
||||
|
||||
/** FourbisButton **/
|
||||
.fourbisButton {
|
||||
width: 100%;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
background-color: #4CB078;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.fourbisButton:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fourbisButton:disabled {
|
||||
background-image: linear-gradient(45deg, #4cb078 15%, #58d18e 15%, #58d18e 50%, #4cb078 50%, #4cb078 65%, #58d18e 65%, #58d18e 100%);
|
||||
background-size: 28.28px 28.28px;
|
||||
}
|
||||
|
||||
.fourbisButton:disabled:hover {
|
||||
opacity: 0.5;
|
||||
background-image: linear-gradient(45deg, #4cb078 15%, #58d18e 15%, #58d18e 50%, #4cb078 50%, #4cb078 65%, #58d18e 65%, #58d18e 100%);
|
||||
background-size: 28.28px 28.28px;
|
||||
}
|
||||
|
||||
/** FourbisButtonDanger **/
|
||||
.fourbisButtonDanger {
|
||||
width: 100%;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
background-color: #ff0000;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.fourbisButtonDanger:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fourbisButtonDanger:disabled {
|
||||
background-image: linear-gradient(45deg, #ff0000 15%, #c20808 15%, #c20808 50%, #ff0000 50%, #ff0000 65%, #c20808 65%, #c20808 100%);
|
||||
background-size: 28.28px 28.28px;
|
||||
}
|
||||
|
||||
.fourbisButtonDanger:disabled:hover {
|
||||
opacity: 0.5;
|
||||
background-image: linear-gradient(45deg, #ff0000 15%, #c20808 15%, #c20808 50%, #ff0000 50%, #ff0000 65%, #c20808 65%, #c20808 100%);
|
||||
background-size: 28.28px 28.28px;
|
||||
}
|
||||
|
||||
/** FourbisButtonRefresh **/
|
||||
.fourbisButtonRefresh {
|
||||
width: 100%;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
background-color: #0094C7;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.fourbisButtonRefresh:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.fourbisButtonRefresh:disabled {
|
||||
background-image: linear-gradient(45deg, #0094c7 25%, #007ba8 25%, #007ba8 50%, #0094c7 50%, #0094c7 75%, #007ba8 75%, #007ba8 100%);
|
||||
background-size: 28.28px 28.28px;
|
||||
}
|
||||
|
||||
.fourbisButtonRefresh:disabled:hover {
|
||||
opacity: 0.5;
|
||||
background-image: linear-gradient(45deg, #0094c7 25%, #007ba8 25%, #007ba8 50%, #0094c7 50%, #0094c7 75%, #007ba8 75%, #007ba8 100%);
|
||||
background-size: 28.28px 28.28px;
|
||||
}
|
||||
|
||||
.portalTitle {
|
||||
color: $primary;
|
||||
font-size: xx-large;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.loadingDiv {
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
height: 70px;
|
||||
background-color: #8fd8ad;
|
||||
border-left: 2px solid #4CB07A;
|
||||
border-right: 2px solid #4CB078;
|
||||
}
|
||||
|
||||
.fourbisContainer {
|
||||
border: 2px solid #4CB078;
|
||||
background-color: white;
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.ContentBlock {
|
||||
display: inline-block;
|
||||
border: 1px solid black;
|
||||
text-align: center;
|
||||
background-color: #4CB078;
|
||||
height: 300px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.ContentBlock:hover {
|
||||
transform: scale(1.1);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ContentBlock h3 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#fail2banDashboard {
|
||||
padding-left: 17px;
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
#loading {
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/** LOADER **/
|
||||
.lds-ellipsis {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.lds-ellipsis div {
|
||||
position: absolute;
|
||||
top: 33px;
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
border-radius: 50%;
|
||||
background: #419766;
|
||||
animation-timing-function: cubic-bezier(0, 1, 1, 0);
|
||||
}
|
||||
|
||||
.lds-ellipsis div:nth-child(1) {
|
||||
left: 8px;
|
||||
animation: lds-ellipsis1 0.6s infinite;
|
||||
}
|
||||
|
||||
.lds-ellipsis div:nth-child(2) {
|
||||
left: 8px;
|
||||
animation: lds-ellipsis2 0.6s infinite;
|
||||
}
|
||||
|
||||
.lds-ellipsis div:nth-child(3) {
|
||||
left: 32px;
|
||||
animation: lds-ellipsis2 0.6s infinite;
|
||||
}
|
||||
|
||||
.lds-ellipsis div:nth-child(4) {
|
||||
left: 56px;
|
||||
animation: lds-ellipsis3 0.6s infinite;
|
||||
}
|
||||
|
||||
@keyframes lds-ellipsis1 {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lds-ellipsis3 {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
transform: scale(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lds-ellipsis2 {
|
||||
0% {
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
100% {
|
||||
transform: translate(24px, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Main page wrapper
|
||||
#wrapper {
|
||||
display: flex;
|
||||
|
||||
#content-wrapper {
|
||||
background-color: #E5E5E5;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
|
||||
#content {
|
||||
flex: 1 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set container padding to match gutter width instead of default 15px
|
||||
.container,
|
||||
.container-fluid {
|
||||
padding-left: $grid-gutter-width;
|
||||
padding-right: $grid-gutter-width;
|
||||
}
|
||||
|
||||
// Scroll to top button
|
||||
.scroll-to-top {
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
bottom: 1rem;
|
||||
display: none;
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
text-align: center;
|
||||
color: $white;
|
||||
background: fade-out($gray-800, .5);
|
||||
line-height: 46px;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $gray-800;
|
||||
}
|
||||
|
||||
i {
|
||||
font-weight: 800;
|
||||
}
|
||||
}
|
51
assets/startbootstrap-sb-admin-2/scss/_login.scss
Normal file
51
assets/startbootstrap-sb-admin-2/scss/_login.scss
Normal file
@ -0,0 +1,51 @@
|
||||
// Pulling these images from Unsplash
|
||||
// Toshi the dog from https://unsplash.com/@charlesdeluvio - what a funny dog...
|
||||
|
||||
.bg-login-image {
|
||||
background: url("/assets/images/login-image.jpg");
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
//transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.bg-register-image {
|
||||
background: url('https://source.unsplash.com/Mv9hjnEUHR4/600x800');
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-password-image {
|
||||
background: url('https://source.unsplash.com/oWTW-jNGl9I/600x800');
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
form.user {
|
||||
|
||||
.custom-checkbox.small {
|
||||
label {
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-control-user {
|
||||
font-size: 0.8rem;
|
||||
border-radius: 10rem;
|
||||
padding: 1.5rem 1rem;
|
||||
}
|
||||
|
||||
.btn-user {
|
||||
font-size: 0.8rem;
|
||||
border-radius: 10rem;
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.btn-google {
|
||||
@include button-variant($brand-google, $white);
|
||||
}
|
||||
|
||||
.btn-facebook {
|
||||
@include button-variant($brand-facebook, $white);
|
||||
}
|
1
assets/startbootstrap-sb-admin-2/scss/_mixins.scss
Normal file
1
assets/startbootstrap-sb-admin-2/scss/_mixins.scss
Normal file
@ -0,0 +1 @@
|
||||
|
3
assets/startbootstrap-sb-admin-2/scss/_navs.scss
Normal file
3
assets/startbootstrap-sb-admin-2/scss/_navs.scss
Normal file
@ -0,0 +1,3 @@
|
||||
@import "navs/global.scss";
|
||||
@import "navs/topbar.scss";
|
||||
@import "navs/sidebar.scss";
|
7
assets/startbootstrap-sb-admin-2/scss/_utilities.scss
Normal file
7
assets/startbootstrap-sb-admin-2/scss/_utilities.scss
Normal file
@ -0,0 +1,7 @@
|
||||
@import "utilities/animation.scss";
|
||||
@import "utilities/background.scss";
|
||||
@import "utilities/display.scss";
|
||||
@import "utilities/text.scss";
|
||||
@import "utilities/border.scss";
|
||||
@import "utilities/progress.scss";
|
||||
@import "utilities/rotate.scss";
|
76
assets/startbootstrap-sb-admin-2/scss/_variables.scss
Normal file
76
assets/startbootstrap-sb-admin-2/scss/_variables.scss
Normal file
@ -0,0 +1,76 @@
|
||||
// Override Bootstrap default variables here
|
||||
// Do not edit any of the files in /vendor/bootstrap/scss/!
|
||||
|
||||
// Color Variables
|
||||
// Bootstrap Color Overrides
|
||||
|
||||
$white: #fff !default;
|
||||
$gray-100: #d9d9d9 !default;
|
||||
$gray-200: #eaecf4 !default;
|
||||
$gray-300: #dddfeb !default;
|
||||
$gray-400: #d1d3e2 !default;
|
||||
$gray-500: #b7b9cc !default;
|
||||
$gray-600: #858796 !default;
|
||||
$gray-700: #6e707e !default;
|
||||
$gray-800: #5a5c69 !default;
|
||||
$gray-900: #3a3b45 !default;
|
||||
$black: #000 !default;
|
||||
|
||||
$blue: #4e73df !default;
|
||||
$indigo: #6610f2 !default;
|
||||
$purple: #6f42c1 !default;
|
||||
$pink: #e83e8c !default;
|
||||
$red: #e74a3b !default;
|
||||
$orange: #fd7e14 !default;
|
||||
$yellow: #f6c23e !default;
|
||||
$green: #1cc88a !default;
|
||||
$teal: #20c9a6 !default;
|
||||
$cyan: #36b9cc !default;
|
||||
|
||||
// Custom Colors
|
||||
$brand-google: #ea4335;
|
||||
$brand-facebook: #3b5998;
|
||||
|
||||
// Set Contrast Threshold
|
||||
$yiq-contrasted-threshold: 195 !default;
|
||||
|
||||
// Typography
|
||||
$body-color: $gray-600 !default;
|
||||
|
||||
$font-family-sans-serif: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", 'Noto Color Emoji' !default;
|
||||
|
||||
$font-weight-light: 300 !default;
|
||||
// $font-weight-base: 400;
|
||||
$headings-font-weight: 400 !default;
|
||||
|
||||
// Shadows
|
||||
$box-shadow-sm: 0 0.125rem 0.25rem 0 rgba($gray-900, .2) !default;
|
||||
$box-shadow: 0 0.15rem 1.75rem 0 rgba($gray-900, .15) !default;
|
||||
// $box-shadow-lg: 0 1rem 3rem rgba($black, .175) !default;
|
||||
|
||||
// Borders Radius
|
||||
$border-radius: 0.35rem !default;
|
||||
$border-color: darken($gray-200, 2%);
|
||||
|
||||
// Spacing Variables
|
||||
// Change below variable if the height of the navbar changes
|
||||
$topbar-base-height: 50px;
|
||||
// Change below variable to change the width of the sidenav
|
||||
$sidebar-base-width: 14rem;
|
||||
// Change below variable to change the width of the sidenav when collapsed
|
||||
$sidebar-collapsed-width: 6.5rem;
|
||||
|
||||
// Card
|
||||
$card-cap-bg: $gray-100;
|
||||
$card-border-color: $border-color;
|
||||
|
||||
// Adjust column spacing for symmetry
|
||||
$spacer: 1rem;
|
||||
$grid-gutter-width: $spacer * 1.5;
|
||||
|
||||
// Transitions
|
||||
$transition-collapse: height .15s ease !default;
|
||||
|
||||
// Dropdowns
|
||||
$dropdown-font-size: 0.85rem;
|
||||
$dropdown-border-color: $border-color;
|
41
assets/startbootstrap-sb-admin-2/scss/navs/_global.scss
Normal file
41
assets/startbootstrap-sb-admin-2/scss/navs/_global.scss
Normal file
@ -0,0 +1,41 @@
|
||||
// Global styles for both custom sidebar and topbar compoments
|
||||
|
||||
.sidebar,
|
||||
.topbar {
|
||||
.nav-item {
|
||||
// Customize Dropdown Arrows for Navbar
|
||||
&.dropdown {
|
||||
.dropdown-toggle {
|
||||
&::after {
|
||||
width: 1rem;
|
||||
text-align: center;
|
||||
float: right;
|
||||
vertical-align: 0;
|
||||
border: 0;
|
||||
font-weight: 900;
|
||||
content: '\f105';
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
}
|
||||
}
|
||||
&.show {
|
||||
.dropdown-toggle::after {
|
||||
content: '\f107';
|
||||
}
|
||||
}
|
||||
}
|
||||
// Counter for nav links and nav link image sizing
|
||||
.nav-link {
|
||||
position: relative;
|
||||
.badge-counter {
|
||||
position: absolute;
|
||||
transform: scale(0.7);
|
||||
transform-origin: top right;
|
||||
right: .25rem;
|
||||
margin-top: -.25rem;
|
||||
}
|
||||
.img-profile {
|
||||
width: 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
459
assets/startbootstrap-sb-admin-2/scss/navs/_sidebar.scss
Normal file
459
assets/startbootstrap-sb-admin-2/scss/navs/_sidebar.scss
Normal file
@ -0,0 +1,459 @@
|
||||
// Sidebar
|
||||
.sidebar {
|
||||
width: $sidebar-collapsed-width;
|
||||
min-height: 100%;
|
||||
|
||||
ul li::marker{
|
||||
display: none;
|
||||
content: '';
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
position: relative;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
text-align: center;
|
||||
padding-left: 0.75rem;
|
||||
width: $sidebar-collapsed-width;
|
||||
|
||||
span {
|
||||
font-size: 0.65rem;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
&>.nav-link {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
// Accordion
|
||||
.collapse {
|
||||
position: absolute;
|
||||
left: calc(#{$sidebar-collapsed-width} + #{$grid-gutter-width} / 2);
|
||||
z-index: 1;
|
||||
top: 2px;
|
||||
// Grow In Animation
|
||||
@extend .animated--grow-in;
|
||||
|
||||
.collapse-inner {
|
||||
border-radius: $border-radius;
|
||||
box-shadow: $box-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
.collapsing {
|
||||
display: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.collapse,
|
||||
.collapsing {
|
||||
.collapse-inner {
|
||||
padding: .5rem 0;
|
||||
min-width: 10rem;
|
||||
font-size: $dropdown-font-size;
|
||||
margin: 0 0 1rem 0;
|
||||
|
||||
.collapse-header {
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
padding: .5rem 1.5rem;
|
||||
text-transform: uppercase;
|
||||
font-weight: 800;
|
||||
font-size: 0.65rem;
|
||||
color: $gray-500;
|
||||
}
|
||||
|
||||
.collapse-item {
|
||||
padding: 0.5rem 1rem;
|
||||
margin: 0 0.5rem;
|
||||
display: block;
|
||||
color: $gray-900;
|
||||
text-decoration: none;
|
||||
border-radius: $border-radius;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
background-color: $gray-200;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: $gray-300;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $primary;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#sidebarToggle {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
text-align: center;
|
||||
margin-bottom: 1rem;
|
||||
cursor: pointer;
|
||||
|
||||
&::after {
|
||||
font-weight: 900;
|
||||
content: '\f104';
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
width: 0 !important;
|
||||
overflow: hidden;
|
||||
|
||||
#sidebarToggle::after {
|
||||
content: '\f105';
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-brand {
|
||||
height: $topbar-base-height;
|
||||
text-decoration: none;
|
||||
font-size: 1rem;
|
||||
font-weight: 800;
|
||||
padding: 1.5rem 1rem;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05rem;
|
||||
z-index: 1;
|
||||
background-color: $secondary;
|
||||
|
||||
.sidebar-brand-icon i {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.sidebar-brand-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
hr.sidebar-divider {
|
||||
margin: 0 1rem 1rem;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
text-align: center;
|
||||
padding: 0 1rem;
|
||||
font-weight: 800;
|
||||
font-size: 0.65rem;
|
||||
@extend .text-uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
.sidebar {
|
||||
width: $sidebar-base-width !important;
|
||||
|
||||
.nav-item {
|
||||
// Accordion
|
||||
.collapse {
|
||||
position: relative;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
animation: none;
|
||||
|
||||
.collapse-inner {
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.sidebar-divider {
|
||||
display: block;
|
||||
margin: 0.5rem 1rem !important;
|
||||
border-top: 1px solid #1919194f !important;
|
||||
}
|
||||
}
|
||||
|
||||
.collapsing {
|
||||
display: block;
|
||||
transition: $transition-collapse;
|
||||
}
|
||||
|
||||
.collapse,
|
||||
.collapsing {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
display: block;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
//padding: 1rem;
|
||||
width: $sidebar-base-width;
|
||||
|
||||
i {
|
||||
font-size: 0.85rem;
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 0.85rem;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
// Accordion Arrow Icon
|
||||
&[data-toggle="collapse"] {
|
||||
&::after {
|
||||
width: 1rem;
|
||||
text-align: center;
|
||||
float: right;
|
||||
vertical-align: 0;
|
||||
border: 0;
|
||||
font-weight: 900;
|
||||
content: '\f107';
|
||||
font-family: 'Font Awesome 5 Free';
|
||||
}
|
||||
|
||||
&.collapsed::after {
|
||||
content: '\f105';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-brand {
|
||||
.sidebar-brand-icon i {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.sidebar-brand-text {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
overflow: visible;
|
||||
width: $sidebar-collapsed-width !important;
|
||||
|
||||
.nav-item {
|
||||
// Accordion
|
||||
.collapse {
|
||||
position: absolute;
|
||||
left: calc(#{$sidebar-collapsed-width} + #{$grid-gutter-width} / 2);
|
||||
z-index: 1;
|
||||
top: 2px;
|
||||
// Grow In Animation for Toggled State
|
||||
animation-name: growIn;
|
||||
animation-duration: 200ms;
|
||||
animation-timing-function: transform cubic-bezier(.18, 1.25, .4, 1), opacity cubic-bezier(0, 1, .4, 1);
|
||||
|
||||
.collapse-inner {
|
||||
box-shadow: $box-shadow;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
||||
|
||||
.collapsing {
|
||||
display: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.collapse,
|
||||
.collapsing {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
text-align: center;
|
||||
padding: 0.75rem 1rem;
|
||||
width: $sidebar-collapsed-width;
|
||||
|
||||
span {
|
||||
font-size: 0.65rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
i {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&[data-toggle="collapse"]::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-brand {
|
||||
.sidebar-brand-icon i {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.sidebar-brand-text {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sidebar Color Variants
|
||||
|
||||
// Sidebar Light
|
||||
.sidebar-light {
|
||||
.sidebar-brand {
|
||||
color: $gray-700;
|
||||
}
|
||||
|
||||
hr.sidebar-divider {
|
||||
border-top: 1px solid $gray-200;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
color: $gray-500;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
.nav-link {
|
||||
color: black;
|
||||
|
||||
i {
|
||||
color: $gray-400;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $gray-700;
|
||||
|
||||
i {
|
||||
color: black;
|
||||
}
|
||||
}
|
||||
|
||||
// Accordion
|
||||
&[data-toggle="collapse"]::after {
|
||||
color: $gray-500;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
&>.nav-link {
|
||||
color: $primary;
|
||||
|
||||
i {
|
||||
color: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Color the sidebar toggler
|
||||
#sidebarToggle {
|
||||
background-color: $gray-200;
|
||||
|
||||
&::after {
|
||||
color: $gray-500;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $gray-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sidebar Dark
|
||||
.sidebar-dark {
|
||||
.sidebar-brand {
|
||||
color: $white;
|
||||
}
|
||||
|
||||
hr.sidebar-divider {
|
||||
border-top: 1px solid fade-out($white, 0.85);
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
color: fade-out($white, 0.6);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
.nav-link {
|
||||
color: fade-out($white, 0.2);
|
||||
|
||||
i {
|
||||
color: fade-out($white, 0.7);
|
||||
}
|
||||
|
||||
&:active,
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: $white;
|
||||
|
||||
i {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
// Accordion
|
||||
&[data-toggle="collapse"]::after {
|
||||
color: fade-out($white, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
&>.active {
|
||||
.nav-link {
|
||||
color: $white;
|
||||
|
||||
i {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Color the sidebar toggler
|
||||
#sidebarToggle {
|
||||
background-color: fade-out($white, 0.8);
|
||||
|
||||
&::after {
|
||||
color: fade-out($white, 0.5);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: fade-out($white, 0.75);
|
||||
}
|
||||
}
|
||||
|
||||
&.toggled {
|
||||
#sidebarToggle::after {
|
||||
color: fade-out($white, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
130
assets/startbootstrap-sb-admin-2/scss/navs/_topbar.scss
Normal file
130
assets/startbootstrap-sb-admin-2/scss/navs/_topbar.scss
Normal file
@ -0,0 +1,130 @@
|
||||
@use "sass:math";
|
||||
// Topbar
|
||||
.topbar {
|
||||
height: $topbar-base-height;
|
||||
#sidebarToggleTop {
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
&:hover {
|
||||
background-color: $gray-200;
|
||||
}
|
||||
&:active {
|
||||
background-color: $gray-300;
|
||||
}
|
||||
}
|
||||
.navbar-search {
|
||||
width: 25rem;
|
||||
input {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
.topbar-divider {
|
||||
width: 0;
|
||||
border-right: 1px solid $border-color;
|
||||
height: calc(#{$topbar-base-height} - 2rem);
|
||||
margin: auto 1rem;
|
||||
}
|
||||
.nav-item {
|
||||
.nav-link {
|
||||
height: $topbar-base-height;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 0.75rem;
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
.dropdown {
|
||||
position: static;
|
||||
.dropdown-menu {
|
||||
width: calc(100% - #{$grid-gutter-width});
|
||||
right: math.div($grid-gutter-width, 2);
|
||||
}
|
||||
}
|
||||
.dropdown-list {
|
||||
padding: 0;
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
.dropdown-header {
|
||||
background-color: $primary;
|
||||
border: 1px solid $primary;
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
color: $white;
|
||||
}
|
||||
.dropdown-item {
|
||||
white-space: normal;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-left: 1px solid $border-color;
|
||||
border-right: 1px solid $border-color;
|
||||
border-bottom: 1px solid $border-color;
|
||||
line-height: 1.3rem;
|
||||
.dropdown-list-image {
|
||||
position: relative;
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
img {
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
}
|
||||
.status-indicator {
|
||||
background-color: $gray-200;
|
||||
height: 0.75rem;
|
||||
width: 0.75rem;
|
||||
border-radius: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
border: .125rem solid $white;
|
||||
}
|
||||
}
|
||||
.text-truncate {
|
||||
max-width: 10rem;
|
||||
}
|
||||
&:active {
|
||||
background-color: $gray-200;
|
||||
color: $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
@include media-breakpoint-up(sm) {
|
||||
.dropdown {
|
||||
position: relative;
|
||||
.dropdown-menu {
|
||||
width: auto;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
.dropdown-list {
|
||||
width: 20rem !important;
|
||||
.dropdown-item {
|
||||
.text-truncate {
|
||||
max-width: 13.375rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topbar.navbar-dark {}
|
||||
|
||||
.topbar.navbar-light {
|
||||
.navbar-nav {
|
||||
.nav-item {
|
||||
.nav-link {
|
||||
color: $gray-400;
|
||||
&:hover {
|
||||
color: $gray-500;
|
||||
}
|
||||
&:active {
|
||||
color: $gray-600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
assets/startbootstrap-sb-admin-2/scss/sb-admin-2.scss
Normal file
20
assets/startbootstrap-sb-admin-2/scss/sb-admin-2.scss
Normal file
@ -0,0 +1,20 @@
|
||||
// Import Custom SB Admin 2 Variables (Overrides Default Bootstrap Variables)
|
||||
@import "variables.scss";
|
||||
|
||||
// Import Bootstrap
|
||||
// @import "../vendor/bootstrap/scss/bootstrap.scss";
|
||||
|
||||
// Import Custom SB Admin 2 Mixins and Components
|
||||
@import "mixins.scss";
|
||||
@import "global.scss";
|
||||
@import "utilities.scss";
|
||||
|
||||
// Custom Components
|
||||
@import "dropdowns.scss";
|
||||
@import "navs.scss";
|
||||
@import "buttons.scss";
|
||||
@import "cards.scss";
|
||||
@import "charts.scss";
|
||||
@import "login.scss";
|
||||
@import "error.scss";
|
||||
@import "footer.scss";
|
@ -0,0 +1,37 @@
|
||||
// Animation Utilities
|
||||
|
||||
// Grow In Animation
|
||||
|
||||
@keyframes growIn {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.animated--grow-in {
|
||||
animation-name: growIn;
|
||||
animation-duration: 200ms;
|
||||
animation-timing-function: transform cubic-bezier(.18,1.25,.4,1), opacity cubic-bezier(0,1,.4,1);
|
||||
}
|
||||
|
||||
// Fade In Animation
|
||||
|
||||
@keyframes fadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.animated--fade-in {
|
||||
animation-name: fadeIn;
|
||||
animation-duration: 200ms;
|
||||
animation-timing-function: opacity cubic-bezier(0,1,.4,1);
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
// Background Gradient Utilities
|
||||
|
||||
.bg-gradient-front {
|
||||
background-color: $primary;
|
||||
background-image: linear-gradient(180deg, $primary 10%, $secondary 100%);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-gradient-primary {
|
||||
background-color: $primary;
|
||||
background-image: linear-gradient(180deg, $primary 10%, darken($primary, 15%) 100%);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-gradient-success {
|
||||
background-color: $success;
|
||||
background-image: linear-gradient(180deg, $success 10%, darken($success, 15%) 100%);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-gradient-info {
|
||||
background-color: $info;
|
||||
background-image: linear-gradient(180deg, $info 10%, darken($info, 15%) 100%);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-gradient-warning {
|
||||
background-color: $warning;
|
||||
background-image: linear-gradient(180deg, $warning 10%, darken($warning, 15%) 100%);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-gradient-danger {
|
||||
background-color: $danger;
|
||||
background-image: linear-gradient(180deg, $danger 10%, darken($danger, 15%) 100%);
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
// Grayscale Background Utilities
|
||||
|
||||
.bg-gray-100 {
|
||||
background-color: $gray-100 !important;
|
||||
}
|
||||
|
||||
.bg-gray-200 {
|
||||
background-color: $gray-200 !important;
|
||||
}
|
||||
|
||||
.bg-gray-300 {
|
||||
background-color: $gray-300 !important;
|
||||
}
|
||||
|
||||
.bg-gray-400 {
|
||||
background-color: $gray-400 !important;
|
||||
}
|
||||
|
||||
.bg-gray-500 {
|
||||
background-color: $gray-500 !important;
|
||||
}
|
||||
|
||||
.bg-gray-600 {
|
||||
background-color: $gray-600 !important;
|
||||
}
|
||||
|
||||
.bg-gray-700 {
|
||||
background-color: $gray-700 !important;
|
||||
}
|
||||
|
||||
.bg-gray-800 {
|
||||
background-color: $gray-800 !important;
|
||||
}
|
||||
|
||||
.bg-gray-900 {
|
||||
background-color: $gray-900 !important;
|
||||
}
|
39
assets/startbootstrap-sb-admin-2/scss/utilities/_border.scss
Normal file
39
assets/startbootstrap-sb-admin-2/scss/utilities/_border.scss
Normal file
@ -0,0 +1,39 @@
|
||||
.border-left-primary {
|
||||
border-left: .25rem solid $primary !important;
|
||||
}
|
||||
|
||||
.border-left-success {
|
||||
border-left: .25rem solid $success !important;
|
||||
}
|
||||
|
||||
.border-left-info {
|
||||
border-left: .25rem solid $info !important;
|
||||
}
|
||||
|
||||
.border-left-warning {
|
||||
border-left: .25rem solid $warning !important;
|
||||
}
|
||||
|
||||
.border-left-danger {
|
||||
border-left: .25rem solid $danger !important;
|
||||
}
|
||||
|
||||
.border-bottom-primary {
|
||||
border-bottom: .25rem solid $primary !important;
|
||||
}
|
||||
|
||||
.border-bottom-success {
|
||||
border-bottom: .25rem solid $success !important;
|
||||
}
|
||||
|
||||
.border-bottom-info {
|
||||
border-bottom: .25rem solid $info !important;
|
||||
}
|
||||
|
||||
.border-bottom-warning {
|
||||
border-bottom: .25rem solid $warning !important;
|
||||
}
|
||||
|
||||
.border-bottom-danger {
|
||||
border-bottom: .25rem solid $danger !important;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
// Overflow Hidden
|
||||
.o-hidden {
|
||||
overflow: hidden !important;
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
.progress-sm {
|
||||
height: .5rem;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
.rotate-15 {
|
||||
transform: rotate(15deg);
|
||||
}
|
||||
|
||||
.rotate-n-15 {
|
||||
transform: rotate(-15deg);
|
||||
}
|
54
assets/startbootstrap-sb-admin-2/scss/utilities/_text.scss
Normal file
54
assets/startbootstrap-sb-admin-2/scss/utilities/_text.scss
Normal file
@ -0,0 +1,54 @@
|
||||
// Grayscale Text Utilities
|
||||
|
||||
.text-xs {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
.text-lg {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.text-gray-100 {
|
||||
color: $gray-100 !important;
|
||||
}
|
||||
|
||||
.text-gray-200 {
|
||||
color: $gray-200 !important;
|
||||
}
|
||||
|
||||
.text-gray-300 {
|
||||
color: $gray-300 !important;
|
||||
}
|
||||
|
||||
.text-gray-400 {
|
||||
color: $gray-400 !important;
|
||||
}
|
||||
|
||||
.text-gray-500 {
|
||||
color: $gray-500 !important;
|
||||
}
|
||||
|
||||
.text-gray-600 {
|
||||
color: $gray-600 !important;
|
||||
}
|
||||
|
||||
.text-gray-700 {
|
||||
color: $gray-700 !important;
|
||||
}
|
||||
|
||||
.text-gray-800 {
|
||||
color: $gray-800 !important;
|
||||
}
|
||||
|
||||
.text-gray-900 {
|
||||
color: $gray-900 !important;
|
||||
}
|
||||
|
||||
.icon-circle {
|
||||
height: 2.5rem;
|
||||
width: 2.5rem;
|
||||
border-radius: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
1579
assets/styles/animate.scss
vendored
Normal file
1579
assets/styles/animate.scss
vendored
Normal file
File diff suppressed because it is too large
Load Diff
115
assets/styles/app.scss
Normal file
115
assets/styles/app.scss
Normal file
@ -0,0 +1,115 @@
|
||||
$primary: #4154f1;
|
||||
$secondary: #00ffc1;
|
||||
$text: #212529FF;
|
||||
$blue: #012970;
|
||||
|
||||
@import "~bootstrap/scss/bootstrap";
|
||||
@import "~tom-select/src/scss/tom-select.scss";
|
||||
@import "~toastify-js/src/toastify.css";
|
||||
@import "bootstrap-icons/font/bootstrap-icons.css";
|
||||
|
||||
@import "style";
|
||||
|
||||
.grow-x-1 {
|
||||
transition: .3s ease-out;
|
||||
|
||||
&:hover {
|
||||
transform: scaleX(1.01);
|
||||
}
|
||||
}
|
||||
|
||||
.grow-x-2 {
|
||||
transition: .3s ease-out;
|
||||
|
||||
&:hover {
|
||||
transform: scaleX(1.02);
|
||||
}
|
||||
}
|
||||
|
||||
.img-container {
|
||||
img {
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
color: $danger;
|
||||
|
||||
&.selected {
|
||||
background: $primary;
|
||||
border-radius: 15px;
|
||||
padding: 2px;
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
input.transparent {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.resource-image {
|
||||
transition: .3s ease-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
transform: scale(1.04);
|
||||
}
|
||||
|
||||
&.selected-image {
|
||||
border: 2px solid #198754FF;
|
||||
}
|
||||
}
|
||||
|
||||
.sl-slide-holder {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.nav-link.active {
|
||||
background: $primary;
|
||||
color: $white;
|
||||
}
|
||||
|
||||
.campaign-card {
|
||||
padding-top: 0.5rem;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.campaign-link {
|
||||
color: $text;
|
||||
}
|
||||
|
||||
.campaign-card-body {
|
||||
transition: .3s ease-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
transform: scale(1.04);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-grow {
|
||||
transition: .3s ease-out;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.04);
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
color: $text;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.collapse.dont-collapse-sm {
|
||||
display: block;
|
||||
height: auto !important;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
148
assets/styles/chosen.scss
Normal file
148
assets/styles/chosen.scss
Normal file
@ -0,0 +1,148 @@
|
||||
select.form-control + .chosen-container.chosen-container-single .chosen-single {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.428571429;
|
||||
color: #555;
|
||||
vertical-align: middle;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
|
||||
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
|
||||
-webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
||||
transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
|
||||
background-image:none;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container.chosen-container-single .chosen-single div {
|
||||
top:4px;
|
||||
color:#000;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container .chosen-drop {
|
||||
background-color: #FFF;
|
||||
border: 1px solid #CCC;
|
||||
border: 1px solid rgba(0, 0, 0, 0.15);
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
|
||||
background-clip: padding-box;
|
||||
margin: 2px 0 0;
|
||||
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container .chosen-search input[type=text] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 34px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.428571429;
|
||||
color: #555;
|
||||
vertical-align: middle;
|
||||
background-color: #FFF;
|
||||
border: 1px solid #CCC;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
background-image:none;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container .chosen-results {
|
||||
margin: 2px 0 0;
|
||||
padding: 5px 0;
|
||||
font-size: 14px;
|
||||
list-style: none;
|
||||
background-color: #fff;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container .chosen-results li ,
|
||||
select.form-control + .chosen-container .chosen-results li.active-result {
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
clear: both;
|
||||
font-weight: normal;
|
||||
line-height: 1.428571429;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
background-image:none;
|
||||
}
|
||||
select.form-control + .chosen-container .chosen-results li:hover,
|
||||
select.form-control + .chosen-container .chosen-results li.active-result:hover,
|
||||
select.form-control + .chosen-container .chosen-results li.highlighted
|
||||
{
|
||||
color: #FFF;
|
||||
text-decoration: none;
|
||||
background-color: #428BCA;
|
||||
background-image:none;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container-multi .chosen-choices {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 34px;
|
||||
padding: 6px;
|
||||
font-size: 14px;
|
||||
line-height: 1.428571429;
|
||||
color: #555;
|
||||
vertical-align: middle;
|
||||
background-color: #FFF;
|
||||
border: 1px solid #CCC;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||
background-image:none;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container-multi .chosen-choices li.search-field input[type="text"] {
|
||||
height:auto;
|
||||
padding:5px 0;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container-multi .chosen-choices li.search-choice {
|
||||
|
||||
background-image: none;
|
||||
padding: 3px 24px 3px 5px;
|
||||
margin: 0 6px 0 0;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
line-height: 1.428571429;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
color: #333;
|
||||
background-color: #FFF;
|
||||
border-color: #CCC;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
|
||||
top:8px;
|
||||
right:6px;
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container-multi.chosen-container-active .chosen-choices,
|
||||
select.form-control + .chosen-container.chosen-container-single.chosen-container-active .chosen-single,
|
||||
select.form-control + .chosen-container .chosen-search input[type=text]:focus{
|
||||
border-color: #66AFE9;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(102, 175, 233, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(102, 175, 233, 0.6);
|
||||
}
|
||||
|
||||
select.form-control + .chosen-container-multi .chosen-results li.result-selected{
|
||||
display: list-item;
|
||||
color: #ccc;
|
||||
cursor: default;
|
||||
background-color: white;
|
||||
}
|
1256
assets/styles/style.scss
Normal file
1256
assets/styles/style.scss
Normal file
File diff suppressed because it is too large
Load Diff
564
assets/styles/wizard.scss
Normal file
564
assets/styles/wizard.scss
Normal file
@ -0,0 +1,564 @@
|
||||
@import "animate.scss";
|
||||
|
||||
.paste-styled .spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 100px auto;
|
||||
background-color: white;
|
||||
border-radius: 100%;
|
||||
-webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
|
||||
animation: sk-scaleout 1.0s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-scaleout {
|
||||
0% {
|
||||
-webkit-transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-scaleout {
|
||||
0% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.paste-styled .control-panel {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.paste-styled .control-panel .control-panel-menu {
|
||||
width: 20%;
|
||||
border-right-color: lightgray;
|
||||
border-right-style: solid;
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.paste-styled .control-panel .control-panel-menu ul {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.paste-styled .control-panel .control-panel-menu ul li {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.paste-styled .control-panel .control-panel-menu ul li a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
box-sizing: border-box;
|
||||
padding-left: 0.5rem;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004);
|
||||
font-weight: 300;
|
||||
transition: .2s;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
|
||||
.paste-styled .control-panel .control-panel-menu ul li a .material-icons {
|
||||
vertical-align: middle;
|
||||
color: black;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.paste-styled .control-panel .control-panel-menu ul li a:hover {
|
||||
color: #147e93;
|
||||
transition: .2s;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: lightgray;
|
||||
}
|
||||
|
||||
.paste-styled .control-panel .control-panel-pane {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.paste-styled .split-h {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.paste-styled .step-by-step {
|
||||
width: 100%;
|
||||
//min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.paste-styled .step-by-step .step-by-step-step {
|
||||
width: 100%;
|
||||
min-height: 300px;
|
||||
//border-radius: 8px;
|
||||
//border-color: lightgray;
|
||||
//border-width: 1px;
|
||||
//border-style: solid;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.paste-styled .step-by-step .step-by-step-step[data-active='0'] {
|
||||
opacity: 0;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.paste-styled .step-by-step .step-by-step-step .default-content {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.paste-styled .step-by-step .step-by-step-step label, .paste-styled .step-by-step .step-by-step-step h1, .paste-styled .step-by-step .step-by-step-step h2, .paste-styled .step-by-step .step-by-step-step h3, .paste-styled .step-by-step .step-by-step-step h4, .paste-styled .step-by-step .step-by-step-step h5, .paste-styled .step-by-step .step-by-step-step h6 {
|
||||
color: #147e93;
|
||||
}
|
||||
|
||||
.paste-styled .step-by-step .step-by-step-step .step-by-step-stepper {
|
||||
width: 100%;
|
||||
height: 92px;
|
||||
line-height: 92px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.paste-styled .step-by-step .step-by-step-step .step-by-step-stepper button {
|
||||
margin-left: 1rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.paste-styled .dashboard {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.paste-styled .dashboard .dashboard-item {
|
||||
width: auto;
|
||||
min-height: 200px;
|
||||
margin: 0.5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.paste-styled .dashboard .dashboard-item .material-icons {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu {
|
||||
background-color: black;
|
||||
min-width: 128px;
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004);
|
||||
z-index: 60;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu ul {
|
||||
display: block !important;
|
||||
list-style: none !important;
|
||||
margin: 0px !important;
|
||||
padding-left: 0px !important;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu ul li {
|
||||
display: block;
|
||||
padding-left: 0px !important;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu ul li a {
|
||||
display: block;
|
||||
color: white;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
font-weight: 200;
|
||||
box-sizing: border-box;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
text-decoration: none;
|
||||
border-bottom: none !important;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu ul li a:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu ul li a .material-icons {
|
||||
vertical-align: middle;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu .drop-menu-button {
|
||||
height: 42px;
|
||||
width: 42px;
|
||||
line-height: 42px;
|
||||
text-align: center;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: absolute;
|
||||
bottom: -42px;
|
||||
border-bottom-right-radius: 10.5px;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu .drop-menu-button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu .drop-menu-button .material-icons {
|
||||
color: white;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.paste-styled .drop-menu[data-active='0'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.paste-styled .backdrop {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: rgba(0, 0, 0, 0.8);
|
||||
z-index: 70;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.paste-styled .backdrop .backdrop-content {
|
||||
z-index: 80;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.paste-styled .backdrop .card {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.paste-styled .backdrop[active="0"] {
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.paste-styled .button {
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
background: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
border-color: transparent;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-radius: 16px;
|
||||
color: black;
|
||||
font-weight: 200;
|
||||
text-align: center;
|
||||
padding-left: 0.8rem;
|
||||
padding-right: 0.8rem;
|
||||
min-width: 92px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
transition: .2s;
|
||||
background-color: lightgray;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.paste-styled .button:hover {
|
||||
cursor: pointer;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-warning {
|
||||
background-color: #ff3b30;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-warning:hover {
|
||||
border-color: black;
|
||||
color: black;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-ok {
|
||||
background-color: #4cd964;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-ok:hover {
|
||||
border-color: black;
|
||||
color: black;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-primary {
|
||||
background-color: #147e93;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-primary:hover {
|
||||
border-color: black;
|
||||
color: black;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-small {
|
||||
min-width: auto;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
text-align: center;
|
||||
color: black;
|
||||
border-radius: 42px;
|
||||
border-color: black;
|
||||
border-width: 1px;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-small:hover {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-small-primary {
|
||||
border-color: #147e93;
|
||||
border-color: #147e93;
|
||||
color: #147e93;
|
||||
}
|
||||
|
||||
.paste-styled .button.button-small-primary:hover {
|
||||
background-color: #147e93;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.paste-styled .button[disabled] {
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.paste-styled .button[disabled]:hover {
|
||||
background-color: lightgray;
|
||||
cursor: default;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.paste-styled .form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.paste-styled .form .button, .paste-styled .form input, .paste-styled .form a, .paste-styled .form label, .paste-styled .form select {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.paste-styled .form label, .paste-styled .form input, .paste-styled .form p, .paste-styled .form a {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004);
|
||||
}
|
||||
|
||||
.paste-styled .form label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.paste-styled .form input {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.paste-styled .form input[type='text'], .paste-styled .form input[type='password'], .paste-styled .form input[type='email'] {
|
||||
//display: inline-block;
|
||||
//width: 100%;
|
||||
//height: 48px;
|
||||
//line-height: 48px;
|
||||
//background: none;
|
||||
//outline: none;
|
||||
//border: none;
|
||||
//border-bottom-color: lightgray;
|
||||
//border-bottom-style: solid;
|
||||
//border-bottom-width: 1px;
|
||||
//font-size: 100%;
|
||||
//font-weight: 300;
|
||||
}
|
||||
|
||||
.paste-styled .form select {
|
||||
display: inline-block;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
background: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-radius: 4px;
|
||||
border-color: lightgray;
|
||||
}
|
||||
|
||||
.paste-styled .form textarea {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 360px;
|
||||
}
|
||||
|
||||
.paste-styled .card {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
|
||||
}
|
||||
|
||||
.paste-styled .simple-card {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
border-width: 1px;
|
||||
border-color: lightgray;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.paste-styled h1, .paste-styled h2, .paste-styled h3, .paste-styled h4, .paste-styled h5, .paste-styled h6, .paste-styled p, .paste-styled a {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004);
|
||||
}
|
||||
|
||||
.paste-styled h1, .paste-styled h2, .paste-styled h3, .paste-styled h4, .paste-styled h5, .paste-styled h6 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.paste-styled p, .paste-styled a {
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.paste-styled .text-warning {
|
||||
color: #ff3b30 !important;
|
||||
}
|
||||
|
||||
.paste-styled .text-ok {
|
||||
color: #4cd964 !important;
|
||||
}
|
||||
|
||||
.paste-styled .text-primary {
|
||||
color: #147e93 !important;
|
||||
}
|
||||
|
||||
.paste-styled .table {
|
||||
text-align: left;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004);
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.paste-styled .table th, .paste-styled .table td {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.paste-styled .table td {
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.paste-styled .table tr {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: lightgray;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.paste-styled .default-content {
|
||||
box-sizing: border-box;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.paste-styled .squeezed-content {
|
||||
box-sizing: border-box;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.paste-styled .material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
/* Preferred icon size */
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
/* Support for all WebKit browsers. */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
/* Support for Safari and Chrome. */
|
||||
text-rendering: optimizeLegibility;
|
||||
/* Support for Firefox. */
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
/* Support for IE. */
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
|
||||
.paste-styled .push-down {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.paste-styled .full-height {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.paste-styled .full-width {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.paste-styled .maximize-height {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.paste-styled .centered-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.paste-styled .centered-text {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.admin-editable p {
|
||||
margin: 0px !important;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=style.css.map */
|
21
bin/console
Executable file
21
bin/console
Executable file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||
|
||||
if (!is_dir(dirname(__DIR__).'/vendor')) {
|
||||
throw new LogicException('Dependencies are missing. Try running "composer install".');
|
||||
}
|
||||
|
||||
if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
|
||||
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
|
||||
}
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
|
||||
return new Application($kernel);
|
||||
};
|
23
bin/phpunit
Executable file
23
bin/phpunit
Executable file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
ini_set('date.timezone', 'UTC');
|
||||
}
|
||||
|
||||
if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
require dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit';
|
||||
} else {
|
||||
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
|
||||
require PHPUNIT_COMPOSER_INSTALL;
|
||||
PHPUnit\TextUI\Command::main();
|
||||
}
|
||||
} else {
|
||||
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
|
||||
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
|
||||
}
|
19
compose.override.yaml
Normal file
19
compose.override.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
###> doctrine/doctrine-bundle ###
|
||||
database:
|
||||
ports:
|
||||
- "5432"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
mailer:
|
||||
image: axllent/mailpit
|
||||
ports:
|
||||
- "1025"
|
||||
- "8025"
|
||||
environment:
|
||||
MP_SMTP_AUTH_ACCEPT_ANY: 1
|
||||
MP_SMTP_AUTH_ALLOW_INSECURE: 1
|
||||
###< symfony/mailer ###
|
21
compose.yaml
Normal file
21
compose.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
###> doctrine/doctrine-bundle ###
|
||||
database:
|
||||
image: postgres:${POSTGRES_VERSION:-16}-alpine
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-app}
|
||||
# You should definitely change the password in production
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-app}
|
||||
volumes:
|
||||
- database_data:/var/lib/postgresql/data:rw
|
||||
# You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
|
||||
# - ./docker/db/data:/var/lib/postgresql/data:rw
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
volumes:
|
||||
###> doctrine/doctrine-bundle ###
|
||||
database_data:
|
||||
###< doctrine/doctrine-bundle ###
|
110
composer.json
Normal file
110
composer.json
Normal file
@ -0,0 +1,110 @@
|
||||
{
|
||||
"type": "project",
|
||||
"license": "proprietary",
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"doctrine/dbal": "^3",
|
||||
"doctrine/doctrine-bundle": "^2.12",
|
||||
"doctrine/doctrine-migrations-bundle": "^3.3",
|
||||
"doctrine/orm": "^3.1",
|
||||
"phpdocumentor/reflection-docblock": "^5.4",
|
||||
"phpstan/phpdoc-parser": "^1.28",
|
||||
"symfony/asset": "6.0.*",
|
||||
"symfony/console": "6.0.*",
|
||||
"symfony/doctrine-messenger": "6.0.*",
|
||||
"symfony/dotenv": "6.0.*",
|
||||
"symfony/expression-language": "6.0.*",
|
||||
"symfony/flex": "^2",
|
||||
"symfony/form": "6.0.*",
|
||||
"symfony/framework-bundle": "6.0.*",
|
||||
"symfony/http-client": "6.0.*",
|
||||
"symfony/intl": "6.0.*",
|
||||
"symfony/mailer": "6.0.*",
|
||||
"symfony/mime": "6.0.*",
|
||||
"symfony/monolog-bundle": "^3.0",
|
||||
"symfony/notifier": "6.0.*",
|
||||
"symfony/process": "6.0.*",
|
||||
"symfony/property-access": "6.0.*",
|
||||
"symfony/property-info": "6.0.*",
|
||||
"symfony/runtime": "6.0.*",
|
||||
"symfony/security-bundle": "6.0.*",
|
||||
"symfony/serializer": "6.0.*",
|
||||
"symfony/stimulus-bundle": "^2.16",
|
||||
"symfony/string": "6.0.*",
|
||||
"symfony/translation": "6.0.*",
|
||||
"symfony/twig-bundle": "6.0.*",
|
||||
"symfony/ux-chartjs": "^2.16",
|
||||
"symfony/ux-react": "^2.16",
|
||||
"symfony/validator": "6.0.*",
|
||||
"symfony/web-link": "6.0.*",
|
||||
"symfony/webpack-encore-bundle": "^1.17",
|
||||
"symfony/yaml": "6.0.*",
|
||||
"twig/extra-bundle": "^2.12|^3.0",
|
||||
"twig/twig": "^2.12|^3.0"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"symfony/flex": true,
|
||||
"symfony/runtime": true
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": {
|
||||
"*": "dist"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"App\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"replace": {
|
||||
"symfony/polyfill-ctype": "*",
|
||||
"symfony/polyfill-iconv": "*",
|
||||
"symfony/polyfill-php72": "*",
|
||||
"symfony/polyfill-php73": "*",
|
||||
"symfony/polyfill-php74": "*",
|
||||
"symfony/polyfill-php80": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@auto-scripts"
|
||||
]
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/symfony": "*"
|
||||
},
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "6.0.*"
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"symfony/browser-kit": "6.0.*",
|
||||
"symfony/css-selector": "6.0.*",
|
||||
"symfony/debug-bundle": "6.0.*",
|
||||
"symfony/maker-bundle": "^1.0",
|
||||
"symfony/phpunit-bridge": "^7.0",
|
||||
"symfony/stopwatch": "6.0.*",
|
||||
"symfony/web-profiler-bundle": "6.0.*"
|
||||
}
|
||||
}
|
9570
composer.lock
generated
Normal file
9570
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
config/bundles.php
Normal file
18
config/bundles.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
|
||||
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
|
||||
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true],
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
||||
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
|
||||
Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true],
|
||||
Symfony\UX\Chartjs\ChartjsBundle::class => ['all' => true],
|
||||
Symfony\UX\React\ReactBundle::class => ['all' => true],
|
||||
];
|
19
config/packages/cache.yaml
Normal file
19
config/packages/cache.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
framework:
|
||||
cache:
|
||||
# Unique name of your app: used to compute stable namespaces for cache keys.
|
||||
#prefix_seed: your_vendor_name/app_name
|
||||
|
||||
# The "app" cache stores to the filesystem by default.
|
||||
# The data in this cache should persist between deploys.
|
||||
# Other options include:
|
||||
|
||||
# Redis
|
||||
#app: cache.adapter.redis
|
||||
#default_redis_provider: redis://localhost
|
||||
|
||||
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
|
||||
#app: cache.adapter.apcu
|
||||
|
||||
# Namespaced pools use the above "app" backend by default
|
||||
#pools:
|
||||
#my.dedicated.cache: null
|
5
config/packages/debug.yaml
Normal file
5
config/packages/debug.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
when@dev:
|
||||
debug:
|
||||
# Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
|
||||
# See the "server:dump" command to start a new server.
|
||||
dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
|
44
config/packages/doctrine.yaml
Normal file
44
config/packages/doctrine.yaml
Normal file
@ -0,0 +1,44 @@
|
||||
doctrine:
|
||||
dbal:
|
||||
url: '%env(resolve:DATABASE_URL)%'
|
||||
|
||||
# IMPORTANT: You MUST configure your server version,
|
||||
# either here or in the DATABASE_URL env var (see .env file)
|
||||
#server_version: '16'
|
||||
use_savepoints: true
|
||||
orm:
|
||||
auto_generate_proxy_classes: true
|
||||
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
|
||||
auto_mapping: true
|
||||
mappings:
|
||||
App:
|
||||
is_bundle: false
|
||||
dir: '%kernel.project_dir%/src/Entity'
|
||||
prefix: 'App\Entity'
|
||||
alias: App
|
||||
|
||||
when@test:
|
||||
doctrine:
|
||||
dbal:
|
||||
# "TEST_TOKEN" is typically set by ParaTest
|
||||
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
|
||||
|
||||
when@prod:
|
||||
doctrine:
|
||||
orm:
|
||||
auto_generate_proxy_classes: false
|
||||
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
|
||||
query_cache_driver:
|
||||
type: pool
|
||||
pool: doctrine.system_cache_pool
|
||||
result_cache_driver:
|
||||
type: pool
|
||||
pool: doctrine.result_cache_pool
|
||||
|
||||
framework:
|
||||
cache:
|
||||
pools:
|
||||
doctrine.result_cache_pool:
|
||||
adapter: cache.app
|
||||
doctrine.system_cache_pool:
|
||||
adapter: cache.system
|
6
config/packages/doctrine_migrations.yaml
Normal file
6
config/packages/doctrine_migrations.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
doctrine_migrations:
|
||||
migrations_paths:
|
||||
# namespace is arbitrary but should be different from App\Migrations
|
||||
# as migrations classes should NOT be autoloaded
|
||||
'DoctrineMigrations': '%kernel.project_dir%/migrations'
|
||||
enable_profiler: false
|
24
config/packages/framework.yaml
Normal file
24
config/packages/framework.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||
framework:
|
||||
secret: '%env(APP_SECRET)%'
|
||||
#csrf_protection: true
|
||||
http_method_override: false
|
||||
|
||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||
# Remove or comment this section to explicitly disable session support.
|
||||
session:
|
||||
handler_id: null
|
||||
cookie_secure: auto
|
||||
cookie_samesite: lax
|
||||
storage_factory_id: session.storage.factory.native
|
||||
|
||||
#esi: true
|
||||
#fragments: true
|
||||
php_errors:
|
||||
log: true
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
test: true
|
||||
session:
|
||||
storage_factory_id: session.storage.factory.mock_file
|
3
config/packages/mailer.yaml
Normal file
3
config/packages/mailer.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
framework:
|
||||
mailer:
|
||||
dsn: '%env(MAILER_DSN)%'
|
29
config/packages/messenger.yaml
Normal file
29
config/packages/messenger.yaml
Normal file
@ -0,0 +1,29 @@
|
||||
framework:
|
||||
messenger:
|
||||
failure_transport: failed
|
||||
|
||||
transports:
|
||||
# https://symfony.com/doc/current/messenger.html#transport-configuration
|
||||
async:
|
||||
dsn: '%env(MESSENGER_TRANSPORT_DSN)%'
|
||||
options:
|
||||
use_notify: true
|
||||
check_delayed_interval: 60000
|
||||
retry_strategy:
|
||||
max_retries: 3
|
||||
multiplier: 2
|
||||
failed: 'doctrine://default?queue_name=failed'
|
||||
# sync: 'sync://'
|
||||
|
||||
default_bus: messenger.bus.default
|
||||
|
||||
buses:
|
||||
messenger.bus.default: []
|
||||
|
||||
routing:
|
||||
Symfony\Component\Mailer\Messenger\SendEmailMessage: async
|
||||
Symfony\Component\Notifier\Message\ChatMessage: async
|
||||
Symfony\Component\Notifier\Message\SmsMessage: async
|
||||
|
||||
# Route your messages to the transports
|
||||
# 'App\Message\YourMessage': async
|
62
config/packages/monolog.yaml
Normal file
62
config/packages/monolog.yaml
Normal file
@ -0,0 +1,62 @@
|
||||
monolog:
|
||||
channels:
|
||||
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
|
||||
|
||||
when@dev:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
channels: ["!event"]
|
||||
# uncomment to get logging in your browser
|
||||
# you may have to allow bigger header sizes in your Web server configuration
|
||||
#firephp:
|
||||
# type: firephp
|
||||
# level: info
|
||||
#chromephp:
|
||||
# type: chromephp
|
||||
# level: info
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine", "!console"]
|
||||
|
||||
when@test:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
channels: ["!event"]
|
||||
nested:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
|
||||
when@prod:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
|
||||
nested:
|
||||
type: stream
|
||||
path: php://stderr
|
||||
level: debug
|
||||
formatter: monolog.formatter.json
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine"]
|
||||
deprecation:
|
||||
type: stream
|
||||
channels: [deprecation]
|
||||
path: php://stderr
|
||||
formatter: monolog.formatter.json
|
12
config/packages/notifier.yaml
Normal file
12
config/packages/notifier.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
framework:
|
||||
notifier:
|
||||
chatter_transports:
|
||||
texter_transports:
|
||||
channel_policy:
|
||||
# use chat/slack, chat/telegram, sms/twilio or sms/nexmo
|
||||
urgent: ['email']
|
||||
high: ['email']
|
||||
medium: ['email']
|
||||
low: ['email']
|
||||
admin_recipients:
|
||||
- { email: admin@example.com }
|
12
config/packages/routing.yaml
Normal file
12
config/packages/routing.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
framework:
|
||||
router:
|
||||
utf8: true
|
||||
|
||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||
#default_uri: http://localhost
|
||||
|
||||
when@prod:
|
||||
framework:
|
||||
router:
|
||||
strict_requirements: null
|
39
config/packages/security.yaml
Normal file
39
config/packages/security.yaml
Normal file
@ -0,0 +1,39 @@
|
||||
security:
|
||||
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
||||
password_hashers:
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
||||
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
||||
providers:
|
||||
users_in_memory: { memory: null }
|
||||
firewalls:
|
||||
dev:
|
||||
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
||||
security: false
|
||||
main:
|
||||
lazy: true
|
||||
provider: users_in_memory
|
||||
|
||||
# activate different ways to authenticate
|
||||
# https://symfony.com/doc/current/security.html#the-firewall
|
||||
|
||||
# https://symfony.com/doc/current/security/impersonating_user.html
|
||||
# switch_user: true
|
||||
|
||||
# Easy way to control access for large sections of your site
|
||||
# Note: Only the *first* access control that matches will be used
|
||||
access_control:
|
||||
# - { path: ^/admin, roles: ROLE_ADMIN }
|
||||
# - { path: ^/profile, roles: ROLE_USER }
|
||||
|
||||
when@test:
|
||||
security:
|
||||
password_hashers:
|
||||
# By default, password hashers are resource intensive and take time. This is
|
||||
# important to generate secure password hashes. In tests however, secure hashes
|
||||
# are not important, waste resources and increase test times. The following
|
||||
# reduces the work factor to the lowest possible values.
|
||||
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
|
||||
algorithm: auto
|
||||
cost: 4 # Lowest possible value for bcrypt
|
||||
time_cost: 3 # Lowest possible value for argon
|
||||
memory_cost: 10 # Lowest possible value for argon
|
7
config/packages/translation.yaml
Normal file
7
config/packages/translation.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
framework:
|
||||
default_locale: en
|
||||
translator:
|
||||
default_path: '%kernel.project_dir%/translations'
|
||||
fallbacks:
|
||||
- en
|
||||
providers:
|
6
config/packages/twig.yaml
Normal file
6
config/packages/twig.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
twig:
|
||||
default_path: '%kernel.project_dir%/templates'
|
||||
|
||||
when@test:
|
||||
twig:
|
||||
strict_variables: true
|
13
config/packages/validator.yaml
Normal file
13
config/packages/validator.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
framework:
|
||||
validation:
|
||||
email_validation_mode: html5
|
||||
|
||||
# Enables validator auto-mapping support.
|
||||
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
|
||||
#auto_mapping:
|
||||
# App\Entity\: []
|
||||
|
||||
when@test:
|
||||
framework:
|
||||
validation:
|
||||
not_compromised_password: false
|
15
config/packages/web_profiler.yaml
Normal file
15
config/packages/web_profiler.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
when@dev:
|
||||
web_profiler:
|
||||
toolbar: true
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { only_exceptions: false }
|
||||
|
||||
when@test:
|
||||
web_profiler:
|
||||
toolbar: false
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { collect: false }
|
45
config/packages/webpack_encore.yaml
Normal file
45
config/packages/webpack_encore.yaml
Normal file
@ -0,0 +1,45 @@
|
||||
webpack_encore:
|
||||
# The path where Encore is building the assets - i.e. Encore.setOutputPath()
|
||||
output_path: '%kernel.project_dir%/public/build'
|
||||
# If multiple builds are defined (as shown below), you can disable the default build:
|
||||
# output_path: false
|
||||
|
||||
# Set attributes that will be rendered on all script and link tags
|
||||
script_attributes:
|
||||
defer: true
|
||||
# Uncomment (also under link_attributes) if using Turbo Drive
|
||||
# https://turbo.hotwired.dev/handbook/drive#reloading-when-assets-change
|
||||
# 'data-turbo-track': reload
|
||||
# link_attributes:
|
||||
# Uncomment if using Turbo Drive
|
||||
# 'data-turbo-track': reload
|
||||
|
||||
# If using Encore.enableIntegrityHashes() and need the crossorigin attribute (default: false, or use 'anonymous' or 'use-credentials')
|
||||
# crossorigin: 'anonymous'
|
||||
|
||||
# Preload all rendered script and link tags automatically via the HTTP/2 Link header
|
||||
# preload: true
|
||||
|
||||
# Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
|
||||
# strict_mode: false
|
||||
|
||||
# If you have multiple builds:
|
||||
# builds:
|
||||
# frontend: '%kernel.project_dir%/public/frontend/build'
|
||||
|
||||
# pass the build name as the 3rd argument to the Twig functions
|
||||
# {{ encore_entry_script_tags('entry1', null, 'frontend') }}
|
||||
|
||||
framework:
|
||||
assets:
|
||||
json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
|
||||
|
||||
#when@prod:
|
||||
# webpack_encore:
|
||||
# # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
|
||||
# # Available in version 1.2
|
||||
# cache: true
|
||||
|
||||
#when@test:
|
||||
# webpack_encore:
|
||||
# strict_mode: false
|
5
config/preload.php
Normal file
5
config/preload.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
|
||||
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
|
||||
}
|
7
config/routes.yaml
Normal file
7
config/routes.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
controllers:
|
||||
resource: ../src/Controller/
|
||||
type: annotation
|
||||
|
||||
kernel:
|
||||
resource: ../src/Kernel.php
|
||||
type: annotation
|
4
config/routes/framework.yaml
Normal file
4
config/routes/framework.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
when@dev:
|
||||
_errors:
|
||||
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
|
||||
prefix: /_error
|
8
config/routes/web_profiler.yaml
Normal file
8
config/routes/web_profiler.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
when@dev:
|
||||
web_profiler_wdt:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
|
||||
prefix: /_wdt
|
||||
|
||||
web_profiler_profiler:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
|
||||
prefix: /_profiler
|
24
config/services.yaml
Normal file
24
config/services.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
# This file is the entry point to configure your own services.
|
||||
# Files in the packages/ subdirectory configure your dependencies.
|
||||
|
||||
# Put parameters here that don't need to change on each machine where the app is deployed
|
||||
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
|
||||
parameters:
|
||||
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
_defaults:
|
||||
autowire: true # Automatically injects dependencies in your services.
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
resource: '../src/'
|
||||
exclude:
|
||||
- '../src/DependencyInjection/'
|
||||
- '../src/Entity/'
|
||||
- '../src/Kernel.php'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
0
migrations/.gitignore
vendored
Normal file
0
migrations/.gitignore
vendored
Normal file
51
package.json
Normal file
51
package.json
Normal file
@ -0,0 +1,51 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@hotwired/stimulus": "^3.0.0",
|
||||
"@symfony/stimulus-bridge": "^3.2.0",
|
||||
"@symfony/stimulus-bundle": "file:vendor/symfony/stimulus-bundle/assets",
|
||||
"@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/assets",
|
||||
"@symfony/ux-react": "file:vendor/symfony/ux-react/assets",
|
||||
"@symfony/webpack-encore": "^1.8.2",
|
||||
"chart.js": "^3.4.1",
|
||||
"core-js": "^3.0.0",
|
||||
"react": "^18.0",
|
||||
"react-dom": "^18.0",
|
||||
"regenerator-runtime": "^0.13.2",
|
||||
"sass": "^1.51.0",
|
||||
"sass-loader": "^12.0.0",
|
||||
"webpack-notifier": "^1.6.0"
|
||||
},
|
||||
"license": "UNLICENSED",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev-server": "encore dev-server",
|
||||
"dev": "encore dev",
|
||||
"watch": "encore dev --watch",
|
||||
"build": "encore production --progress"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^6.2",
|
||||
"@popperjs/core": "^2.11.5",
|
||||
"bootstrap": "^5.3.3",
|
||||
"bootstrap-icons": "^1.11.1",
|
||||
"chosen-js": "^1.8.7",
|
||||
"codemirror": "^5.63.3",
|
||||
"datatables": "^1.10.18",
|
||||
"date-fns": "^2.30.0",
|
||||
"htmx.org": "^1.7.0",
|
||||
"jquery": "^3.6.0",
|
||||
"jquery-validation": "^1.19.3",
|
||||
"pdfmake": "^0.2.2",
|
||||
"react-chartjs-2": "^5.2.0",
|
||||
"react-select": "^5.7.7",
|
||||
"react-toastify": "^9.1.3",
|
||||
"summernote": "^0.8.20",
|
||||
"sweetalert2": "^11.4.33",
|
||||
"toastify-js": "^1.12.0",
|
||||
"tom-select": "^2.2.1",
|
||||
"uuid": "^9.0.1",
|
||||
"webpack-jquery-ui": "^2.0.1"
|
||||
}
|
||||
}
|
38
phpunit.xml.dist
Normal file
38
phpunit.xml.dist
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
colors="true"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
convertDeprecationsToExceptions="false"
|
||||
>
|
||||
<php>
|
||||
<ini name="display_errors" value="1" />
|
||||
<ini name="error_reporting" value="-1" />
|
||||
<server name="APP_ENV" value="test" force="true" />
|
||||
<server name="SHELL_VERBOSITY" value="-1" />
|
||||
<server name="SYMFONY_PHPUNIT_REMOVE" value="" />
|
||||
<server name="SYMFONY_PHPUNIT_VERSION" value="9.5" />
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">src</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
|
||||
<listeners>
|
||||
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener" />
|
||||
</listeners>
|
||||
|
||||
<extensions>
|
||||
</extensions>
|
||||
</phpunit>
|
13
public/build/710.47c7f965.css
Normal file
13
public/build/710.47c7f965.css
Normal file
File diff suppressed because one or more lines are too long
2
public/build/710.fddd3797.js
Normal file
2
public/build/710.fddd3797.js
Normal file
File diff suppressed because one or more lines are too long
49
public/build/710.fddd3797.js.LICENSE.txt
Normal file
49
public/build/710.fddd3797.js.LICENSE.txt
Normal file
@ -0,0 +1,49 @@
|
||||
/*!
|
||||
* Bootstrap v5.3.3 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @kurkle/color v0.2.1
|
||||
* https://github.com/kurkle/color#readme
|
||||
* (c) 2022 Jukka Kurkela
|
||||
* Released under the MIT License
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Chart.js v3.9.1
|
||||
* https://www.chartjs.org
|
||||
* (c) 2022 Chart.js Contributors
|
||||
* Released under the MIT License
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
1
public/build/app.2a46ef8a.js
Normal file
1
public/build/app.2a46ef8a.js
Normal file
@ -0,0 +1 @@
|
||||
(self.webpackChunk=self.webpackChunk||[]).push([[524],{5926:(t,e,r)=>{var n={"./hello_controller.js":6824};function o(t){var e=u(t);return r(e)}function u(t){if(!r.o(n,t)){var e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return n[t]}o.keys=function(){return Object.keys(n)},o.resolve=u,t.exports=o,o.id=5926},2946:t=>{function e(t){var e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}e.keys=()=>[],e.resolve=e,e.id=2946,t.exports=e},5828:(t,e,r)=>{"use strict";r.d(e,{A:()=>u});var n=r(5978),o=r(666);const u={"symfony--ux-chartjs--chart":n.A,"symfony--ux-react--react":o.A}},6824:(t,e,r)=>{"use strict";r.r(e),r.d(e,{default:()=>a});r(2675),r(9463),r(2259),r(5700),r(3792),r(9572),r(4170),r(2892),r(9904),r(4185),r(875),r(287),r(6099),r(825),r(7764),r(2953);function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},n(t)}function o(t,e){for(var r=0;r<e.length;r++){var n=e[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,u(n.key),n)}}function u(t){var e=function(t,e){if("object"!=n(t)||!t)return t;var r=t[Symbol.toPrimitive];if(void 0!==r){var o=r.call(t,e||"default");if("object"!=n(o))return o;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===e?String:Number)(t)}(t,"string");return"symbol"==n(e)?e:e+""}function i(t,e,r){return e=f(e),function(t,e){if(e&&("object"===n(e)||"function"==typeof e))return e;if(void 0!==e)throw new TypeError("Derived constructors may only return object or undefined");return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t)}(t,c()?Reflect.construct(e,r||[],f(t).constructor):e.apply(t,r))}function c(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(t){}return(c=function(){return!!t})()}function f(t){return f=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)},f(t)}function l(t,e){return l=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t},l(t,e)}var a=function(t){function e(){return function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),i(this,e,arguments)}return function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),Object.defineProperty(t,"prototype",{writable:!1}),e&&l(t,e)}(e,t),r=e,(n=[{key:"connect",value:function(){this.element.textContent="Hello Stimulus! Edit me in assets/controllers/hello_controller.js"}}])&&o(r.prototype,n),u&&o(r,u),Object.defineProperty(r,"prototype",{writable:!1}),r;var r,n,u}(r(2891).xI)},2882:(t,e,r)=>{"use strict";var n=r(4517);r(9336),(0,r(3066).E)(r(5926));(0,n.$)(r(2946))}},t=>{t.O(0,[710],(()=>{return e=2882,t(t.s=e);var e}));t.O()}]);
|
6
public/build/app.76b5401d.css
Normal file
6
public/build/app.76b5401d.css
Normal file
File diff suppressed because one or more lines are too long
15
public/build/entrypoints.json
Normal file
15
public/build/entrypoints.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"entrypoints": {
|
||||
"app": {
|
||||
"js": [
|
||||
"/build/runtime.8ab7f0c8.js",
|
||||
"/build/710.fddd3797.js",
|
||||
"/build/app.2a46ef8a.js"
|
||||
],
|
||||
"css": [
|
||||
"/build/710.47c7f965.css",
|
||||
"/build/app.76b5401d.css"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
BIN
public/build/fonts/bootstrap-icons.39795c0b.woff
Normal file
BIN
public/build/fonts/bootstrap-icons.39795c0b.woff
Normal file
Binary file not shown.
BIN
public/build/fonts/bootstrap-icons.b7bcc075.woff2
Normal file
BIN
public/build/fonts/bootstrap-icons.b7bcc075.woff2
Normal file
Binary file not shown.
9
public/build/manifest.json
Normal file
9
public/build/manifest.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"build/app.css": "/build/app.76b5401d.css",
|
||||
"build/app.js": "/build/app.2a46ef8a.js",
|
||||
"build/runtime.js": "/build/runtime.8ab7f0c8.js",
|
||||
"build/710.47c7f965.css": "/build/710.47c7f965.css",
|
||||
"build/710.fddd3797.js": "/build/710.fddd3797.js",
|
||||
"build/fonts/bootstrap-icons.woff?": "/build/fonts/bootstrap-icons.39795c0b.woff",
|
||||
"build/fonts/bootstrap-icons.woff2?": "/build/fonts/bootstrap-icons.b7bcc075.woff2"
|
||||
}
|
1
public/build/runtime.8ab7f0c8.js
Normal file
1
public/build/runtime.8ab7f0c8.js
Normal file
@ -0,0 +1 @@
|
||||
(()=>{"use strict";var e,r={},t={};function o(e){var n=t[e];if(void 0!==n)return n.exports;var i=t[e]={exports:{}};return r[e].call(i.exports,i,i.exports,o),i.exports}o.m=r,e=[],o.O=(r,t,n,i)=>{if(!t){var l=1/0;for(s=0;s<e.length;s++){for(var[t,n,i]=e[s],a=!0,u=0;u<t.length;u++)(!1&i||l>=i)&&Object.keys(o.O).every((e=>o.O[e](t[u])))?t.splice(u--,1):(a=!1,i<l&&(l=i));if(a){e.splice(s--,1);var f=n();void 0!==f&&(r=f)}}return r}i=i||0;for(var s=e.length;s>0&&e[s-1][2]>i;s--)e[s]=e[s-1];e[s]=[t,n,i]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{var e={121:0};o.O.j=r=>0===e[r];var r=(r,t)=>{var n,i,[l,a,u]=t,f=0;if(l.some((r=>0!==e[r]))){for(n in a)o.o(a,n)&&(o.m[n]=a[n]);if(u)var s=u(o)}for(r&&r(t);f<l.length;f++)i=l[f],o.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return o.O(s)},t=self.webpackChunk=self.webpackChunk||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})()})();
|
9
public/index.php
Normal file
9
public/index.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
use App\Kernel;
|
||||
|
||||
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
|
||||
|
||||
return function (array $context) {
|
||||
return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
|
||||
};
|
0
src/Controller/.gitignore
vendored
Normal file
0
src/Controller/.gitignore
vendored
Normal file
349
src/Controller/BaseController.php
Normal file
349
src/Controller/BaseController.php
Normal file
@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use LogicException;
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Twig\Environment;
|
||||
|
||||
abstract class BaseController extends AbstractController
|
||||
{
|
||||
protected const EDIT = "edit";
|
||||
protected const NEW = "new";
|
||||
|
||||
public function isSlide(): string
|
||||
{
|
||||
return $this->getRequest()->isXmlHttpRequest() ? "_slide.html.twig" : ".html.twig";
|
||||
}
|
||||
|
||||
protected function blankSlide(string $html = ""): Response
|
||||
{
|
||||
return $this->render("default/slide/blank.html.twig", [
|
||||
'html' => $html,
|
||||
]);
|
||||
}
|
||||
|
||||
public function renderBlock(string $template, string $block, array $context = [])
|
||||
{
|
||||
$twig = $this->getTwig();
|
||||
$template = $twig->load($template);
|
||||
|
||||
return new Response($template->renderBlock($block, $context));
|
||||
}
|
||||
|
||||
protected function getTwig(): Environment
|
||||
{
|
||||
return $this->container->get("twig");
|
||||
}
|
||||
|
||||
protected function widget(string $template, array $context = []): JsonResponse
|
||||
{
|
||||
return $this->json([
|
||||
'status' => "OK",
|
||||
'html' => $this->renderView($template, $context),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function baseIndex(
|
||||
$datatable,
|
||||
$newUri = null,
|
||||
$title = null,
|
||||
$context = [],
|
||||
$viewTemplate = 'default/index.html.twig'
|
||||
): Response
|
||||
{
|
||||
// if ($this->isAjax()) {
|
||||
// return $this->render($grid);
|
||||
// }
|
||||
|
||||
return $this->renderAjax(
|
||||
'default/slide/index.html.twig',
|
||||
$viewTemplate,
|
||||
array_merge([
|
||||
'new_uri' => $newUri,
|
||||
'datatable' => $datatable,
|
||||
'title' => $title,
|
||||
], $context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NotFoundExceptionInterface
|
||||
* @throws ContainerExceptionInterface
|
||||
*/
|
||||
protected function baseDelete(
|
||||
mixed $entity,
|
||||
string $message,
|
||||
EntityManagerInterface $entityManager = null,
|
||||
callable $preDelete = null
|
||||
): Response
|
||||
{
|
||||
$em = $entityManager ?? $this->getEm();
|
||||
|
||||
$request = $this->getRequest();
|
||||
if ($request->isMethod(Request::METHOD_POST)) {
|
||||
if (null !== $preDelete) {
|
||||
$preDelete();
|
||||
}
|
||||
|
||||
$em->remove($entity);
|
||||
$em->flush();
|
||||
|
||||
return $this->renderAjax(
|
||||
'default/slide/success.html.twig',
|
||||
'default/delete.html.twig',
|
||||
[
|
||||
'message' => 'successfully deleted',
|
||||
]
|
||||
);
|
||||
} else {
|
||||
return $this->renderAjax(
|
||||
'default/slide/delete.html.twig',
|
||||
'default/delete.html.twig',
|
||||
[
|
||||
'message' => $message,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function form(FormInterface $form, string|array $title, string|null $template = "default/slide/form.html.twig"): Response
|
||||
{
|
||||
if (is_array($title)) {
|
||||
$title = implode(" ", $title);
|
||||
}
|
||||
|
||||
$context = [
|
||||
'form' => $form->createView(),
|
||||
"title" => $title
|
||||
];
|
||||
|
||||
return $this->render($template, $context);
|
||||
}
|
||||
|
||||
protected function successSlideOrRedirect(
|
||||
$redirectRoute,
|
||||
$routeParams = [],
|
||||
$message = null
|
||||
): RedirectResponse|Response
|
||||
{
|
||||
if ($this->isAjax()) {
|
||||
return $this->successSlide($message);
|
||||
} else {
|
||||
return $this->redirectToRoute($redirectRoute, $routeParams);
|
||||
}
|
||||
}
|
||||
|
||||
protected function successSlide($message = null, WidgetReloader|null $widgetReloader = null): Response
|
||||
{
|
||||
if ($widgetReloader) {
|
||||
foreach ($widgetReloader->getWidgets() as $widget) {
|
||||
$this->renderWidget($widget);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->render('default/slide/success.html.twig', [
|
||||
'message' => $message,
|
||||
'widgetReloader' => $widgetReloader
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
protected function closeSlide(WidgetReloader|null $widgetReloader = null): Response
|
||||
{
|
||||
if (!$widgetReloader) {
|
||||
$widgetReloader = new WidgetReloader();
|
||||
}
|
||||
foreach ($widgetReloader->getWidgets() as $widget) {
|
||||
$this->renderWidget($widget);
|
||||
}
|
||||
|
||||
$context = ["widgetReloader" => $widgetReloader];
|
||||
|
||||
return $this->render("default/slide/close.html.twig", $context);
|
||||
}
|
||||
|
||||
protected function errorSlide($message = null): Response
|
||||
{
|
||||
return $this->render('default/slide/error.html.twig', ['message' => $message]);
|
||||
}
|
||||
|
||||
protected function renderAjax($ajaxTemplate, $pageTemplate, $context = []): Response
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
if ($request->isXmlHttpRequest()) {
|
||||
return $this->render($ajaxTemplate, $context);
|
||||
} else {
|
||||
return $this->render($pageTemplate, $context);
|
||||
}
|
||||
}
|
||||
|
||||
protected function renderEdit($form): Response
|
||||
{
|
||||
if ($form instanceof FormInterface) {
|
||||
$form = $form->createView();
|
||||
}
|
||||
|
||||
return $this->renderAjax(
|
||||
'default/slide/edit.html.twig',
|
||||
'default/edit.html.twig',
|
||||
[
|
||||
'form' => $form,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function renderNew(
|
||||
$form,
|
||||
$title = null,
|
||||
$ajaxTemplate = 'default/slide/new.html.twig',
|
||||
$pageTemplate = 'default/new.html.twig'
|
||||
): Response
|
||||
{
|
||||
if ($form instanceof FormInterface) {
|
||||
$form = $form->createView();
|
||||
}
|
||||
|
||||
return $this->renderAjax(
|
||||
$ajaxTemplate,
|
||||
$pageTemplate,
|
||||
[
|
||||
'form' => $form,
|
||||
'title' => $title,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
protected function renderShow($showTemplate, $context = [])
|
||||
{
|
||||
|
||||
$parent = $this->isAjax() ? 'default/slide/show.html.twig' : 'base.html.twig';
|
||||
|
||||
|
||||
return $this->render($showTemplate,
|
||||
array_merge($context, [
|
||||
'parent' => $parent,
|
||||
'isSlide' => $this->isAjax()
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
protected function isAjax(): bool
|
||||
{
|
||||
return $this->getRequest()->isXmlHttpRequest();
|
||||
}
|
||||
|
||||
protected function getRequest(): Request|bool|null
|
||||
{
|
||||
try {
|
||||
return $this->container->get('request_stack')->getCurrentRequest();
|
||||
} catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerExceptionInterface
|
||||
* @throws NotFoundExceptionInterface
|
||||
*/
|
||||
protected function getEm(): ?EntityManagerInterface
|
||||
{
|
||||
return $this->container->get('em');
|
||||
}
|
||||
|
||||
public static function getSubscribedServices(): array
|
||||
{
|
||||
return array_merge(parent::getSubscribedServices(), [
|
||||
'em' => '?' . EntityManagerInterface::class,
|
||||
]);
|
||||
}
|
||||
|
||||
public function slide(
|
||||
FormInterface $form,
|
||||
string $slide,
|
||||
string $class = "",
|
||||
array $context = [],
|
||||
string|null $template = null
|
||||
): Response
|
||||
{
|
||||
$context = array_merge($context, [
|
||||
'form' => $form->createView(),
|
||||
"class" => $class,
|
||||
]);
|
||||
|
||||
return $this->render($template ?: "default/slide/$slide.html.twig", $context);
|
||||
}
|
||||
|
||||
protected function handleWidget(string|array $parameter): bool|JsonResponse
|
||||
{
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ($widget = $request->get("widget")) {
|
||||
if (is_array($parameter)) {
|
||||
$context = $parameter;
|
||||
$parameter = $parameter["parameter"];
|
||||
} else {
|
||||
$context = [$parameter => $request->attributes->get($parameter)];
|
||||
}
|
||||
|
||||
$context = array_merge($context, $request->query->all());
|
||||
|
||||
return $this->widget("{$parameter}/widgets/{$widget}.html.twig", $context);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function slideOrRender(string $regular, string $slide, array $context = []): Response
|
||||
{
|
||||
if ($this->getRequest()->isXmlHttpRequest()) {
|
||||
return $this->render($slide, $context);
|
||||
}
|
||||
|
||||
return $this->render($regular, $context);
|
||||
}
|
||||
|
||||
public function disableFilter(string $filter): void
|
||||
{
|
||||
if (!property_exists($this, "entityManager")) {
|
||||
throw new LogicException("Property \"entityManager\" does not exist in " . get_class($this));
|
||||
}
|
||||
|
||||
$filters = $this->entityManager->getFilters();
|
||||
$filters->disable($filter);
|
||||
}
|
||||
|
||||
public function enableFilter(string $filter): void
|
||||
{
|
||||
if (!property_exists($this, "entityManager")) {
|
||||
throw new LogicException("Property \"entityManager\" does not exist in " . get_class($this));
|
||||
}
|
||||
|
||||
$filters = $this->entityManager->getFilters();
|
||||
$filters->enable($filter);
|
||||
}
|
||||
|
||||
protected function repo(string $class): EntityRepository
|
||||
{
|
||||
if (!property_exists($this, "entityManager")) {
|
||||
$this->entityManager = $this->getEm();
|
||||
}
|
||||
|
||||
return $this->entityManager->getRepository($class);
|
||||
}
|
||||
|
||||
public function renderWidget(Widget $widget): Widget
|
||||
{
|
||||
$widget->setHtml($this->renderView($widget->getWidget(), $widget->getContext()));
|
||||
return $widget;
|
||||
}
|
||||
}
|
105
src/Controller/FeedController.php
Normal file
105
src/Controller/FeedController.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Fourbis\CmsBundle\Entity\Post\Post;
|
||||
use Fourbis\CmsBundle\Entity\Post\PostTranslation;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
#[Route("/{_locale}/rss")]
|
||||
class FeedController extends BaseController
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
#[Route("/get", name: "get_rss", options: ['expose' => true])]
|
||||
public function index(RequestStack $requestStack): Response
|
||||
{
|
||||
$request = $requestStack->getCurrentRequest();
|
||||
$baseUrl = $request->getSchemeAndHttpHost();
|
||||
$locale = $request->getLocale();
|
||||
$posts = $this->getAdvertisementNewsUpdates($baseUrl, $locale);
|
||||
|
||||
if (empty($posts)) {
|
||||
return new JsonResponse(['error' => 'No posts found'], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$rssFeed = $this->generateRssFeed($posts, $baseUrl, $locale, $request);
|
||||
$response = new Response($rssFeed->asXML());
|
||||
$response->headers->set('Content-Type', 'text/xml');
|
||||
return $response;
|
||||
}
|
||||
|
||||
private function getAdvertisementNewsUpdates(string $baseUrl, string $locale): array
|
||||
{
|
||||
return $this->entityManager->getRepository(Post::class)->createQueryBuilder('p')
|
||||
->select('p.uuid AS post_uuid', 'pt.uuid AS translation_uuid', 'pt.title', 'pt.description', 'p.publishedAt', 'pt.content', 'pt.url', "CONCAT(:baseUrl, '/', :locale, pt.fullUrl) AS absoluteUrl, pt.locale")
|
||||
->leftJoin('p.translations', 'pt')
|
||||
->where('pt.fullUrl LIKE :url')
|
||||
->andWhere('pt.locale = :locale')
|
||||
->setParameter('url', '%/blog/%')
|
||||
->setParameter('baseUrl', $baseUrl)
|
||||
->setParameter('locale', $locale)
|
||||
->orderBy('p.publishedAt', 'DESC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
private function generateRssFeed(array $posts, string $baseUrl, string $locale, Request $request): \SimpleXMLElement
|
||||
{
|
||||
$rssFeed = new \SimpleXMLElement("<?xml version='1.0' encoding='UTF-8'?><rss xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:media=\"http://search.yahoo.com/mrss/\" xmlns:atom=\"http://www.w3.org/2005/Atom\" version='2.0'></rss>");
|
||||
$channel = $rssFeed->addChild('channel');
|
||||
$channel->addChild('title', '4BIS Innovation Blog Articles');
|
||||
$channel->addChild('link', 'https://4bis.nl/' . $locale . '/blog');
|
||||
|
||||
$atomLink = $channel->addChild('link', '');
|
||||
$atomLink->addAttribute('href', $request->getUri());
|
||||
$atomLink->addAttribute('rel', 'self');
|
||||
$atomLink->addAttribute('type', 'application/rss+xml');
|
||||
|
||||
$channel->addChild('language', $locale);
|
||||
$currentYear = date('Y');
|
||||
$channel->addChild('copyright', "4bis.nl © $currentYear All rights reserved");
|
||||
$channel->addChild('description', '4bis.nl, software development and hosting partner | Maastricht, NL');
|
||||
|
||||
$image = $channel->addChild('image');
|
||||
$image->addChild('title', '4BIS Innovation Blog Articles');
|
||||
$image->addChild('url', 'https://cdn.4b.is/techlabs.4bis.co/cdn/4bis-nl/4bis-nl/2022-02-25/6218c42533d9b.4BIS%20Innovations_logo.png');
|
||||
$image->addChild('link', 'https://4bis.nl/' . $locale . '/');
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$item = $channel->addChild('item');
|
||||
$item->addChild('title', htmlspecialchars(strip_tags($post['title'])));
|
||||
$item->addChild('link', htmlspecialchars($post['absoluteUrl']));
|
||||
|
||||
$atomLink = $item->addChild('atom:link', '');
|
||||
$atomLink->addAttribute('href', htmlspecialchars($post['absoluteUrl']));
|
||||
$atomLink->addAttribute('rel', 'standout');
|
||||
|
||||
$item->addChild('language', $locale);
|
||||
$item->addChild('translation', $post['translation_uuid']);
|
||||
|
||||
$guid = $item->addChild('guid', $post['post_uuid']);
|
||||
$guid->addAttribute('isPermaLink', 'false');
|
||||
|
||||
$item->addChild('description', htmlspecialchars(strip_tags($post['description'])));
|
||||
$item->addChild('content:encoded', htmlspecialchars(strip_tags($post['content'])));
|
||||
|
||||
$pubDateTime = new \DateTime($post['publishedAt']->format('Y-m-d H:i:s'), new \DateTimeZone('UTC'));
|
||||
$pubDateFormatted = $pubDateTime->format('D, d M Y H:i:s O');
|
||||
$item->addChild('pubDate', $pubDateFormatted);
|
||||
}
|
||||
|
||||
return $rssFeed;
|
||||
}
|
||||
}
|
95
src/Controller/HomeController.php
Normal file
95
src/Controller/HomeController.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Fourbis\CmsBundle\Entity\Post\Post;
|
||||
use Fourbis\CmsBundle\Entity\Post\PostTranslation;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
#[Route("/{_locale}")]
|
||||
class HomeController extends BaseController
|
||||
{
|
||||
private EntityManagerInterface $entityManager;
|
||||
|
||||
public function __construct(EntityManagerInterface $entityManager)
|
||||
{
|
||||
$this->entityManager = $entityManager;
|
||||
}
|
||||
|
||||
#[Route("/", name: "home_index", options: ['expose' => true])]
|
||||
public function index(RequestStack $requestStack): Response
|
||||
{
|
||||
return $this->render('home/index.html.twig', [
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
private function getAdvertisementNewsUpdates(string $baseUrl, string $locale): array
|
||||
{
|
||||
return $this->entityManager->getRepository(Post::class)->createQueryBuilder('p')
|
||||
->select('p.uuid AS post_uuid', 'pt.uuid AS translation_uuid', 'pt.title', 'pt.description', 'p.publishedAt', 'pt.content', 'pt.url', "CONCAT(:baseUrl, '/', :locale, pt.fullUrl) AS absoluteUrl, pt.locale")
|
||||
->leftJoin('p.translations', 'pt')
|
||||
->where('pt.fullUrl LIKE :url')
|
||||
->andWhere('pt.locale = :locale')
|
||||
->setParameter('url', '%/blog/%')
|
||||
->setParameter('baseUrl', $baseUrl)
|
||||
->setParameter('locale', $locale)
|
||||
->orderBy('p.publishedAt', 'DESC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
private function generateRssFeed(array $posts, string $baseUrl, string $locale, Request $request): \SimpleXMLElement
|
||||
{
|
||||
$rssFeed = new \SimpleXMLElement("<?xml version='1.0' encoding='UTF-8'?><rss xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:media=\"http://search.yahoo.com/mrss/\" xmlns:atom=\"http://www.w3.org/2005/Atom\" version='2.0'></rss>");
|
||||
$channel = $rssFeed->addChild('channel');
|
||||
$channel->addChild('title', '4BIS Innovation Blog Articles');
|
||||
$channel->addChild('link', 'https://4bis.nl/' . $locale . '/blog');
|
||||
|
||||
$atomLink = $channel->addChild('link', '');
|
||||
$atomLink->addAttribute('href', $request->getUri());
|
||||
$atomLink->addAttribute('rel', 'self');
|
||||
$atomLink->addAttribute('type', 'application/rss+xml');
|
||||
|
||||
$channel->addChild('language', $locale);
|
||||
$currentYear = date('Y');
|
||||
$channel->addChild('copyright', "4bis.nl © $currentYear All rights reserved");
|
||||
$channel->addChild('description', '4bis.nl, software development and hosting partner | Maastricht, NL');
|
||||
|
||||
$image = $channel->addChild('image');
|
||||
$image->addChild('title', '4BIS Innovation Blog Articles');
|
||||
$image->addChild('url', 'https://cdn.4b.is/techlabs.4bis.co/cdn/4bis-nl/4bis-nl/2022-02-25/6218c42533d9b.4BIS%20Innovations_logo.png');
|
||||
$image->addChild('link', 'https://4bis.nl/' . $locale . '/');
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$item = $channel->addChild('item');
|
||||
$item->addChild('title', htmlspecialchars(strip_tags($post['title'])));
|
||||
$item->addChild('link', htmlspecialchars($post['absoluteUrl']));
|
||||
|
||||
$atomLink = $item->addChild('atom:link', '');
|
||||
$atomLink->addAttribute('href', htmlspecialchars($post['absoluteUrl']));
|
||||
$atomLink->addAttribute('rel', 'standout');
|
||||
|
||||
$item->addChild('language', $locale);
|
||||
$item->addChild('translation', $post['translation_uuid']);
|
||||
|
||||
$guid = $item->addChild('guid', $post['post_uuid']);
|
||||
$guid->addAttribute('isPermaLink', 'false');
|
||||
|
||||
$item->addChild('description', htmlspecialchars(strip_tags($post['description'])));
|
||||
$item->addChild('content:encoded', htmlspecialchars(strip_tags($post['content'])));
|
||||
|
||||
$pubDateTime = new \DateTime($post['publishedAt']->format('Y-m-d H:i:s'), new \DateTimeZone('UTC'));
|
||||
$pubDateFormatted = $pubDateTime->format('D, d M Y H:i:s O');
|
||||
$item->addChild('pubDate', $pubDateFormatted);
|
||||
}
|
||||
|
||||
return $rssFeed;
|
||||
}
|
||||
}
|
0
src/Entity/.gitignore
vendored
Normal file
0
src/Entity/.gitignore
vendored
Normal file
11
src/Kernel.php
Normal file
11
src/Kernel.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
|
||||
class Kernel extends BaseKernel
|
||||
{
|
||||
use MicroKernelTrait;
|
||||
}
|
0
src/Repository/.gitignore
vendored
Normal file
0
src/Repository/.gitignore
vendored
Normal file
301
symfony.lock
Normal file
301
symfony.lock
Normal file
@ -0,0 +1,301 @@
|
||||
{
|
||||
"doctrine/doctrine-bundle": {
|
||||
"version": "2.12",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "2.4",
|
||||
"ref": "91690c0a440faba1a3676256bcca2b4aa9f55b72"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/doctrine.yaml",
|
||||
"src/Entity/.gitignore",
|
||||
"src/Repository/.gitignore"
|
||||
]
|
||||
},
|
||||
"doctrine/doctrine-migrations-bundle": {
|
||||
"version": "3.3",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "3.1",
|
||||
"ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/doctrine_migrations.yaml",
|
||||
"migrations/.gitignore"
|
||||
]
|
||||
},
|
||||
"phpunit/phpunit": {
|
||||
"version": "9.6",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "9.6",
|
||||
"ref": "7364a21d87e658eb363c5020c072ecfdc12e2326"
|
||||
},
|
||||
"files": [
|
||||
".env.test",
|
||||
"phpunit.xml.dist",
|
||||
"tests/bootstrap.php"
|
||||
]
|
||||
},
|
||||
"symfony/console": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.3",
|
||||
"ref": "1781ff40d8a17d87cf53f8d4cf0c8346ed2bb461"
|
||||
},
|
||||
"files": [
|
||||
"bin/console"
|
||||
]
|
||||
},
|
||||
"symfony/debug-bundle": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.3",
|
||||
"ref": "5aa8aa48234c8eb6dbdd7b3cd5d791485d2cec4b"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/debug.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/flex": {
|
||||
"version": "2.4",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "146251ae39e06a95be0fe3d13c807bcf3938b172"
|
||||
},
|
||||
"files": [
|
||||
".env"
|
||||
]
|
||||
},
|
||||
"symfony/framework-bundle": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.4",
|
||||
"ref": "3cd216a4d007b78d8554d44a5b1c0a446dab24fb"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/cache.yaml",
|
||||
"config/packages/framework.yaml",
|
||||
"config/preload.php",
|
||||
"config/routes/framework.yaml",
|
||||
"config/services.yaml",
|
||||
"public/index.php",
|
||||
"src/Controller/.gitignore",
|
||||
"src/Kernel.php"
|
||||
]
|
||||
},
|
||||
"symfony/mailer": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "4.3",
|
||||
"ref": "df66ee1f226c46f01e85c29c2f7acce0596ba35a"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/mailer.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/maker-bundle": {
|
||||
"version": "1.50",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
||||
}
|
||||
},
|
||||
"symfony/messenger": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.0",
|
||||
"ref": "ba1ac4e919baba5644d31b57a3284d6ba12d52ee"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/messenger.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/monolog-bundle": {
|
||||
"version": "3.10",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "3.7",
|
||||
"ref": "aff23899c4440dd995907613c1dd709b6f59503f"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/monolog.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/notifier": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.0",
|
||||
"ref": "178877daf79d2dbd62129dd03612cb1a2cb407cc"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/notifier.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/phpunit-bridge": {
|
||||
"version": "7.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.3",
|
||||
"ref": "a411a0480041243d97382cac7984f7dce7813c08"
|
||||
},
|
||||
"files": [
|
||||
".env.test",
|
||||
"bin/phpunit",
|
||||
"phpunit.xml.dist",
|
||||
"tests/bootstrap.php"
|
||||
]
|
||||
},
|
||||
"symfony/routing": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.0",
|
||||
"ref": "eb3b377a4dc07006c4bdb2c773652cc9434f5246"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/routing.yaml",
|
||||
"config/routes.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/security-bundle": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "6.0",
|
||||
"ref": "8a5b112826f7d3d5b07027f93786ae11a1c7de48"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/security.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/stimulus-bundle": {
|
||||
"version": "2.16",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "2.8",
|
||||
"ref": "9e33a8a3794b603fb4be6c04ee5ecab901ce549e"
|
||||
}
|
||||
},
|
||||
"symfony/translation": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.3",
|
||||
"ref": "e28e27f53663cc34f0be2837aba18e3a1bef8e7b"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/translation.yaml",
|
||||
"translations/.gitignore"
|
||||
]
|
||||
},
|
||||
"symfony/twig-bundle": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.4",
|
||||
"ref": "bb2178c57eee79e6be0b297aa96fc0c0def81387"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/twig.yaml",
|
||||
"templates/base.html.twig"
|
||||
]
|
||||
},
|
||||
"symfony/ux-chartjs": {
|
||||
"version": "v2.16.0"
|
||||
},
|
||||
"symfony/ux-react": {
|
||||
"version": "2.16",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "2.8",
|
||||
"ref": "fee05066d80fef87f20023aa637f96ca8cd415c7"
|
||||
}
|
||||
},
|
||||
"symfony/validator": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.3",
|
||||
"ref": "c32cfd98f714894c4f128bb99aa2530c1227603c"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/validator.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/web-profiler-bundle": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "5.3",
|
||||
"ref": "24bbc3d84ef2f427f82104f766014e799eefcc3e"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/web_profiler.yaml",
|
||||
"config/routes/web_profiler.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/webapp-pack": {
|
||||
"version": "1.2",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.0",
|
||||
"ref": "7d5c5e282f7e2c36a2c3bbb1504f78456c352407"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/messenger.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/webpack-encore-bundle": {
|
||||
"version": "1.17",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "1.10",
|
||||
"ref": "eff2e505d4557c967b6710fe06bd947ba555cae5"
|
||||
},
|
||||
"files": [
|
||||
"assets/app.js",
|
||||
"assets/bootstrap.js",
|
||||
"assets/controllers.json",
|
||||
"assets/controllers/hello_controller.js",
|
||||
"assets/styles/app.css",
|
||||
"config/packages/webpack_encore.yaml",
|
||||
"package.json",
|
||||
"webpack.config.js"
|
||||
]
|
||||
},
|
||||
"twig/extra-bundle": {
|
||||
"version": "v3.8.0"
|
||||
}
|
||||
}
|
38
templates/base.html.twig
Normal file
38
templates/base.html.twig
Normal file
@ -0,0 +1,38 @@
|
||||
{% extends "layout.html.twig" %}
|
||||
|
||||
{% block page_title %}{% block title %}{% endblock %}{% endblock page_title %}
|
||||
|
||||
|
||||
{% block head_description %}
|
||||
{% endblock %}
|
||||
|
||||
{% block gtm_head_part %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block gtm_body_part %}
|
||||
{% endblock %}
|
||||
|
||||
{% block navbar %}
|
||||
{% endblock %}
|
||||
|
||||
{% block default_head_javascripts %}
|
||||
{{ encore_entry_script_tags('app') }}
|
||||
{% endblock default_head_javascripts %}
|
||||
|
||||
{% block head_javascripts %}
|
||||
{% endblock head_javascripts %}
|
||||
|
||||
{% block stylesheets %}
|
||||
{{ encore_entry_link_tags('app') }}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block above_footer %}
|
||||
<!-- above footer -->
|
||||
<!-- end above footer -->
|
||||
{% endblock %}
|
||||
{% block footer_content %}
|
||||
{% endblock %}
|
9
templates/home/index.html.twig
Normal file
9
templates/home/index.html.twig
Normal file
@ -0,0 +1,9 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
{% block main_content %}
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
Test
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock main_content %}
|
69
templates/layout.html.twig
Normal file
69
templates/layout.html.twig
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{% block page_title %}{% endblock page_title %}</title>
|
||||
{% block meta %}
|
||||
<link rel="shortcut icon" href="">
|
||||
<link rel="icon" type="image/x-icon" href="">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0">
|
||||
{% if block('head_description') %}
|
||||
<meta name="description" content="{% block head_description %}{% endblock %}" >
|
||||
{% endif %}
|
||||
<meta name="keywords" content="Technology news, Tech trends, Innovation updates, Gadgets, Tech analysis, Emerging technologies, Digital advancements, Latest News"/>
|
||||
{% endblock meta %}
|
||||
{% block meta_robots %}
|
||||
<meta name="robots" content="index,follow"/>
|
||||
{% endblock meta_robots %}
|
||||
|
||||
{% block stylesheets %}{% endblock stylesheets %}
|
||||
|
||||
{% block default_head_javascripts %}{% endblock default_head_javascripts %}
|
||||
{% block head_javascripts %}{% endblock head_javascripts %}
|
||||
|
||||
{% block gtm_head_part %}{% endblock gtm_head_part %}
|
||||
</head>
|
||||
|
||||
|
||||
{% block body %}
|
||||
<body id="page-top" class="{% block body_class %}{% endblock %}">
|
||||
{% block gtm_body_part %}{% endblock %}
|
||||
{% block nav %}
|
||||
{% block navbar %}{% endblock %}
|
||||
{% endblock %}
|
||||
{% block page_wrapper %}
|
||||
<div id="wrapper">
|
||||
{% block page_wrapper_content %}
|
||||
{% block content_wrapper %}
|
||||
<!-- Content Wrapper -->
|
||||
<div id="content-wrapper" class="d-flex flex-column">
|
||||
{% block content_wrapper_content %}
|
||||
<!-- Main Content -->
|
||||
{% block content_breadcrumbs %}{% endblock %}
|
||||
{% block main_content_body %}
|
||||
{% block main_content_title %}{% endblock main_content_title %}
|
||||
{% block main_content %}{% endblock main_content %}
|
||||
{% endblock %}
|
||||
|
||||
<!-- End of Main Content -->
|
||||
{% endblock content_wrapper_content %}
|
||||
</div>
|
||||
<!-- End of Content Wrapper -->
|
||||
{% endblock content_wrapper %}
|
||||
{% endblock page_wrapper_content %}
|
||||
</div>
|
||||
{% endblock page_wrapper %}
|
||||
<!-- bottom footer -->
|
||||
{% block above_footer %}{% endblock %}
|
||||
|
||||
{% block footer_wrapper %}
|
||||
{% block footer_content %}{% endblock footer_content %}
|
||||
{% endblock footer_wrapper %}
|
||||
<!-- /bottom footer -->
|
||||
{% block default_footer_javascripts %}{% endblock default_footer_javascripts %}
|
||||
{% block footer_javascripts %}{% endblock footer_javascripts %}
|
||||
</body>
|
||||
{% endblock body %}
|
||||
</html>
|
11
tests/bootstrap.php
Normal file
11
tests/bootstrap.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
require dirname(__DIR__).'/vendor/autoload.php';
|
||||
|
||||
if (file_exists(dirname(__DIR__).'/config/bootstrap.php')) {
|
||||
require dirname(__DIR__).'/config/bootstrap.php';
|
||||
} elseif (method_exists(Dotenv::class, 'bootEnv')) {
|
||||
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
|
||||
}
|
0
translations/.gitignore
vendored
Normal file
0
translations/.gitignore
vendored
Normal file
75
webpack.config.js
Normal file
75
webpack.config.js
Normal file
@ -0,0 +1,75 @@
|
||||
const Encore = require('@symfony/webpack-encore');
|
||||
|
||||
// Manually configure the runtime environment if not already configured yet by the "encore" command.
|
||||
// It's useful when you use tools that rely on webpack.config.js file.
|
||||
if (!Encore.isRuntimeEnvironmentConfigured()) {
|
||||
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
|
||||
}
|
||||
|
||||
Encore
|
||||
// directory where compiled assets will be stored
|
||||
.setOutputPath('public/build/')
|
||||
// public path used by the web server to access the output path
|
||||
.setPublicPath('/build')
|
||||
// only needed for CDN's or sub-directory deploy
|
||||
//.setManifestKeyPrefix('build/')
|
||||
|
||||
/*
|
||||
* ENTRY CONFIG
|
||||
*
|
||||
* Each entry will result in one JavaScript file (e.g. app.js)
|
||||
* and one CSS file (e.g. app.css) if your JavaScript imports CSS.
|
||||
*/
|
||||
.addEntry('app', './assets/app.js')
|
||||
|
||||
// enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js)
|
||||
.enableStimulusBridge('./assets/controllers.json')
|
||||
|
||||
// When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
|
||||
.splitEntryChunks()
|
||||
|
||||
// will require an extra script tag for runtime.js
|
||||
// but, you probably want this, unless you're building a single-page app
|
||||
.enableSingleRuntimeChunk()
|
||||
|
||||
/*
|
||||
* FEATURE CONFIG
|
||||
*
|
||||
* Enable & configure other features below. For a full
|
||||
* list of features, see:
|
||||
* https://symfony.com/doc/current/frontend.html#adding-more-features
|
||||
*/
|
||||
.cleanupOutputBeforeBuild()
|
||||
.enableBuildNotifications()
|
||||
.enableSourceMaps(!Encore.isProduction())
|
||||
// enables hashed filenames (e.g. app.abc123.css)
|
||||
.enableVersioning(Encore.isProduction())
|
||||
|
||||
.configureBabel((config) => {
|
||||
config.plugins.push('@babel/plugin-proposal-class-properties');
|
||||
})
|
||||
|
||||
// enables @babel/preset-env polyfills
|
||||
.configureBabelPresetEnv((config) => {
|
||||
config.useBuiltIns = 'usage';
|
||||
config.corejs = 3;
|
||||
})
|
||||
|
||||
// enables Sass/SCSS support
|
||||
.enableSassLoader()
|
||||
|
||||
// uncomment if you use TypeScript
|
||||
//.enableTypeScriptLoader()
|
||||
|
||||
// uncomment if you use React
|
||||
.enableReactPreset()
|
||||
|
||||
// uncomment to get integrity="..." attributes on your script & link tags
|
||||
// requires WebpackEncoreBundle 1.4 or higher
|
||||
//.enableIntegrityHashes(Encore.isProduction())
|
||||
|
||||
// uncomment if you're having problems with a jQuery plugin
|
||||
//.autoProvidejQuery()
|
||||
;
|
||||
|
||||
module.exports = Encore.getWebpackConfig();
|
Loading…
x
Reference in New Issue
Block a user