diff --git a/src/.env.example b/src/.env.example --- a/src/.env.example +++ b/src/.env.example @@ -5,10 +5,13 @@ APP_URL=http://127.0.0.1:8000 APP_PUBLIC_URL= APP_DOMAIN=kolabnow.com +APP_THEME=default ASSET_URL=http://127.0.0.1:8000 -SUPPORT_URL= +WEBMAIL_URL=/apps +SUPPORT_URL=/support +SUPPORT_EMAIL= LOG_CHANNEL=stack diff --git a/src/app/Documents/Receipt.php b/src/app/Documents/Receipt.php --- a/src/app/Documents/Receipt.php +++ b/src/app/Documents/Receipt.php @@ -99,7 +99,7 @@ // Fix font and image paths $html = str_replace('url(/fonts/', 'url(fonts/', $html); - $html = str_replace('src="/images/', 'src="images/', $html); + $html = str_replace('src="/', 'src="', $html); // TODO: The output file is about ~200KB, we could probably slim it down // by using separate font files with small subset of languages when @@ -254,6 +254,7 @@ $footer = \config('app.company.details'); $contact = \config('app.company.email'); $logo = \config('app.company.logo'); + $theme = \config('app.theme'); if ($contact) { $length = strlen($footer) + strlen($contact) + 3; @@ -262,8 +263,12 @@ . sprintf('%s', $contact, $contact); } + if ($logo && strpos($logo, '/') === false) { + $logo = "/themes/$theme/images/$logo"; + } + return [ - 'logo' => $logo ? "" : '', + 'logo' => $logo ? "" : '', 'header' => $header, 'footer' => $footer, ]; diff --git a/src/app/Http/Controllers/API/V4/SupportController.php b/src/app/Http/Controllers/API/V4/SupportController.php new file mode 100644 --- /dev/null +++ b/src/app/Http/Controllers/API/V4/SupportController.php @@ -0,0 +1,69 @@ + 'string|nullable|max:256', + 'name' => 'string|nullable|max:256', + 'email' => 'required|email', + 'summary' => 'required|string|max:512', + 'body' => 'required|string', + ]; + + $params = $request->only(array_keys($rules)); + + // Check required fields + $v = Validator::make($params, $rules); + + if ($v->fails()) { + return response()->json(['status' => 'error', 'errors' => $v->errors()], 422); + } + + $to = \config('app.support_email'); + + if (empty($to)) { + \Log::error("Failed to send a support request. SUPPORT_EMAIL not set"); + return $this->errorResponse(500, \trans('app.support-request-error')); + } + + $content = sprintf( + "ID: %s\nName: %s\nWorking email address: %s\nSubject: %s\n\n%s\n", + $params['user'] ?? '', + $params['name'] ?? '', + $params['email'], + $params['summary'], + $params['body'], + ); + + Mail::raw($content, function ($message) use ($params, $to) { + // Remove the global reply-to addressee + $message->getHeaders()->remove('Reply-To'); + + $message->to($to) + ->from($params['email'], $params['name'] ?? null) + ->replyTo($params['email'], $params['name'] ?? null) + ->subject($params['summary']); + }); + + return response()->json([ + 'status' => 'success', + 'message' => \trans('app.support-request-success'), + ]); + } +} diff --git a/src/app/Http/Controllers/ContentController.php b/src/app/Http/Controllers/ContentController.php new file mode 100644 --- /dev/null +++ b/src/app/Http/Controllers/ContentController.php @@ -0,0 +1,62 @@ +with('env', \App\Utils::uiEnv()); + } + + /** + * Get the list of FAQ entries for the specified page + * + * @param string $page Page path + * + * @return \Illuminate\Http\JsonResponse JSON response + */ + public function faqContent(string $page) + { + if (empty($page)) { + return $this->errorResponse(404); + } + + $faq = []; + + $theme_name = \config('app.theme'); + $theme_file = resource_path("themes/{$theme_name}/theme.json"); + + if (file_exists($theme_file)) { + $theme = json_decode(file_get_contents($theme_file), true); + if (json_last_error() != JSON_ERROR_NONE) { + \Log::error("Failed to parse $theme_file: " . json_last_error_msg()); + } elseif (!empty($theme['faq']) && !empty($theme['faq'][$page])) { + $faq = $theme['faq'][$page]; + } + + // TODO: Support pages with variables, e.g. users/ + } + + return response()->json(['status' => 'success', 'faq' => $faq]); + } +} diff --git a/src/app/Providers/AppServiceProvider.php b/src/app/Providers/AppServiceProvider.php --- a/src/app/Providers/AppServiceProvider.php +++ b/src/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; @@ -48,5 +49,11 @@ \Log::debug(sprintf('[SQL] %s [%s]', $query->sql, implode(', ', $query->bindings))); }); } + + // Register some template helpers + Blade::directive('theme_asset', function ($path) { + $path = trim($path, '/\'"'); + return ""; + }); } } diff --git a/src/app/Utils.php b/src/app/Utils.php --- a/src/app/Utils.php +++ b/src/app/Utils.php @@ -321,7 +321,16 @@ */ public static function uiEnv(): array { - $opts = ['app.name', 'app.url', 'app.domain']; + $opts = [ + 'app.name', + 'app.url', + 'app.domain', + 'app.theme', + 'app.webmail_url', + 'app.support_email', + 'mail.from.address' + ]; + $env = \app('config')->getMany($opts); $countries = include resource_path('countries.php'); @@ -333,6 +342,21 @@ $env['paymentProvider'] = \config('services.payment_provider'); $env['stripePK'] = \config('services.stripe.public_key'); + $theme_file = resource_path("themes/{$env['app.theme']}/theme.json"); + $menu = []; + + if (file_exists($theme_file)) { + $theme = json_decode(file_get_contents($theme_file), true); + + if (json_last_error() != JSON_ERROR_NONE) { + \Log::error("Failed to parse $theme_file: " . json_last_error_msg()); + } elseif (!empty($theme['menu'])) { + $menu = $theme['menu']; + } + } + + $env['menu'] = $menu; + return $env; } } diff --git a/src/config/app.php b/src/config/app.php --- a/src/config/app.php +++ b/src/config/app.php @@ -59,6 +59,12 @@ 'support_url' => env('SUPPORT_URL', null), + 'support_email' => env('SUPPORT_EMAIL', null), + + 'webmail_url' => env('WEBMAIL_URL', null), + + 'theme' => env('APP_THEME', 'default'), + /* |-------------------------------------------------------------------------- | Application Domain diff --git a/src/config/view.php b/src/config/view.php --- a/src/config/view.php +++ b/src/config/view.php @@ -15,6 +15,7 @@ 'paths' => [ resource_path('views'), + resource_path('themes'), ], /* diff --git a/src/public/images/icons/icon-128x128.png b/src/public/images/icons/icon-128x128.png deleted file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@

