akaunting 3.0 (the last dance)

This commit is contained in:
Burak Civan
2022-06-01 10:15:55 +03:00
parent cead09f6d4
commit d9c0764572
3812 changed files with 126831 additions and 102949 deletions

View File

@ -0,0 +1,15 @@
@stack('content_start')
<div id="app">
@stack('content_content_start')
{!! $slot !!}
@stack('content_content_end')
<notifications></notifications>
<form id="form-dynamic-component" method="POST" action="#"></form>
<component v-bind:is="component"></component>
</div>
@stack('content_end')

View File

@ -0,0 +1,12 @@
@stack('footer_start')
<footer class="footer">
<div class="flex flex-col sm:flex-row items-center justify-between mt-10 lg:mt-20 py-7 text-sm font-light">
<div>
{{ trans('footer.powered') }}:
<a href="{{ trans('footer.link') }}" target="_blank">{{ trans('footer.software') }}</a>
&nbsp;<span class="material-icons align-middle text-black-300">code</span>&nbsp;
{{ trans('footer.version') }} {{ version('short') }}
</div>
</div>
</footer>
@stack('footer_end')

View File

@ -0,0 +1,61 @@
@props([
'metaTitle', 'title',
])
<head>
@stack('head_start')
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8; charset=ISO-8859-1"/>
<title>{!! ! empty($metaTitle) ? $metaTitle : $title !!} - @setting('company.name')</title>
<base href="{{ config('app.url') . '/' }}">
<x-layouts.pwa.head />
<!-- Favicon -->
<link rel="icon" href="{{ asset('public/img/favicon.ico') }}" type="image/png">
<!--Icons-->
<link rel="stylesheet" href="{{ asset('public/css/fonts/material-icons/style.css?v=' . version('short')) }}" type="text/css">
<!-- Font -->
<link rel="stylesheet" href="{{ asset('public/vendor/quicksand/css/quicksand.css?v=' . version('short')) }}" type="text/css">
<!-- Css -->
<link rel="stylesheet" href="{{ asset('public/css//third_party/swiper-bundle.min.css?v=' . version('short')) }}" type="text/css">
<link rel="stylesheet" href="{{ asset('public/css//third_party/vue-html-editor.css?v=' . version('short')) }}" type="text/css">
<link rel="stylesheet" href="{{ asset('public/css/element.css?v=' . version('short')) }}" type="text/css">
<link rel="stylesheet" href="{{ asset('public/css/app.css') }}" type="text/css">
@stack('css')
@stack('stylesheet')
@livewireStyles
<script type="text/javascript"><!--
var url = '{{ url("/" . company_id()) }}';
var app_url = '{{ config("app.url") }}';
var aka_currency = {!! !empty($currency) ? $currency : 'false' !!};
//--></script>
@stack('js')
<script type="text/javascript"><!--
window.Laravel = <?php echo json_encode([
'csrfToken' => csrf_token(),
]); ?>;
var flash_notification = {!! (session()->has('flash_notification')) ? json_encode(session()->get('flash_notification')) : 'false' !!};
//--></script>
{{ session()->forget('flash_notification') }}
@stack('scripts')
@stack('head_end')
</head>

View File

@ -0,0 +1,37 @@
@stack('header_start')
<div id="header" class="xl:pt-6">
<div class="flex flex-col sm:flex-row flex-wrap items-start justify-between hide-empty-page">
<div class="w-full sm:w-6/12 items-center mb-3 sm:mb-0">
<div class="flex items-center">
<h1 class="flex items-center text-2xl xl:text-5xl text-black font-light -ml-0.5">
{!! $title !!}
@yield('dashboard_action')
</h1>
{!! $status ?? '' !!}
{!! $favorite ?? '' !!}
</div>
</div>
<div class="w-full sm:w-6/12">
<div class="flex flex-wrap flex-col sm:flex-row sm:items-center justify-end sm:space-x-2 sm:rtl:space-x-reverse">
@stack('header_button_start')
{!! $buttons !!}
@stack('header_button_end')
<x-suggestions />
@stack('header_suggestion_end')
{!! $moreButtons !!}
</div>
</div>
</div>
</div>
@stack('header_end')

