Update ACP UI copy, accents, and defaults
This commit is contained in:
@@ -35,3 +35,7 @@
|
|||||||
- Moved the Laravel app to the repo root and removed the separate `api/` and `frontend/` folders.
|
- Moved the Laravel app to the repo root and removed the separate `api/` and `frontend/` folders.
|
||||||
- Serve the SPA shell via Blade with Vite-managed React assets.
|
- Serve the SPA shell via Blade with Vite-managed React assets.
|
||||||
- Dropped Tailwind tooling to keep the frontend Bootstrap-only.
|
- Dropped Tailwind tooling to keep the frontend Bootstrap-only.
|
||||||
|
- Replaced the default Laravel README with a forum placeholder.
|
||||||
|
- Updated ACP forum tools with accent-tinted buttons and larger action spacing.
|
||||||
|
- Defaulted the ACP forum tree to collapsed on page load.
|
||||||
|
- Improved ACP create/edit dialog copy based on forum vs category and hid type selection during creation.
|
||||||
|
|||||||
60
README.md
60
README.md
@@ -1,59 +1,7 @@
|
|||||||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
# SpeedBB Forum
|
||||||
|
|
||||||
<p align="center">
|
Placeholder README for the forum application.
|
||||||
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
|
||||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
## About Laravel
|
## Status
|
||||||
|
|
||||||
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:
|
Work in progress.
|
||||||
|
|
||||||
- [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. You can also check out [Laravel Learn](https://laravel.com/learn), where you will be guided through building a modern Laravel application.
|
|
||||||
|
|
||||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains thousands of 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 Partners program](https://partners.laravel.com).
|
|
||||||
|
|
||||||
### Premium Partners
|
|
||||||
|
|
||||||
- **[Vehikl](https://vehikl.com)**
|
|
||||||
- **[Tighten Co.](https://tighten.co)**
|
|
||||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
|
||||||
- **[64 Robots](https://64robots.com)**
|
|
||||||
- **[Curotec](https://www.curotec.com/services/technologies/laravel)**
|
|
||||||
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
|
|
||||||
- **[Redberry](https://redberry.international/laravel-development)**
|
|
||||||
- **[Active Logic](https://activelogic.com)**
|
|
||||||
|
|
||||||
## 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).
|
|
||||||
|
|
||||||
## Code of Conduct
|
|
||||||
|
|
||||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
|
||||||
|
|
||||||
## 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-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
|
||||||
|
|||||||
@@ -199,6 +199,52 @@ a {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bb-acp-action.btn-outline-dark {
|
||||||
|
--bs-btn-color: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-border-color: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-hover-color: #0f1218;
|
||||||
|
--bs-btn-hover-bg: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-hover-border-color: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-active-color: #0f1218;
|
||||||
|
--bs-btn-active-bg: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-active-border-color: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-focus-shadow-rgb: 242, 155, 63;
|
||||||
|
color: var(--bb-accent, #f29b3f) !important;
|
||||||
|
border-color: var(--bb-accent, #f29b3f) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bb-acp-action--active.btn-outline-dark {
|
||||||
|
background-color: var(--bb-accent, #f29b3f);
|
||||||
|
border-color: var(--bb-accent, #f29b3f);
|
||||||
|
color: #0f1218;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bb-acp-action.btn-outline-dark:hover,
|
||||||
|
.bb-acp-action.btn-outline-dark:focus {
|
||||||
|
background-color: var(--bb-accent, #f29b3f) !important;
|
||||||
|
border-color: var(--bb-accent, #f29b3f) !important;
|
||||||
|
color: #0f1218 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-bs-theme="dark"] .bb-acp-action.btn-outline-dark {
|
||||||
|
--bs-btn-color: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-border-color: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-hover-color: #0f1218;
|
||||||
|
--bs-btn-hover-bg: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-hover-border-color: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-active-color: #0f1218;
|
||||||
|
--bs-btn-active-bg: var(--bb-accent, #f29b3f);
|
||||||
|
--bs-btn-active-border-color: var(--bb-accent, #f29b3f);
|
||||||
|
color: var(--bb-accent, #f29b3f) !important;
|
||||||
|
border-color: var(--bb-accent, #f29b3f) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-bs-theme="dark"] .bb-acp-action--active.btn-outline-dark {
|
||||||
|
background-color: var(--bb-accent, #f29b3f);
|
||||||
|
border-color: var(--bb-accent, #f29b3f);
|
||||||
|
color: #0f1218;
|
||||||
|
}
|
||||||
|
|
||||||
.bb-load-time {
|
.bb-load-time {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { Button, ButtonGroup, Col, Container, Form, Modal, Row, Tab, Tabs } from 'react-bootstrap'
|
import { Button, ButtonGroup, Col, Container, Form, Modal, Row, Tab, Tabs } from 'react-bootstrap'
|
||||||
import DataTable, { createTheme } from 'react-data-table-component'
|
import DataTable, { createTheme } from 'react-data-table-component'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@@ -218,6 +218,7 @@ export default function Acp({ isAdmin }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
const [collapsed, setCollapsed] = useState(() => new Set())
|
const [collapsed, setCollapsed] = useState(() => new Set())
|
||||||
|
const hasInitializedCollapse = useRef(false)
|
||||||
const [showModal, setShowModal] = useState(false)
|
const [showModal, setShowModal] = useState(false)
|
||||||
const [form, setForm] = useState({
|
const [form, setForm] = useState({
|
||||||
name: '',
|
name: '',
|
||||||
@@ -245,6 +246,16 @@ export default function Acp({ isAdmin }) {
|
|||||||
}
|
}
|
||||||
}, [isAdmin])
|
}, [isAdmin])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!hasInitializedCollapse.current && forums.length > 0) {
|
||||||
|
const ids = forums
|
||||||
|
.filter((forum) => forum.type === 'category')
|
||||||
|
.map((forum) => String(forum.id))
|
||||||
|
setCollapsed(new Set(ids))
|
||||||
|
hasInitializedCollapse.current = true
|
||||||
|
}
|
||||||
|
}, [forums])
|
||||||
|
|
||||||
const refreshUsers = async () => {
|
const refreshUsers = async () => {
|
||||||
setUsersLoading(true)
|
setUsersLoading(true)
|
||||||
setUsersError('')
|
setUsersError('')
|
||||||
@@ -602,7 +613,7 @@ export default function Acp({ isAdmin }) {
|
|||||||
<div className="bb-muted">{node.description || t('forum.no_description')}</div>
|
<div className="bb-muted">{node.description || t('forum.no_description')}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex align-items-center gap-2">
|
<div className="d-flex align-items-center gap-3">
|
||||||
<span
|
<span
|
||||||
className="bb-drag-handle text-muted"
|
className="bb-drag-handle text-muted"
|
||||||
style={{ cursor: 'grab', display: 'inline-flex' }}
|
style={{ cursor: 'grab', display: 'inline-flex' }}
|
||||||
@@ -651,11 +662,11 @@ export default function Acp({ isAdmin }) {
|
|||||||
<div className="d-flex align-items-center justify-content-between mb-3 gap-3 flex-wrap">
|
<div className="d-flex align-items-center justify-content-between mb-3 gap-3 flex-wrap">
|
||||||
<div className="d-flex align-items-center gap-2">
|
<div className="d-flex align-items-center gap-2">
|
||||||
<h5 className="mb-0">{t('acp.forums_tree')}</h5>
|
<h5 className="mb-0">{t('acp.forums_tree')}</h5>
|
||||||
<Button size="sm" variant="outline-dark" onClick={handleExpandAll}>
|
<Button size="sm" variant="outline-dark" className="bb-acp-action" onClick={handleExpandAll}>
|
||||||
<i className="bi bi-arrows-expand me-1" aria-hidden="true" />
|
<i className="bi bi-arrows-expand me-1" aria-hidden="true" />
|
||||||
{t('acp.expand_all')}
|
{t('acp.expand_all')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="sm" variant="outline-dark" onClick={handleCollapseAll}>
|
<Button size="sm" variant="outline-dark" className="bb-acp-action" onClick={handleCollapseAll}>
|
||||||
<i className="bi bi-arrows-collapse me-1" aria-hidden="true" />
|
<i className="bi bi-arrows-collapse me-1" aria-hidden="true" />
|
||||||
{t('acp.collapse_all')}
|
{t('acp.collapse_all')}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -663,7 +674,8 @@ export default function Acp({ isAdmin }) {
|
|||||||
<div className="d-flex gap-2">
|
<div className="d-flex gap-2">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant={createType === 'category' ? 'dark' : 'outline-dark'}
|
variant="outline-dark"
|
||||||
|
className={`bb-acp-action ${createType === 'category' ? 'bb-acp-action--active' : ''}`}
|
||||||
onClick={() => handleStartCreate('category')}
|
onClick={() => handleStartCreate('category')}
|
||||||
>
|
>
|
||||||
<i className="bi bi-folder2 me-1" aria-hidden="true" />
|
<i className="bi bi-folder2 me-1" aria-hidden="true" />
|
||||||
@@ -671,7 +683,8 @@ export default function Acp({ isAdmin }) {
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant={createType === 'forum' ? 'dark' : 'outline-dark'}
|
variant="outline-dark"
|
||||||
|
className={`bb-acp-action ${createType === 'forum' ? 'bb-acp-action--active' : ''}`}
|
||||||
onClick={() => handleStartCreate('forum')}
|
onClick={() => handleStartCreate('forum')}
|
||||||
>
|
>
|
||||||
<i className="bi bi-chat-left-text me-1" aria-hidden="true" />
|
<i className="bi bi-chat-left-text me-1" aria-hidden="true" />
|
||||||
@@ -720,11 +733,29 @@ export default function Acp({ isAdmin }) {
|
|||||||
<Modal show={showModal} onHide={handleReset} centered size="lg">
|
<Modal show={showModal} onHide={handleReset} centered size="lg">
|
||||||
<Modal.Header closeButton closeVariant="white">
|
<Modal.Header closeButton closeVariant="white">
|
||||||
<Modal.Title>
|
<Modal.Title>
|
||||||
{selectedId ? t('acp.forums_edit_title') : t('acp.forums_create_title')}
|
{selectedId
|
||||||
|
? form.type === 'category'
|
||||||
|
? t('acp.forums_edit_category_title')
|
||||||
|
: t('acp.forums_edit_forum_title')
|
||||||
|
: createType === 'category'
|
||||||
|
? t('acp.forums_create_category_title')
|
||||||
|
: createType === 'forum'
|
||||||
|
? t('acp.forums_create_forum_title')
|
||||||
|
: t('acp.forums_create_title')}
|
||||||
</Modal.Title>
|
</Modal.Title>
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
<p className="bb-muted">{t('acp.forums_form_hint')}</p>
|
<p className="bb-muted">
|
||||||
|
{selectedId
|
||||||
|
? form.type === 'category'
|
||||||
|
? t('acp.forums_edit_category_hint')
|
||||||
|
: t('acp.forums_edit_forum_hint')
|
||||||
|
: createType === 'category'
|
||||||
|
? t('acp.forums_create_category_hint')
|
||||||
|
: createType === 'forum'
|
||||||
|
? t('acp.forums_create_forum_hint')
|
||||||
|
: t('acp.forums_form_hint')}
|
||||||
|
</p>
|
||||||
<Form onSubmit={handleSubmit}>
|
<Form onSubmit={handleSubmit}>
|
||||||
<Form.Group className="mb-3">
|
<Form.Group className="mb-3">
|
||||||
<Form.Label>{t('form.title')}</Form.Label>
|
<Form.Label>{t('form.title')}</Form.Label>
|
||||||
@@ -744,16 +775,18 @@ export default function Acp({ isAdmin }) {
|
|||||||
onChange={(event) => setForm({ ...form, description: event.target.value })}
|
onChange={(event) => setForm({ ...form, description: event.target.value })}
|
||||||
/>
|
/>
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<Form.Group className="mb-3">
|
{selectedId && (
|
||||||
<Form.Label>{t('acp.forums_type')}</Form.Label>
|
<Form.Group className="mb-3">
|
||||||
<Form.Select
|
<Form.Label>{t('acp.forums_type')}</Form.Label>
|
||||||
value={form.type}
|
<Form.Select
|
||||||
onChange={(event) => setForm({ ...form, type: event.target.value })}
|
value={form.type}
|
||||||
>
|
onChange={(event) => setForm({ ...form, type: event.target.value })}
|
||||||
<option value="category">{t('forum.type_category')}</option>
|
>
|
||||||
<option value="forum">{t('forum.type_forum')}</option>
|
<option value="category">{t('forum.type_category')}</option>
|
||||||
</Form.Select>
|
<option value="forum">{t('forum.type_forum')}</option>
|
||||||
</Form.Group>
|
</Form.Select>
|
||||||
|
</Form.Group>
|
||||||
|
)}
|
||||||
<Form.Group className="mb-3">
|
<Form.Group className="mb-3">
|
||||||
<Form.Label>{t('acp.forums_parent')}</Form.Label>
|
<Form.Label>{t('acp.forums_parent')}</Form.Label>
|
||||||
<Form.Select
|
<Form.Select
|
||||||
|
|||||||
@@ -9,11 +9,19 @@
|
|||||||
"acp.forums": "Foren",
|
"acp.forums": "Foren",
|
||||||
"acp.forums_confirm_delete": "Dieses Forum löschen? Das kann nicht rückgängig gemacht werden.",
|
"acp.forums_confirm_delete": "Dieses Forum löschen? Das kann nicht rückgängig gemacht werden.",
|
||||||
"acp.forums_create_title": "Forum oder Kategorie erstellen",
|
"acp.forums_create_title": "Forum oder Kategorie erstellen",
|
||||||
|
"acp.forums_create_category_title": "Kategorie erstellen",
|
||||||
|
"acp.forums_create_forum_title": "Forum erstellen",
|
||||||
"acp.forums_edit_title": "Forum bearbeiten",
|
"acp.forums_edit_title": "Forum bearbeiten",
|
||||||
|
"acp.forums_edit_category_title": "Kategorie bearbeiten",
|
||||||
|
"acp.forums_edit_forum_title": "Forum bearbeiten",
|
||||||
"acp.forums_empty": "Noch keine Foren vorhanden. Lege rechts das erste an.",
|
"acp.forums_empty": "Noch keine Foren vorhanden. Lege rechts das erste an.",
|
||||||
"acp.forums_form_empty_hint": "Wähle ein Forum zum Bearbeiten oder klicke auf Neue Kategorie / Neues Forum.",
|
"acp.forums_form_empty_hint": "Wähle ein Forum zum Bearbeiten oder klicke auf Neue Kategorie / Neues Forum.",
|
||||||
"acp.forums_form_empty_title": "Keine Auswahl",
|
"acp.forums_form_empty_title": "Keine Auswahl",
|
||||||
"acp.forums_form_hint": "Erstelle ein neues Forum oder bearbeite das ausgewählte. Kategorien können Foren und andere Kategorien enthalten.",
|
"acp.forums_form_hint": "Erstelle ein neues Forum oder bearbeite das ausgewählte. Kategorien können Foren und andere Kategorien enthalten.",
|
||||||
|
"acp.forums_create_category_hint": "Erstelle eine neue Kategorie. Kategorien können Foren und andere Kategorien enthalten.",
|
||||||
|
"acp.forums_create_forum_hint": "Erstelle ein neues Forum innerhalb einer Kategorie.",
|
||||||
|
"acp.forums_edit_category_hint": "Aktualisiere die Kategorie. Kategorien können Foren und andere Kategorien enthalten.",
|
||||||
|
"acp.forums_edit_forum_hint": "Aktualisiere die Forum-Details.",
|
||||||
"acp.forums_hint": "Kategorien und Foren in einer Baumansicht verwalten.",
|
"acp.forums_hint": "Kategorien und Foren in einer Baumansicht verwalten.",
|
||||||
"acp.forums_name_required": "Bitte zuerst einen Namen eingeben.",
|
"acp.forums_name_required": "Bitte zuerst einen Namen eingeben.",
|
||||||
"acp.forums_parent": "Ãbergeordnete Kategorie",
|
"acp.forums_parent": "Ãbergeordnete Kategorie",
|
||||||
|
|||||||
@@ -9,11 +9,19 @@
|
|||||||
"acp.forums": "Forums",
|
"acp.forums": "Forums",
|
||||||
"acp.forums_confirm_delete": "Delete this forum? This cannot be undone.",
|
"acp.forums_confirm_delete": "Delete this forum? This cannot be undone.",
|
||||||
"acp.forums_create_title": "Create forum or category",
|
"acp.forums_create_title": "Create forum or category",
|
||||||
|
"acp.forums_create_category_title": "Create category",
|
||||||
|
"acp.forums_create_forum_title": "Create forum",
|
||||||
"acp.forums_edit_title": "Edit forum",
|
"acp.forums_edit_title": "Edit forum",
|
||||||
|
"acp.forums_edit_category_title": "Edit category",
|
||||||
|
"acp.forums_edit_forum_title": "Edit forum",
|
||||||
"acp.forums_empty": "No forums yet. Create the first one on the right.",
|
"acp.forums_empty": "No forums yet. Create the first one on the right.",
|
||||||
"acp.forums_form_empty_hint": "Choose a forum to edit or click New category / New forum to create one.",
|
"acp.forums_form_empty_hint": "Choose a forum to edit or click New category / New forum to create one.",
|
||||||
"acp.forums_form_empty_title": "No selection",
|
"acp.forums_form_empty_title": "No selection",
|
||||||
"acp.forums_form_hint": "Create a new forum or edit the selected one. Categories can contain forums and other categories.",
|
"acp.forums_form_hint": "Create a new forum or edit the selected one. Categories can contain forums and other categories.",
|
||||||
|
"acp.forums_create_category_hint": "Create a new category. Categories can contain forums and other categories.",
|
||||||
|
"acp.forums_create_forum_hint": "Create a new forum within a category.",
|
||||||
|
"acp.forums_edit_category_hint": "Update the category details. Categories can contain forums and other categories.",
|
||||||
|
"acp.forums_edit_forum_hint": "Update the forum details.",
|
||||||
"acp.forums_hint": "Manage categories and forums from a tree view.",
|
"acp.forums_hint": "Manage categories and forums from a tree view.",
|
||||||
"acp.forums_name_required": "Please enter a name before saving.",
|
"acp.forums_name_required": "Please enter a name before saving.",
|
||||||
"acp.forums_parent": "Parent category",
|
"acp.forums_parent": "Parent category",
|
||||||
|
|||||||
Reference in New Issue
Block a user