diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 3cc5119..da2f081 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -1,7 +1,16 @@ language: "en-US" +tone_instructions: "chill" reviews: profile: "chill" high_level_summary: true + collapse_walkthrough: true + suggested_labels: false + high_level_summary_in_walkthrough: false + changed_files_summary: false + poem: false + finishing_touches: + docstrings: + enabled: false auto_review: enabled: true base_branches: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b4c9b3f..1bb015d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,5 @@ +@coderabbitai summary + ### Summary Provide a general description of the code changes in your pull request โ€ฆ diff --git a/.husky/pre-commit b/.husky/pre-commit index 73d8277..bb5f8a8 100644 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,11 +1,11 @@ #!/bin/sh . "$(dirname "$0")/_/husky.sh" -#echo "๐Ÿ” Running PHPStan..." -#php vendor/bin/phpstan analyse -l 5 src/ tests/ || exit 1 -# -#echo "๐Ÿ“ Running PHPMD..." -#php vendor/bin/phpmd src/ text vendor/phplist/core/config/PHPMD/rules.xml || exit 1 -# -#echo "๐Ÿงน Running PHPCS..." -#php vendor/bin/phpcs --standard=vendor/phplist/core/config/PhpCodeSniffer/ src/ tests/ || exit 1 +echo "๐Ÿ” Running PHPStan..." +php vendor/bin/phpstan analyse -l 5 src/ tests/ || exit 1 + +echo "๐Ÿ“ Running PHPMD..." +php vendor/bin/phpmd src/ text vendor/phplist/core/config/PHPMD/rules.xml || exit 1 + +echo "๐Ÿงน Running PHPCS..." +php vendor/bin/phpcs --standard=vendor/phplist/core/config/PhpCodeSniffer/ src/ tests/ || exit 1 diff --git a/apache/web-frontend.conf b/apache/web-frontend.conf new file mode 100644 index 0000000..775f35d --- /dev/null +++ b/apache/web-frontend.conf @@ -0,0 +1,26 @@ + + ServerName frontend.phplist.local + ServerAdmin webmaster@localhost + + DocumentRoot /{pathToTheProject}/web-frontend/public + + ErrorLog ${APACHE_LOG_DIR}/web-frontend-error.log + CustomLog ${APACHE_LOG_DIR}/web-frontend-access.log combined + + + Options FollowSymLinks + AllowOverride All + Require all granted + DirectoryIndex app.php + + + + Require all denied + + + + + SetHandler "proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost" + + + diff --git a/assets/app.js b/assets/app.js index 385fa94..7d3fec5 100644 --- a/assets/app.js +++ b/assets/app.js @@ -1,12 +1,13 @@ -console.log('app.js loaded'); +import './styles/app.css'; import { createApp } from 'vue'; import App from './vue/App.vue'; import { router } from './router'; const appElement = document.getElementById('vue-app'); + if (appElement) { const app = createApp(App); app.use(router); - app.mount('#vue-app'); + app.mount(appElement); } diff --git a/assets/images/avatar.jpg b/assets/images/avatar.jpg new file mode 100644 index 0000000..e051a3b Binary files /dev/null and b/assets/images/avatar.jpg differ diff --git a/assets/router/index.js b/assets/router/index.js index 328ab06..526b664 100644 --- a/assets/router/index.js +++ b/assets/router/index.js @@ -1,6 +1,18 @@ import { createRouter, createWebHistory } from 'vue-router'; +import DashboardView from '../vue/views/DashboardView.vue' +import SubscribersView from '../vue/views/SubscribersView.vue' export const router = createRouter({ history: createWebHistory(), - routes: [ /* ... */ ], + routes: [ + { path: '/', name: 'dashboard', component: DashboardView, meta: { title: 'Dashboard' } }, + { path: '/subscribers', name: 'subscribers', component: SubscribersView, meta: { title: 'Subscribers' } }, + { path: '/:pathMatch(.*)*', redirect: '/' }, + ], +}); + +router.afterEach((to) => { + const defaultTitle = 'phpList'; + const pageTitle = to.meta.title; + document.title = pageTitle ? `${defaultTitle} - ${pageTitle}` : defaultTitle; }); diff --git a/assets/styles/app.css b/assets/styles/app.css new file mode 100644 index 0000000..540b446 --- /dev/null +++ b/assets/styles/app.css @@ -0,0 +1,16 @@ +@import "tailwindcss"; +@tailwind utilities; + +@theme { + --color-primary: #2563eb; + --color-secondary: #6b7280; + --color-success: #16a34a; + --color-danger: #dc2626; + --color-info: #0891b2; + --color-ext-wf1: #543ff6; /** indigo-500 **/ + --color-ext-wf2: #eef2ff; /** indigo-50 **/ + --color-ext-wf3: #303F9F; /** indigo-700 **/ +} + +@source "../../templates/**/*.twig"; +@source "../**/*.vue"; diff --git a/assets/vue/App.vue b/assets/vue/App.vue index 170881d..e38be10 100644 --- a/assets/vue/App.vue +++ b/assets/vue/App.vue @@ -1,52 +1,13 @@ diff --git a/assets/vue/AppSidebar.vue b/assets/vue/AppSidebar.vue deleted file mode 100644 index 9b0dc2f..0000000 --- a/assets/vue/AppSidebar.vue +++ /dev/null @@ -1,52 +0,0 @@ - - - diff --git a/assets/vue/BaseCard.vue b/assets/vue/BaseCard.vue deleted file mode 100644 index 3203c2b..0000000 --- a/assets/vue/BaseCard.vue +++ /dev/null @@ -1,14 +0,0 @@ - - - diff --git a/assets/vue/CampaignsTable.vue b/assets/vue/CampaignsTable.vue deleted file mode 100644 index b0984b2..0000000 --- a/assets/vue/CampaignsTable.vue +++ /dev/null @@ -1,136 +0,0 @@ - - - - - diff --git a/assets/vue/DashboardView.vue b/assets/vue/DashboardView.vue deleted file mode 100644 index c78de13..0000000 --- a/assets/vue/DashboardView.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/assets/vue/PerformanceChartCard.vue b/assets/vue/PerformanceChartCard.vue deleted file mode 100644 index 4ff4a2e..0000000 --- a/assets/vue/PerformanceChartCard.vue +++ /dev/null @@ -1,19 +0,0 @@ - - - diff --git a/assets/vue/RecentCampaignsCard.vue b/assets/vue/RecentCampaignsCard.vue deleted file mode 100644 index 7424df9..0000000 --- a/assets/vue/RecentCampaignsCard.vue +++ /dev/null @@ -1,27 +0,0 @@ - - - - diff --git a/assets/vue/SidebarLogo.vue b/assets/vue/SidebarLogo.vue deleted file mode 100644 index d196522..0000000 --- a/assets/vue/SidebarLogo.vue +++ /dev/null @@ -1,80 +0,0 @@ - - - - - diff --git a/assets/vue/SidebarNavItem.vue b/assets/vue/SidebarNavItem.vue deleted file mode 100644 index 246c3a0..0000000 --- a/assets/vue/SidebarNavItem.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - diff --git a/assets/vue/SidebarNavSection.vue b/assets/vue/SidebarNavSection.vue deleted file mode 100644 index bc6c472..0000000 --- a/assets/vue/SidebarNavSection.vue +++ /dev/null @@ -1,22 +0,0 @@ - - - diff --git a/assets/vue/SystemOverviewCard.vue b/assets/vue/SystemOverviewCard.vue deleted file mode 100644 index db3a872..0000000 --- a/assets/vue/SystemOverviewCard.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - diff --git a/assets/vue/api.js b/assets/vue/api.js new file mode 100644 index 0000000..b61c721 --- /dev/null +++ b/assets/vue/api.js @@ -0,0 +1,18 @@ +import { Client, SubscribersClient } from '@tatevikgr/rest-api-client'; + +const appElement = document.getElementById('vue-app'); +const apiToken = appElement?.dataset.apiToken; +const apiBaseUrl = appElement?.dataset.apiBaseUrl; + +if (!apiBaseUrl) { + console.error('API Base URL is not configured.'); +} + +const client = new Client(apiBaseUrl || ''); + +if (apiToken) { + client.setSessionId(apiToken); +} + +export const subscribersClient = new SubscribersClient(client); +export default client; diff --git a/assets/vue/components/base/BaseBadge.vue b/assets/vue/components/base/BaseBadge.vue index 2cb2fb1..217fd1b 100644 --- a/assets/vue/components/base/BaseBadge.vue +++ b/assets/vue/components/base/BaseBadge.vue @@ -1,36 +1,28 @@ - - +const badgeClass = computed(() => { + const base = 'inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium'; + switch (props.variant) { + case 'counter': + return `${base} bg-indigo-50 text-ext-wf3 border border-indigo-100`; + case 'neutral': + default: + return `${base} bg-gray-100 text-gray-800`; + } +}) + diff --git a/assets/vue/components/base/BaseButton.vue b/assets/vue/components/base/BaseButton.vue index 0fd51bd..aaeb2e8 100644 --- a/assets/vue/components/base/BaseButton.vue +++ b/assets/vue/components/base/BaseButton.vue @@ -1,8 +1,7 @@ - - diff --git a/assets/vue/components/base/BaseCard.vue b/assets/vue/components/base/BaseCard.vue index 6708c8d..2278c74 100644 --- a/assets/vue/components/base/BaseCard.vue +++ b/assets/vue/components/base/BaseCard.vue @@ -1,30 +1,34 @@ - - + +const cardClasses = cardVariantMap[props.variant] || cardVariantMap.default +const bodyClasses = bodyVariantMap[props.variant] || bodyVariantMap.default + diff --git a/assets/vue/components/base/BaseIcon.vue b/assets/vue/components/base/BaseIcon.vue index c0296b1..c427505 100644 --- a/assets/vue/components/base/BaseIcon.vue +++ b/assets/vue/components/base/BaseIcon.vue @@ -1,29 +1,46 @@ - +const wrapperClass = computed(() => { + const classes = [ + "inline-flex", + "items-center", + "justify-center", + "transition-colors", + ]; + + if (props.active) { + classes.push("text-ext-wf3"); + } else { + classes.push("text-slate-400 group-hover:text-slate-600"); + } + + return classes.join(" "); +}); + diff --git a/assets/vue/components/base/BaseProgressBar.vue b/assets/vue/components/base/BaseProgressBar.vue index 10ccf14..91ac7a7 100644 --- a/assets/vue/components/base/BaseProgressBar.vue +++ b/assets/vue/components/base/BaseProgressBar.vue @@ -1,9 +1,13 @@ @@ -14,22 +18,13 @@ const props = defineProps({ type: Number, default: 0, }, + height: { + type: String, + default: "6px", // allows easy overrides: "4px", "10px", etc. + }, }) - - + diff --git a/assets/vue/components/charts/LineChart.vue b/assets/vue/components/charts/LineChart.vue index c356af3..9ce7870 100644 --- a/assets/vue/components/charts/LineChart.vue +++ b/assets/vue/components/charts/LineChart.vue @@ -1,8 +1,9 @@