View File

@ -0,0 +1,231 @@
@props(['companies'])
<div class="container flex items-center py-3 mb-4 border-b-2 xl:hidden">
<span class="material-icons text-black js-hamburger-menu">menu</span>
<div class="flex items-center m-auto">
<img src="{{ asset('public/img/akaunting-logo-green.svg') }}" class="w-8 m-auto" alt="Akaunting" />
<span class="ltr:ml-2 rtl:mr-2">{{ Str::limit(setting('company.name'), 22) }}</span>
</div>
@can('create-banking-transactions')
<x-dropdown id="dropdown-mobile-actions">
<x-slot name="trigger">
<span class="material-icons">more_horiz</span>
</x-slot>
<x-dropdown.link href="{{ route('transactions.create', ['type' => 'income']) }}">
{{ trans('general.title.new', ['type' => trans_choice('general.incomes', 1)]) }}
</x-dropdown.link>
<x-dropdown.link href="{{ route('transactions.create', ['type' => 'expense']) }}" kind="primary">
{{ trans('general.title.new', ['type' => trans_choice('general.expenses', 1)]) }}
</x-dropdown.link>
</x-dropdown>
@endcan
</div>
@stack('menu_start')
<div data-real-menu class="w-70 h-screen flex hidden fixed top-0 js-menu z-20 xl:z-10 transition-all ltr:-left-80 rtl:-right-80 xl:ltr:left-0 xl:rtl:right-0">
<div class="w-14 py-7 px-1 bg-lilac-900 z-10 menu-scroll overflow-y-auto overflow-x-hidden">
<div
data-tooltip-target="tooltip-profile"
data-tooltip-placement="right"
class="flex flex-col items-center justify-center mb-5 cursor-pointer menu-button"
data-menu="profile-menu"
>
<span id="menu-profile-icon-cancel" name="account_circle" class="material-icons-outlined w-8 h-8 flex items-center justify-center text-purple text-2xl hidden">
account_circle
</span>
@if (setting('default.use_gravatar', '0') == '1')
<img src="{{ user()->picture }}" alt="{{ user()->name }}" class="w-8 h-8 m-auto rounded-full" alt="{{ user()->name }}" title="{{ user()->name }}">
@elseif (is_object(user()->picture))
<img src="{{ Storage::url(user()->picture->id) }}" class="w-8 h-8 m-auto rounded-full" alt="{{ user()->name }}" title="{{ user()->name }}">
@else
<span id="menu-profile-icon" name="account_circle" class="material-icons-outlined text-purple w-8 h-8 flex items-center justify-center text-center text-2xl" alt="{{ user()->name }}" title="{{ user()->name }}">
account_circle
</span>
@endif
</div>
<div id="tooltip-profile" class="inline-block absolute z-20 py-1 px-2 text-sm font-medium rounded-lg bg-white text-gray-900 w-auto border border-gray-200 shadow-sm whitespace-nowrap tooltip-content opacity-0 invisible">
{{ trans('auth.profile') }}
<div class="absolute w-2 h-2 before:absolute before:w-2 before:h-2 before:bg-white before:border-gray-200 before:transform before:rotate-45 before:border -left-1 before:border-t-0 before:border-r-0 border-gray-200" data-popper-arrow></div>
</div>
<div class="group flex flex-col items-center justify-center menu-toggle-buttons">
@can('read-notifications')
<x-tooltip id="tooltip-notifications" placement="right" message="{{ trans_choice('general.notifications', 2) }}">
<button type="button"
@class([
'flex items-center menu-button justify-center w-8 h-8 mb-2.5 relative cursor-pointer js-menu-toggles',
'animate-vibrate' => $notification_count,
])
data-menu="notifications-menu">
<span id="menu-notification-icon" name="notifications" class="material-icons-outlined text-purple text-2xl">notifications</span>
@if ($notification_count)
<span data-notification-count class="w-2 h-2 absolute top-2 right-2 inline-flex items-center justify-center p-2.5 text-xs text-white font-bold leading-none transform translate-x-1/2 -translate-y-1/2 bg-orange rounded-full">
{{ $notification_count }}
</span>
@endif
</button>
</x-tooltip>
@endcan
<x-tooltip id="tooltip-search" placement="right" message="{{ trans('general.search') }}">
<button type="button" class="flex items-center menu-button justify-center w-8 h-8 mb-2.5 relative cursor-pointer">
<span id="menu-search-icon" name="search" class="material-icons-outlined text-purple text-2xl">search</span>
</button>
</x-tooltip>
<x-tooltip id="tooltip-new" placement="right" message="{{ trans('general.new') }}">
<button type="button" class="add-item menu-button flex items-center justify-center w-8 h-8 mb-2.5 cursor-pointer js-menu-toggles" data-menu="add-new-menu">
<span id="menu-neww-icon" name="add_circle_outline" class="material-icons-outlined text-purple text-2xl">add_circle_outline</span>
</button>
</x-tooltip>
<x-tooltip id="tooltip-settings" placement="right" message="{{ trans_choice('general.settings', 2) }}">
<button type="button" class="settings-item menu-button flex items-center justify-center w-8 h-8 mb-2.5 cursor-pointer js-menu-toggles" data-menu="settings-menu">
<span id="menu-settings-icon" name="settings" class="material-icons-outlined text-purple text-2xl">settings</span>
</button>
</x-tooltip>
<x-tooltip id="tooltip-support" placement="right" message="{{ trans('general.help') }}">
<a href="{{ url(trans('header.support_link')) }}" target="_blank" class="flex items-center justify-center w-8 h-8 mb-2.5 cursor-pointer js-menu-toggles">
<span id="menu-support-icon" class="material-icons-outlined text-purple text-2xl">support</span>
</a>
</x-tooltip>
</div>
<livewire:menu.favorites />
</div>
<nav class="menu-list js-main-menu" id="sidenav-main">
<div class="relative mb-5 cursor-pointer">
<button type="button" class="flex items-center" data-dropdown-toggle="dropdown-menu-company">
<div class="w-8 h-8 flex items-center justify-center">
<img src="{{ asset('public/img/akaunting-logo-green.svg') }}" class="w-6 h-6" alt="Akaunting" />
</div>
<div class="flex ltr:ml-2 rtl:mr-2">
<span class="w-28 text-left block text-base truncate">
<span class="border-b border-transparent transition-all hover:border-black">
{{ Str::limit(setting('company.name'), 22) }}
</span>
</span>
@can('read-common-companies')
<div class="absolute top-2 ltr:-right-1 rtl:-left-1">
<svg class="h-5 w-5 text-gray-400" x-description="Heroicon name: solid/selector" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd"></path>
</svg>
</div>
@endcan
</div>
</button>
@can('read-common-companies')
<div id="dropdown-menu-company" class="absolute right-0 mt-3 pt-2 bg-white rounded-md shadow-xl z-20 hidden" style="left: auto; min-width: 10rem;">
@foreach($companies as $com)
<a href="{{ route('companies.switch', $com->id) }}" id="$com->id" class="h-9 leading-9 flex items-center text-sm px-2" role="menuitem" tabindex="-1">
<div class="w-full h-full flex items-center rounded-md px-2 hover:bg-lilac-100">
<span class="material-icons-outlined text-purple text-xl">business</span>
<span class="ltr:pl-2 rtl:pr-2 text-purple text-xs truncate">{{ Str::limit($com->name, 18) }}</span>
</div>
</a>
@endforeach
@can('update-common-companies')
<a href="{{ route('companies.index') }}" class="h-9 leading-9 flex items-center text-sm px-2 mt-2 border-t rounded-bl rounded-br group hover:bg-purple">
<div class="w-full h-full flex items-center rounded-md px-2">
<span class="material-icons-outlined text-purple text-xl group-hover:text-white">settings</span>
<span class="ltr:pl-2 rtl:pr-2 text-purple text-xs truncate group-hover:text-white">
{{ trans('general.title.manage', ['type' => trans_choice('general.companies', 2)]) }}
</span>
</div>
</a>
@endcan
</div>
@endcan
</div>
<div class="main-menu transform">
{!! menu('admin') !!}
</div>
</nav>
<div class="profile-menu user-menu menu-list fixed h-full ltr:-left-80 rtl:-right-80">
<div class="flex h-12.5">
@if (setting('default.use_gravatar', '0') == '1')
<img src="{{ user()->picture }}" alt="{{ user()->name }}" class="w-8 h-8 rounded-full" alt="{{ user()->name }}" title="{{ user()->name }}">
@elseif (is_object(user()->picture))
<img src="{{ Storage::url(user()->picture->id) }}" class="w-8 h-8 rounded-full" alt="{{ user()->name }}" title="{{ user()->name }}">
@else
<span name="account_circle" class="material-icons-outlined w-8 h-8 flex items-center justify-center text-purple text-2xl" alt="{{ user()->name }}" title="{{ user()->name }}">account_circle</span>
@endif
@stack('navbar_profile_welcome')
<div class="flex flex-col text-black ml-2">
<span class="text-xs">{{ trans('general.welcome') }}</span>
{{ user()->name }}
</div>
</div>
<livewire:menu.profile />
</div>
@can('read-notifications')
<div class="notifications-menu user-menu menu-list fixed h-full ltr:-left-80 rtl:-right-80">
<div class="flex items-center mb-3">
<span name="notifications" class="material-icons-outlined w-8 h-8 flex items-center justify-center text-purple text-2xl">notifications</span>
<div class="text-black ltr:ml-1 rtl:mr-1">
{{ trans_choice('general.your_notifications', 2) }}
</div>
</div>
<livewire:menu.notifications />
</div>
@endcan
<div class="settings-menu user-menu menu-list fixed h-full overflow-y-unset ltr:-left-80 rtl:-right-80">
<div class="flex items-center mb-3">
<span name="settings" class="material-icons-outlined w-8 h-8 flex items-center justify-center text-purple text-2xl">settings</span>
<div class="text-black ltr:ml-1 rtl:mr-1">
{{ trans_choice('general.settings', 2) }}
</div>
</div>
<livewire:menu.settings />
</div>
<div class="add-new-menu user-menu menu-list fixed h-full ltr:-left-80 rtl:-right-80">
<div class="flex items-center mb-3">
<span name="add_circle_outline" class="material-icons-outlined w-8 h-8 flex items-center justify-center text-purple text-2xl">add_circle_outline</span>
<div class="text-black ltr:ml-1 rtl:mr-1">
{{ trans('general.new_more') }}
</div>
</div>
<livewire:menu.neww />
</div>
<button type="button" class="toggle-button absolute ltr:-right-2 rtl:-left-2 top-8 cursor-pointer transition-opacity ease-in-out z-50">
<span class="material-icons text-lg text-purple transform ltr:rotate-90 rtl:-rotate-90">expand_circle_down</span>
</button>
<span data-menu-close id="menu-cancel" class="material-icons absolute ltr:-right-2 rtl:right-12 top-8 text-lg text-purple cursor-pointer z-10 hidden">cancel</span>
<div class="fixed w-full h-full invisible lg:hidden js-menu-background" style="background-color: rgba(0, 0, 0, 0.5); z-index: -1;"></div>
</div>
<x-loading.menu />
@stack('menu_end')

