Skip to content

Commit f990eda

Browse files
Improve UI and run migrations when system updated
1 parent 3dfedba commit f990eda

File tree

8 files changed

+98
-52
lines changed

8 files changed

+98
-52
lines changed

public/js/api-settings.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/js/api-settings.js

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,20 @@ $(() => {
4747

4848
// Update examples when API key changes
4949
$('#api-key-input').on('input', function() {
50-
const apiKey = $(this).val() || 'your-api-key-here';
50+
const apiKey = $(this).val() || (window.trans.api.your_api_key_here || 'your-api-key-here');
5151
updateExamplesWithApiKey(apiKey);
5252

5353
// Show/hide copy button based on whether there's a value
5454
const copyButton = $('#copy-api-key');
55-
if (apiKey && apiKey !== 'your-api-key-here') {
55+
if (apiKey && apiKey !== (window.trans.api.your_api_key_here || 'your-api-key-here')) {
5656
copyButton.show();
5757
} else {
5858
copyButton.hide();
5959
}
6060
});
6161

6262
// Initialize examples on page load
63-
const currentApiKey = $('#api-key-input').val() || 'your-api-key-here';
63+
const currentApiKey = $('#api-key-input').val() || (window.trans.api.your_api_key_here || 'your-api-key-here');
6464
updateExamplesWithApiKey(currentApiKey);
6565

6666
// Handle service account file upload
@@ -80,7 +80,7 @@ $(() => {
8080

8181
// Validate file size (max 2MB)
8282
if (file.size > 2 * 1024 * 1024) {
83-
Botble.showError('File size must be less than 2MB.');
83+
Botble.showError(window.trans.api.file_size_too_large || 'File size must be less than 2MB.');
8484
return;
8585
}
8686

@@ -92,7 +92,7 @@ $(() => {
9292
$('#remove-service-account-btn').on('click', function(e) {
9393
e.preventDefault();
9494

95-
if (confirm('Are you sure you want to remove the service account file?')) {
95+
if (confirm(window.trans.api.confirm_remove_service_account || 'Are you sure you want to remove the service account file?')) {
9696
removeServiceAccountFile();
9797
}
9898
});
@@ -175,7 +175,7 @@ $(() => {
175175
const removeBtn = $('#remove-service-account-btn');
176176
const originalHtml = removeBtn.html();
177177

178-
removeBtn.prop('disabled', true).html('<i class="ti ti-loader"></i>');
178+
removeBtn.prop('disabled', true).html('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 6l0 -3" /><path d="M16.25 7.75l2.15 -2.15" /><path d="M18 12l3 0" /><path d="M16.25 16.25l2.15 2.15" /><path d="M12 18l0 3" /><path d="M7.75 16.25l-2.15 2.15" /><path d="M6 12l-3 0" /><path d="M7.75 7.75l-2.15 -2.15" /></svg>');
179179

180180
$.ajax({
181181
url: '/admin/settings/api/remove-service-account',
@@ -226,16 +226,16 @@ $(() => {
226226
if (path && filename) {
227227
statusDiv.html(`
228228
<small class="text-success">
229-
<i class="ti ti-file-check me-1"></i>
230-
Service account file: <strong>${filename}</strong>
231-
<span class="text-muted">(Just uploaded)</span>
229+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-1"><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" /><path d="M9 15l2 2l4 -4" /></svg>
230+
${window.trans.api.service_account_file_label || 'Service account file:'} <strong>${filename}</strong>
231+
<span class="text-muted">${window.trans.api.just_uploaded || '(Just uploaded)'}</span>
232232
</small>
233233
`);
234234
} else {
235235
statusDiv.html(`
236236
<small class="text-warning">
237-
<i class="ti ti-file-x me-1"></i>
238-
Service account file is <strong>not uploaded</strong>. Please upload your service account JSON file.
237+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-1"><path d="M14 3v4a1 1 0 0 0 1 1h4" /><path d="M17 21h-10a2 2 0 0 1 -2 -2v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2z" /><path d="M10 12l4 4m0 -4l-4 4" /></svg>
238+
${window.trans.api.service_account_not_uploaded || 'Service account file is <strong>not uploaded</strong>. Please upload your service account JSON file.'}
239239
</small>
240240
`);
241241
}
@@ -253,13 +253,13 @@ $(() => {
253253
const message = $('#notification-message').val().trim();
254254

255255
if (!title) {
256-
Botble.showError('Please enter a notification title.');
256+
Botble.showError(window.trans.api.please_enter_notification_title || 'Please enter a notification title.');
257257
$('#notification-title').focus();
258258
return;
259259
}
260260

261261
if (!message) {
262-
Botble.showError('Please enter a notification message.');
262+
Botble.showError(window.trans.api.please_enter_notification_message || 'Please enter a notification message.');
263263
$('#notification-message').focus();
264264
return;
265265
}
@@ -301,7 +301,7 @@ $(() => {
301301
}
302302
},
303303
error: function(xhr) {
304-
let errorMessage = 'An error occurred while sending the notification.';
304+
let errorMessage = window.trans.api.notification_error_occurred || 'An error occurred while sending the notification.';
305305

306306
if (xhr.responseJSON && xhr.responseJSON.message) {
307307
errorMessage = xhr.responseJSON.message;
@@ -339,12 +339,12 @@ $(() => {
339339
function generateRandomApiKey() {
340340
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
341341
let result = '';
342-
342+
343343
// Generate a 32-character random string
344344
for (let i = 0; i < 32; i++) {
345345
result += chars.charAt(Math.floor(Math.random() * chars.length));
346346
}
347-
347+
348348
return result;
349349
}
350350

@@ -354,16 +354,16 @@ $(() => {
354354
*/
355355
function updateExamplesWithApiKey(apiKey) {
356356
const baseUrl = window.location.origin + '/api/v1';
357-
357+
358358
// Update cURL example
359-
const curlExample = `curl -X GET "${baseUrl}/products" \\
359+
const curlExample = `curl -X GET "${baseUrl}/pages" \\
360360
-H "Accept: application/json" \\
361361
-H "X-API-KEY: ${apiKey}"`;
362-
362+
363363
$('#curl-example').text(curlExample);
364-
364+
365365
// Update JavaScript example
366-
const jsExample = `fetch("${baseUrl}/products", {
366+
const jsExample = `fetch("${baseUrl}/pages", {
367367
method: "GET",
368368
headers: {
369369
"Accept": "application/json",
@@ -372,7 +372,7 @@ $(() => {
372372
})
373373
.then(response => response.json())
374374
.then(data => console.log(data));`;
375-
375+
376376
$('#js-example').text(jsExample);
377377
}
378378

@@ -385,27 +385,32 @@ $(() => {
385385
function showNotificationResult(type, message, data = null) {
386386
const resultDiv = $('#notification-result');
387387
const alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
388-
const iconClass = type === 'success' ? 'ti-check-circle' : 'ti-alert-circle';
388+
const iconSvg = type === 'success'
389+
? '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2"><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /><path d="M9 12l2 2l4 -4" /></svg>'
390+
: '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-2"><path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" /><path d="M12 8v4" /><path d="M12 16h.01" /></svg>';
389391

390392
let content = `
391393
<div class="alert ${alertClass} alert-dismissible fade show" role="alert">
392-
<i class="${iconClass} me-2"></i>
394+
${iconSvg}
393395
<strong>${message}</strong>
394396
`;
395397

396398
if (data && type === 'success') {
399+
const sentText = (window.trans.api.sent_to_devices || 'Sent to: :count devices').replace(':count', data.sent_count || 0);
400+
const failedText = (window.trans.api.failed_devices || 'Failed: :count devices').replace(':count', data.failed_count || 0);
401+
397402
content += `
398403
<div class="mt-2">
399404
<small>
400-
Sent to: ${data.sent_count || 0} devices<br>
401-
Failed: ${data.failed_count || 0} devices
405+
${sentText}<br>
406+
${failedText}
402407
</small>
403408
</div>
404409
`;
405410
}
406411

407412
content += `
408-
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
413+
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="${window.trans.api.close || 'Close'}"></button>
409414
</div>
410415
`;
411416

@@ -445,10 +450,15 @@ $(() => {
445450
// Update the notification send info text
446451
const infoText = $('#notification-send-info');
447452
if (infoText.length && stats.total > 0) {
453+
const deviceText = (window.trans.api.will_send_to_devices || 'Will send to :total active devices (:android Android, :ios iOS, :customers customers)')
454+
.replace(':total', stats.total)
455+
.replace(':android', stats.android)
456+
.replace(':ios', stats.ios)
457+
.replace(':customers', stats.customers);
458+
448459
infoText.html(`
449-
<i class="ti ti-info-circle me-1"></i>
450-
Will send to ${stats.total} active devices
451-
(${stats.android} Android, ${stats.ios} iOS, ${stats.customers} customers)
460+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="me-1"><path d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0" /><path d="M12 9h.01" /><path d="M11 12h1v4h1" /></svg>
461+
${deviceText}
452462
`);
453463
}
454464
}

resources/lang/en/api.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,19 @@
8787
'fcm_step_4_2' => 'Enter the path to your service account JSON file',
8888
'fcm_security_note_title' => 'Security Note:',
8989
'fcm_security_note' => 'Keep your service account JSON file secure and never commit it to version control. Store it in a secure location on your server.',
90+
91+
// Additional JavaScript translations
92+
'your_api_key_here' => 'your-api-key-here',
93+
'file_size_too_large' => 'File size must be less than 2MB.',
94+
'confirm_remove_service_account' => 'Are you sure you want to remove the service account file?',
95+
'service_account_file_label' => 'Service account file:',
96+
'just_uploaded' => '(Just uploaded)',
97+
'service_account_not_uploaded' => 'Service account file is <strong>not uploaded</strong>. Please upload your service account JSON file.',
98+
'please_enter_notification_title' => 'Please enter a notification title.',
99+
'please_enter_notification_message' => 'Please enter a notification message.',
100+
'notification_error_occurred' => 'An error occurred while sending the notification.',
101+
'sent_to_devices' => 'Sent to: :count devices',
102+
'failed_devices' => 'Failed: :count devices',
103+
'will_send_to_devices' => 'Will send to :total active devices (:android Android, :ios iOS, :customers customers)',
104+
'close' => 'Close',
90105
];

resources/views/settings/partials/fcm-setup-instructions.blade.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,57 @@
11
<div class="mt-3">
2-
<div class="card border-0 bg-light">
2+
<div class="card border-0 bg-white">
33
<div class="card-body">
44
<h6 class="mb-3">
55
<x-core::icon name="ti ti-info-circle" class="me-2" />
66
{{ trans('packages/api::api.fcm_setup_title') }}
77
</h6>
8-
8+
99
<div class="row">
1010
<div class="col-md-6">
1111
<h6 class="text-primary">{{ trans('packages/api::api.fcm_step_1_title') }}</h6>
12-
<ol class="small mb-3">
12+
<ul class="small mb-3">
1313
<li>{{ trans('packages/api::api.fcm_step_1_1') }}</li>
1414
<li>{{ trans('packages/api::api.fcm_step_1_2') }}</li>
1515
<li>{{ trans('packages/api::api.fcm_step_1_3') }}</li>
16-
</ol>
16+
</ul>
1717
</div>
18-
18+
1919
<div class="col-md-6">
2020
<h6 class="text-primary">{{ trans('packages/api::api.fcm_step_2_title') }}</h6>
21-
<ol class="small mb-3">
21+
<ul class="small mb-3">
2222
<li>{{ trans('packages/api::api.fcm_step_2_1') }}</li>
2323
<li>{{ trans('packages/api::api.fcm_step_2_2') }}</li>
2424
<li>{{ trans('packages/api::api.fcm_step_2_3') }}</li>
2525
<li>{{ trans('packages/api::api.fcm_step_2_4') }}</li>
26-
</ol>
26+
</ul>
2727
</div>
2828
</div>
2929

3030
<div class="row">
3131
<div class="col-md-6">
3232
<h6 class="text-primary">{{ trans('packages/api::api.fcm_step_3_title') }}</h6>
33-
<ol class="small mb-3">
33+
<ul class="small mb-3">
3434
<li>{{ trans('packages/api::api.fcm_step_3_1') }}</li>
3535
<li>{{ trans('packages/api::api.fcm_step_3_2') }}</li>
3636
<li>{{ trans('packages/api::api.fcm_step_3_3') }}</li>
37-
</ol>
37+
</ul>
3838
</div>
39-
39+
4040
<div class="col-md-6">
4141
<h6 class="text-primary">{{ trans('packages/api::api.fcm_step_4_title') }}</h6>
42-
<ol class="small mb-3">
42+
<ul class="small mb-3">
4343
<li>{{ trans('packages/api::api.fcm_step_4_1') }}</li>
4444
<li>{{ trans('packages/api::api.fcm_step_4_2') }}</li>
45-
</ol>
45+
</ul>
4646
</div>
4747
</div>
4848

4949
<div class="alert alert-info mb-0">
5050
<x-core::icon name="ti ti-bulb" class="me-2" />
51-
<strong>{{ trans('packages/api::api.fcm_security_note_title') }}</strong>
52-
{{ trans('packages/api::api.fcm_security_note') }}
51+
<p class="mb-0">
52+
<strong>{{ trans('packages/api::api.fcm_security_note_title') }}</strong>
53+
{{ trans('packages/api::api.fcm_security_note') }}
54+
</p>
5355
</div>
5456
</div>
5557
</div>

resources/views/settings/partials/send-notification-form.blade.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div class="mt-4 send-notification-section">
22
<h6 class="mb-3">{{ trans('packages/api::api.send_custom_notification') }}</h6>
3-
4-
<div class="card border-0 bg-light">
3+
4+
<div class="card border-0 bg-white">
55
<div class="card-body">
66
<div id="send-notification-form">
77
@csrf
@@ -37,7 +37,7 @@ class="form-control"
3737
</div>
3838
</div>
3939
</div>
40-
40+
4141
<div class="mb-3">
4242
<label for="notification-message" class="form-label">
4343
{{ trans('packages/api::api.notification_message') }}

resources/views/settings/partials/usage-examples.blade.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,20 @@
44

55
<div class="mt-3">
66
<h6>{{ trans('packages/api::api.api_usage_examples') }}</h6>
7-
7+
88
<div class="mb-3 api-code-example">
99
<label class="form-label">{{ trans('packages/api::api.api_usage_curl_example') }}</label>
1010
<div class="position-relative">
11-
<pre class="bg-dark text-light p-3 rounded" style="font-size: 0.875rem;"><code id="curl-example">curl -X GET "{{ $baseUrl }}/products" \
11+
<pre class="bg-dark text-light p-3 rounded" style="font-size: 0.875rem;"><code id="curl-example">curl -X GET "{{ $baseUrl }}/pages" \
1212
-H "Accept: application/json" \
1313
-H "X-API-KEY: your-api-key-here"</code></pre>
1414
</div>
1515
</div>
16-
16+
1717
<div class="mb-3 api-code-example">
1818
<label class="form-label">{{ trans('packages/api::api.api_usage_javascript_example') }}</label>
1919
<div class="position-relative">
20-
<pre class="bg-dark text-light p-3 rounded" style="font-size: 0.875rem;"><code id="js-example">fetch("{{ $baseUrl }}/products", {
20+
<pre class="bg-dark text-light p-3 rounded" style="font-size: 0.875rem;"><code id="js-example">fetch("{{ $baseUrl }}/pages", {
2121
method: "GET",
2222
headers: {
2323
"Accept": "application/json",

src/Http/Controllers/ApiController.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ public function edit(SanctumTokenTable $sanctumTokenTable)
4343
'invalid_json_file' => trans('packages/api::api.invalid_json_file'),
4444
'file_upload_error' => trans('packages/api::api.file_upload_error'),
4545
'file_remove_error' => trans('packages/api::api.file_remove_error'),
46+
'send_notification' => trans('packages/api::api.send_notification'),
47+
'your_api_key_here' => trans('packages/api::api.your_api_key_here'),
48+
'file_size_too_large' => trans('packages/api::api.file_size_too_large'),
49+
'confirm_remove_service_account' => trans('packages/api::api.confirm_remove_service_account'),
50+
'service_account_file_label' => trans('packages/api::api.service_account_file_label'),
51+
'just_uploaded' => trans('packages/api::api.just_uploaded'),
52+
'service_account_not_uploaded' => trans('packages/api::api.service_account_not_uploaded'),
53+
'please_enter_notification_title' => trans('packages/api::api.please_enter_notification_title'),
54+
'please_enter_notification_message' => trans('packages/api::api.please_enter_notification_message'),
55+
'notification_error_occurred' => trans('packages/api::api.notification_error_occurred'),
56+
'sent_to_devices' => trans('packages/api::api.sent_to_devices'),
57+
'failed_devices' => trans('packages/api::api.failed_devices'),
58+
'will_send_to_devices' => trans('packages/api::api.will_send_to_devices'),
59+
'close' => trans('packages/api::api.close'),
4660
];
4761

4862
return view('packages/api::settings', compact('form', 'sanctumTokenTable', 'translations'));

src/Providers/ApiServiceProvider.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Botble\Api\Http\Middleware\ApiKeyMiddleware;
1010
use Botble\Api\Http\Middleware\ForceJsonResponseMiddleware;
1111
use Botble\Api\Models\PersonalAccessToken;
12+
use Botble\Base\Events\SystemUpdateDBMigrated;
1213
use Botble\Base\Facades\PanelSectionManager;
1314
use Botble\Base\PanelSections\PanelSectionItem;
1415
use Botble\Base\Supports\ServiceProvider;
@@ -105,6 +106,10 @@ public function boot(): void
105106
return $permissions;
106107
}, 120);
107108
});
109+
110+
$this->app['events']->listen(SystemUpdateDBMigrated::class, function () {
111+
$this->app['migrator']->run($this->getPath('database/migrations'));
112+
});
108113
}
109114

110115
protected function getPath(?string $path = null): string

0 commit comments

Comments
 (0)