- -

-Build Status -Total Downloads -Latest Stable Version -License -

- -## About Laravel - -Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as: - -- [Simple, fast routing engine](https://laravel.com/docs/routing). -- [Powerful dependency injection container](https://laravel.com/docs/container). -- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage. -- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent). -- Database agnostic [schema migrations](https://laravel.com/docs/migrations). -- [Robust background job processing](https://laravel.com/docs/queues). -- [Real-time event broadcasting](https://laravel.com/docs/broadcasting). - -Laravel is accessible, powerful, and provides tools required for large, robust applications. - -## Learning Laravel - -Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework. - -If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library. - -## Laravel Sponsors - -We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell). - -- **[Vehikl](https://vehikl.com/)** -- **[Tighten Co.](https://tighten.co)** -- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)** -- **[64 Robots](https://64robots.com)** -- **[Cubet Techno Labs](https://cubettech.com)** -- **[Cyber-Duck](https://cyber-duck.co.uk)** -- **[British Software Development](https://www.britishsoftware.co)** -- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)** -- **[DevSquad](https://devsquad.com)** -- [UserInsights](https://userinsights.com) -- [Fragrantica](https://www.fragrantica.com) -- [SOFTonSOFA](https://softonsofa.com/) -- [User10](https://user10.com) -- [Soumettre.fr](https://soumettre.fr/) -- [CodeBrisk](https://codebrisk.com) -- [1Forge](https://1forge.com) -- [TECPRESSO](https://tecpresso.co.jp/) -- [Runtime Converter](http://runtimeconverter.com/) -- [WebL'Agence](https://weblagence.com/) -- [Invoice Ninja](https://www.invoiceninja.com) -- [iMi digital](https://www.imi-digital.de/) -- [Earthlink](https://www.earthlink.ro/) -- [Steadfast Collective](https://steadfastcollective.com/) -- [We Are The Robots Inc.](https://watr.mx/) -- [Understand.io](https://www.understand.io/) -- [Abdel Elrafa](https://abdelelrafa.com) -- [Hyper Host](https://hyper.host) - -## Contributing - -Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). - -## Security Vulnerabilities - -If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed. - -## License - -The Laravel framework is open-source software licensed under the [MIT license](https://opensource.org/licenses/MIT). diff --git a/src/resources/js/app.js b/src/resources/js/app.js --- a/src/resources/js/app.js +++ b/src/resources/js/app.js @@ -8,6 +8,7 @@ import AppComponent from '../vue/App' import MenuComponent from '../vue/Widgets/Menu' +import SupportForm from '../vue/Widgets/SupportForm' import store from './store' const loader = '
Loading
' @@ -132,10 +133,12 @@ if (!msg) msg = map[code] || "Unknown Error" - const error_page = `
${code}
${msg}
` + const error_page = `
${code}
${msg}
` $('#error-page').remove() $('#app').append(error_page) + + app.updateBodyClass('error') }, errorHandler(error) { this.stopLoading() @@ -231,6 +234,38 @@ return 'Active' }, + pageName(path) { + let page = this.$route.path + + // check if it is a "menu page", find the page name + // otherwise we'll use the real path as page name + window.config.menu.every(item => { + if (item.location == page && item.page) { + page = item.page + return false + } + }) + + page = page.replace(/^\//, '') + + return page ? page : '404' + }, + supportDialog(container) { + let dialog = $('#support-dialog') + + // FIXME: Find a nicer way of doing this + if (!dialog.length) { + let form = new Vue(SupportForm) + form.$mount($('
').appendTo(container)[0]) + form.$root = this + form.$toast = this.$toast + dialog = $(form.$el) + } + + dialog.on('shown.bs.modal', () => { + dialog.find('input').first().focus() + }).modal() + }, userStatusClass(user) { if (user.isDeleted) { return 'text-muted' @@ -260,6 +295,12 @@ } return 'Active' + }, + updateBodyClass(name) { + // Add 'class' attribute to the body, different for each page + // so, we can apply page-specific styles + let className = 'page-' + (name || this.pageName()).replace(/\/.*$/, '') + $(document.body).removeClass().addClass(className) } } }) @@ -289,6 +330,11 @@ let error_msg let status = error.response ? error.response.status : 200 + // Do not display the error in a toast message, pass the error as-is + if (error.config.ignoreErrors) { + return Promise.reject(error) + } + if (error.response && status == 422) { error_msg = "Form validation error" @@ -356,3 +402,13 @@ return Promise.reject(error) } ) + +// TODO: Investigate if we can use App component's childMounted() method instead +window.router.afterEach((to, from) => { + // When changing a page remove old: + // - error page + // - modal backdrop + $('#error-page,.modal-backdrop.show').remove() + + app.updateBodyClass() +}) diff --git a/src/resources/js/bootstrap.js b/src/resources/js/bootstrap.js --- a/src/resources/js/bootstrap.js +++ b/src/resources/js/bootstrap.js @@ -83,13 +83,6 @@ next() }) -router.afterEach((to, from) => { - // When changing a page remove old: - // - error page - // - modal backdrop - $('#error-page,.modal-backdrop.show').remove() -}) - /** * We'll load the axios HTTP library which allows us to easily issue requests * to our Laravel back-end. This library automatically handles sending the diff --git a/src/resources/js/fontawesome.js b/src/resources/js/fontawesome.js --- a/src/resources/js/fontawesome.js +++ b/src/resources/js/fontawesome.js @@ -12,6 +12,7 @@ faCheck, faCheckCircle, faDownload, + faEnvelope, faGlobe, faExclamationCircle, faInfoCircle, @@ -35,6 +36,7 @@ faCheckSquare, faCreditCard, faDownload, + faEnvelope, faExclamationCircle, faGlobe, faInfoCircle, diff --git a/src/resources/js/routes-admin.js b/src/resources/js/routes-admin.js --- a/src/resources/js/routes-admin.js +++ b/src/resources/js/routes-admin.js @@ -1,8 +1,8 @@ import DashboardComponent from '../vue/Admin/Dashboard' import DomainComponent from '../vue/Admin/Domain' -import Error404Component from '../vue/404' import LoginComponent from '../vue/Login' import LogoutComponent from '../vue/Logout' +import PageComponent from '../vue/Page' import UserComponent from '../vue/Admin/User' const routes = [ @@ -41,7 +41,7 @@ { name: '404', path: '*', - component: Error404Component + component: PageComponent } ] diff --git a/src/resources/js/routes-user.js b/src/resources/js/routes-user.js --- a/src/resources/js/routes-user.js +++ b/src/resources/js/routes-user.js @@ -1,9 +1,9 @@ import DashboardComponent from '../vue/Dashboard' import DomainInfoComponent from '../vue/Domain/Info' import DomainListComponent from '../vue/Domain/List' -import Error404Component from '../vue/404' import LoginComponent from '../vue/Login' import LogoutComponent from '../vue/Logout' +import PageComponent from '../vue/Page' import PasswordResetComponent from '../vue/PasswordReset' import SignupComponent from '../vue/Signup' import UserInfoComponent from '../vue/User/Info' @@ -14,10 +14,6 @@ const routes = [ { - path: '/', - redirect: { name: 'dashboard' } - }, - { path: '/dashboard', name: 'dashboard', component: DashboardComponent, @@ -89,7 +85,7 @@ { name: '404', path: '*', - component: Error404Component + component: PageComponent } ] diff --git a/src/resources/lang/en/app.php b/src/resources/lang/en/app.php --- a/src/resources/lang/en/app.php +++ b/src/resources/lang/en/app.php @@ -44,6 +44,9 @@ 'search-foundxdomains' => ':x domains have been found.', 'search-foundxusers' => ':x user accounts have been found.', + 'support-request-success' => 'Support request submitted successfully.', + 'support-request-error' => 'Failed to submit the support request.', + 'wallet-award-success' => 'The bonus has been added to the wallet successfully.', 'wallet-penalty-success' => 'The penalty has been added to the wallet successfully.', 'wallet-update-success' => 'User wallet updated successfully.', diff --git a/src/resources/themes/README.md b/src/resources/themes/README.md new file mode 100644 --- /dev/null +++ b/src/resources/themes/README.md @@ -0,0 +1,65 @@ +## THEMES + +### Creating a theme + +1. First create the theme directory and content by copying the default theme: + +``` +cp resources/themes/default resources/themes/mytheme +``` + +2. Compile resources. This will also make sure to copy static files (e.g. images) + to `public/themes/`: + +``` +npm run prod +``` + +3. Configure the app to use your new theme (in .env file): + +``` +APP_THEME=mytheme +``` + +### Styles + +The main theme directory should include following files: + +- "theme.json": Theme metadata, e.g. menu definition. +- "app.scss": The app styles. +- "document.scss": Documents styles. +- "images/logo_header.png": An image that is not controlled by the theme (yet). +- "images/logo_footer.png": An image that is not controlled by the theme (yet). +- "images/favicon.ico": An image that is not controlled by the theme (yet). + +Note: Applying some styles to `` or other elements outside of the template +content can be done using `.page-` class that is always added to the ``. + +### Menu definition + +The menu items are defined using "menu" property in `theme.json` file. +It should be an array of object. Here are all available properties for such an object. + +- "title" (string): The displayed label for the menu item. Required. +- "location" (string): The page location. Can be a full URL (for external pages) + or relative path starting with a slash for internal locations. Required. +- "page" (string): The name of the page. Required for internal pages. + This is the first element of the page template file which should exist + in `resources/themes//pages/` directory. The template file name should be + `.blade.php`. +- "footer" (bool): Whether the menu should appear only in the footer menu. + +Note that menu definition should not include special pages like "Signup", "Contact" or "Login". + +### Page templates + +Page content templates placed in `resources/themes//pages/` directory are +Blade templates. Some notes about that: + +- the content will be placed inside the page layout so you should not use nor + nor even a wrapper
. +- for internal links use `href="/"`. Such links will be handled by + Vue router (without page reload). +- for images or other resource files use `@theme_asset(images/file.jpg)`. + +See also: https://laravel.com/docs/6.x/blade diff --git a/src/resources/sass/app.scss b/src/resources/themes/app.scss rename from src/resources/sass/app.scss rename to src/resources/themes/app.scss --- a/src/resources/sass/app.scss +++ b/src/resources/themes/app.scss @@ -1,9 +1,3 @@ -@import 'variables'; -@import 'bootstrap'; -@import 'menu'; -@import 'toast'; -@import 'forms'; - html, body, body > .outer-container { @@ -35,7 +29,7 @@ } } -#error-page { +.error-page { position: absolute; top: 0; height: 100%; @@ -273,7 +267,8 @@ // Various improvements for mobile @include media-breakpoint-down(sm) { - .card { + .card, + .card-footer { border: 0; } diff --git a/src/resources/sass/bootstrap.scss b/src/resources/themes/bootstrap.scss rename from src/resources/sass/bootstrap.scss rename to src/resources/themes/bootstrap.scss diff --git a/src/resources/sass/_variables.scss b/src/resources/themes/default/_variables.scss rename from src/resources/sass/_variables.scss rename to src/resources/themes/default/_variables.scss --- a/src/resources/sass/_variables.scss +++ b/src/resources/themes/default/_variables.scss @@ -7,17 +7,7 @@ $line-height-base: 1.5; // Colors -$blue: #3490dc; -$indigo: #6574cd; -$purple: #9561e2; -$pink: #f66d9b; -$red: #e3342f; $orange: #f1a539; -$yellow: #ffed4a; -$green: #38c172; -$teal: #4dc0b5; -$cyan: #6cb2eb; - $light: #f6f5f3; // App colors diff --git a/src/resources/themes/default/app.scss b/src/resources/themes/default/app.scss new file mode 100644 --- /dev/null +++ b/src/resources/themes/default/app.scss @@ -0,0 +1,7 @@ +@import 'variables'; + +@import '../bootstrap'; +@import '../menu'; +@import '../toast'; +@import '../forms'; +@import '../app'; diff --git a/src/resources/themes/default/document.scss b/src/resources/themes/default/document.scss new file mode 100644 --- /dev/null +++ b/src/resources/themes/default/document.scss @@ -0,0 +1,3 @@ +// Variables +@import 'variables'; +@import '../document'; diff --git a/src/public/images/favicon.ico b/src/resources/themes/default/images/favicon.ico rename from src/public/images/favicon.ico rename to src/resources/themes/default/images/favicon.ico diff --git a/src/public/images/logo.svg b/src/resources/themes/default/images/logo.svg rename from src/public/images/logo.svg rename to src/resources/themes/default/images/logo.svg diff --git a/src/public/images/logo_footer.png b/src/resources/themes/default/images/logo_footer.png rename from src/public/images/logo_footer.png rename to src/resources/themes/default/images/logo_footer.png diff --git a/src/public/images/logo_header.png b/src/resources/themes/default/images/logo_header.png rename from src/public/images/logo_header.png rename to src/resources/themes/default/images/logo_header.png diff --git a/src/public/images/logo_print.svg b/src/resources/themes/default/images/logo_print.svg rename from src/public/images/logo_print.svg rename to src/resources/themes/default/images/logo_print.svg diff --git a/src/resources/themes/default/pages/support.blade.php b/src/resources/themes/default/pages/support.blade.php new file mode 100644 --- /dev/null +++ b/src/resources/themes/default/pages/support.blade.php @@ -0,0 +1,21 @@ +
+
+