View File

@ -0,0 +1,3 @@
@foreach ($notifications as $notification)
{!! $notification !!}
@endforeach

View File

@ -0,0 +1,256 @@
<!-- Core -->
<script src="{{ asset('public/vendor/js-cookie/js.cookie.js') }}"></script>
<script type="text/javascript">
var company_currency_code = '{{ setting("default.currency") }}';
</script>
@stack('scripts_start')
@apexchartsScripts
@stack('charts')
<!-- <script type="text/javascript" src="{{ asset('public/akaunting-js/hotkeys.js') }}" defer></script> -->
<script type="text/javascript" src="{{ asset('public/akaunting-js/generalAction.js') }}"></script>
<script type="text/javascript" src="{{ asset('public/akaunting-js/popper.js') }}"></script>
<script type="text/javascript">
"use strict";
var Layout = (function() {
const toggleButton = document.querySelector(".toggle-button");
const sideBar = document.querySelector(".js-main-menu");
const navbarMenu = document.querySelector(".js-menu");
const mainContent = document.querySelector(".main-menu");
const menus = document.querySelectorAll(".user-menu");
const menuButtons = document.querySelectorAll(".menu-button");
const detailsEL = mainContent.getElementsByTagName("details");
const sectionContent = document.querySelector(".main-content");
const menuBackground = document.querySelector(".js-menu-background");
const menuClose = document.querySelector("[data-menu-close]");
if (document.querySelector('[data-menu="notifications-menu"]')) {
setTimeout(function() {
document.querySelector('[data-menu="notifications-menu"]').classList.remove("animate-vibrate");
}, 6000);
}
Array.from(detailsEL).forEach((el) => {
el.addEventListener("toggle", function(e) {
if (e.target.querySelector(".material-icons-outlined")) {
e.target.querySelector(".material-icons").classList.toggle("rotate-180");
} else {
if (e.target.querySelectorAll(".material-icons")[1]) {
e.target.querySelectorAll(".material-icons")[1].classList.toggle("rotate-180");
} else {
e.target.querySelectorAll(".material-icons")[0].classList.toggle("rotate-180");
}
}
})
}
);
function contentTransitionLeft() {
sectionContent.classList.add("xl:ltr:ml-0", "xl:rtl:mr-0");
sectionContent.classList.remove("xl:ltr:ml-64", "xl:rtl:mr-64");
toggleButton.querySelector("span").classList.add("ltr:-rotate-90", "rtl:rotate-90");
}
function contentTransitionRight() {
sectionContent.classList.remove("xl:ltr:ml-0", "xl:rtl:mr-0");
sectionContent.classList.add("xl:ltr:ml-64", "xl:rtl:mr-64");
toggleButton.querySelector("span").classList.remove("ltr:-rotate-90", "rtl:rotate-90");
}
function notificationCount(action) {
let notification_count = document.querySelector('[data-notification-count]');
if (notification_count) {
notification_count.style = `display: ${action}`
}
}
function slideMenu() {
if (document.body.clientWidth <= 1280) {
mobileMenuHidden();
} else {
if (sideBar.classList.contains("menu-list-hidden")) {
toggleButton.classList.remove("ltr:left-12", "rtl:right-12");
sideBar.classList.remove("menu-list-hidden");
if (document.body.clientWidth > "991") {
contentTransitionRight();
}
} else {
sideBar.classList.add("menu-list-hidden");
toggleButton.classList.add("ltr:left-12", "rtl:right-12");
if (document.body.clientWidth > "991") {
contentTransitionLeft();
}
}
}
}
toggleButton.addEventListener("click", function() {
slideMenu();
});
function toggleMenu(iconButton, event) {
const menuRef = iconButton.getAttribute("data-menu");
const icon = iconButton.children[0].getAttribute("name");
if (iconButton.getAttribute("data-menu") === "profile-menu") {
if (iconButton.children[0].textContent != "cancel") {
iconButton.children[0].classList.remove("hidden");
iconButton.children[1].classList.add("hidden");
} else {
iconButton.children[0].classList.add("hidden");
iconButton.children[1].classList.remove("hidden");
}
}
menuButtons.forEach((button) => {
if (icon) {
if (button.getAttribute("data-menu") !== menuRef && iconButton.children[0].textContent != "cancel") {
button.children[0].textContent = button.children[0].getAttribute("name");
button.children[0].classList.remove("active"); // inactive icon
}
}
});
menus.forEach((menu) => {
if (menu.classList.contains(menuRef) && iconButton.children[0].textContent != "cancel") {
iconButton.children[0].textContent = "cancel";
iconButton.children[0].classList.add("active");
menu.classList.remove("ltr:-left-80", "rtl:-right-80");
menu.classList.add("ltr:left-14", "rtl:right-14");
mainContent.classList.add("hidden");
toggleButton.classList.add("invisible");
menuClose.classList.remove("hidden");
notificationCount("none");
} else if (menu.classList.contains(menuRef) && iconButton.children[0].textContent == "cancel") {
iconButton.children[0].textContent = icon;
iconButton.children[0].classList.remove("active");
menu.classList.add("ltr:-left-80", "rtl:-right-80");
menu.classList.remove("ltr:left-14", "rtl:right-14");
mainContent.classList.remove("hidden");
toggleButton.classList.remove("invisible");
menuClose.classList.add("hidden");
notificationCount("flex");
} else {
menu.classList.add("ltr:-left-80", "rtl:-right-80");
menu.classList.remove("ltr:left-14", "rtl:right-14");
}
menuClose.addEventListener("click", function() {
menu.classList.add("ltr:-left-80", "rtl:-right-80");
menu.classList.remove("ltr:left-14", "rtl:right-14");
iconButton.children[0].textContent = icon;
iconButton.children[0].classList.remove("active");
mainContent.classList.remove("hidden");
this.classList.add("hidden");
toggleButton.classList.remove("invisible");
});
});
}
if (document.body.clientWidth >= 1280) {
if (is_profile_menu == 1) {
let profile_menu_html = document.querySelector(".profile-menu");
let profile_icon_html = document.querySelector("[data-menu='profile-menu']");
profile_menu_html.classList.add("ltr:left-14", "rtl:right-14");
profile_menu_html.classList.remove("ltr:-left-80", "rtl:-right-80");
profile_icon_html.children[0].textContent = "cancel";
profile_icon_html.children[0].classList.add("active");
profile_icon_html.children[0].classList.remove("hidden");
profile_icon_html.children[1].classList.add("hidden");
toggleButton.classList.add("invisible");
}
if (is_settings_menu == 1) {
let settings_menu_html = document.querySelector(".settings-menu");
let settings_icon_html = document.querySelector("[data-menu='settings-menu']");
settings_menu_html.classList.add("ltr:left-14", "rtl:right-14");
settings_menu_html.classList.remove("ltr:-left-80", "rtl:-right-80");
settings_icon_html.children[0].textContent = "cancel";
settings_icon_html.children[0].classList.add("active");
toggleButton.classList.add("invisible");
}
}
function mobileMenuActive() {
navbarMenu.classList.add("ltr:left-0", "rtl:right-0");
navbarMenu.classList.remove("ltr:-left-80", "rtl:-right-80");
menuBackground.classList.add("visible");
menuBackground.classList.remove("invisible");
}
function mobileMenuHidden() {
navbarMenu.classList.remove("ltr:left-0", "rtl:right-0");
navbarMenu.classList.add("ltr:-left-80", "rtl:-right:80");
mainContent.classList.remove("hidden");
menus.forEach((menu) => {
menu.classList.remove("ltr:left-14", "rtl:right-14");
menu.classList.add("ltr:-left-80", "rtl:-right-80");
});
menuButtons.forEach((iconButton) => {
iconButton.children[0].classList.remove("active");
iconButton.children[0].textContent = iconButton.children[0].getAttribute("name");
});
menuBackground.classList.remove("visible");
menuBackground.classList.add("invisible");
}
document.querySelector(".js-hamburger-menu").addEventListener("click", function() {
mobileMenuActive();
});
menuBackground.addEventListener("click", function() {
mobileMenuHidden();
});
menuButtons.forEach((iconButton) =>
iconButton.addEventListener("click", function() {
toggleMenu(iconButton, event);
})
);
})(500);
</script>
@stack('body_css')
@stack('body_stylesheet')
@stack('body_js')
@stack('body_scripts')
@livewireScripts
<script src="{{ asset('public/vendor/alpinejs/alpine.min.js') }}"></script>
<!-- Livewire -->
<script type="text/javascript">
window.livewire_app_url = {{ company_id() }};
</script>
@stack('scripts_end')