Contact Support

+

+ Our technical support team is here to provide help, should you run + into issues. You won’t have to talk to computers or navigate voice + menus, but have actual human beings answering you personally. +
+
+ This support is already included in your subscription fee, so + there are no further costs for you. If you have issues with your + Kolab Now account, or questions about our product before you sign + up, please contact us. +

+
+ +
+
+
diff --git a/src/resources/themes/default/theme.json b/src/resources/themes/default/theme.json new file mode 100644 --- /dev/null +++ b/src/resources/themes/default/theme.json @@ -0,0 +1,41 @@ +{ + "menu": [ + { + "title": "Explore", + "location": "https://kolabnow.com/", + "admin": true + }, + { + "title": "Blog", + "location": "https://blogs.kolabnow.com/", + "admin": true + }, + { + "title": "Support", + "location": "/support", + "page": "support", + "admin": true + }, + { + "title": "ToS", + "location": "https://kolabnow.com/tos", + "footer": true + } + ], + "faq": { + "signup": [ + { + "href": "https://kolabnow.com/tos", + "title": "What are your terms of service?" + }, + { + "href": "https://kb.kolabnow.com/faq/can-i-upgrade-an-individual-account-to-a-group-account", + "title": "Can I upgrade an individual account to a group account?" + }, + { + "href": "https://kb.kolabnow.com/faq/how-much-storage-comes-with-my-account", + "title": "How much storage comes with my account?" + } + ] + } +} diff --git a/src/resources/sass/document.scss b/src/resources/themes/document.scss rename from src/resources/sass/document.scss rename to src/resources/themes/document.scss --- a/src/resources/sass/document.scss +++ b/src/resources/themes/document.scss @@ -1,6 +1,3 @@ -// Variables -@import 'variables'; - @font-face { font-family: 'Roboto'; font-style: normal; diff --git a/src/resources/sass/forms.scss b/src/resources/themes/forms.scss rename from src/resources/sass/forms.scss rename to src/resources/themes/forms.scss diff --git a/src/resources/sass/menu.scss b/src/resources/themes/menu.scss rename from src/resources/sass/menu.scss rename to src/resources/themes/menu.scss --- a/src/resources/sass/menu.scss +++ b/src/resources/themes/menu.scss @@ -104,6 +104,8 @@ } #footer-menu { + height: 80px; + .navbar-nav { display: none; } @@ -130,8 +132,6 @@ } #footer-menu { - height: 80px; - .container { flex-direction: column; } diff --git a/src/resources/sass/toast.scss b/src/resources/themes/toast.scss rename from src/resources/sass/toast.scss rename to src/resources/themes/toast.scss diff --git a/src/resources/views/documents/receipt.blade.php b/src/resources/views/documents/receipt.blade.php --- a/src/resources/views/documents/receipt.blade.php +++ b/src/resources/views/documents/receipt.blade.php @@ -3,7 +3,7 @@ diff --git a/src/resources/views/layouts/app.blade.php b/src/resources/views/layouts/app.blade.php --- a/src/resources/views/layouts/app.blade.php +++ b/src/resources/views/layouts/app.blade.php @@ -9,8 +9,8 @@ {{ config('app.name') }} -- @yield('title') {{-- TODO: PWA disabled for now: @laravelPWA --}} - - + +
diff --git a/src/resources/vue/404.vue b/src/resources/vue/404.vue deleted file mode 100644 --- a/src/resources/vue/404.vue +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/src/resources/vue/App.vue b/src/resources/vue/App.vue --- a/src/resources/vue/App.vue +++ b/src/resources/vue/App.vue @@ -1,9 +1,16 @@ diff --git a/src/resources/vue/PasswordReset.vue b/src/resources/vue/PasswordReset.vue --- a/src/resources/vue/PasswordReset.vue +++ b/src/resources/vue/PasswordReset.vue @@ -4,7 +4,8 @@

Password Reset - Step 1/3

- Enter your email address to reset your password. You may need to check your spam folder or unblock noreply@kolabnow.com. + Enter your email address to reset your password. + You may need to check your spam folder or unblock {{ fromEmail }}.

@@ -65,7 +66,8 @@ code: '', short_code: '', password: '', - password_confirmation: '' + password_confirmation: '', + fromEmail: window.config['mail.from.address'] } }, created() { diff --git a/src/resources/vue/Signup.vue b/src/resources/vue/Signup.vue --- a/src/resources/vue/Signup.vue +++ b/src/resources/vue/Signup.vue @@ -1,7 +1,7 @@