New `./chrome` entrypoint exporting `<AdminShell>` and the header
components (Search, SearchHistory, SearchOptions, Messages, BrowseApps,
HeaderCustomers, HeaderContacts, LogoutButton). Refactored from the
Chronos-style AdminShell that gscCRM was vendoring byte-for-byte —
header/footer/sidebar are now a single shared surface across apps.
Explicit props contract (no site-informations.json, no internal data
sources): `menus`, `apps`, `user`, `brand` are required; `features.*`
flags gate every section (search/browseApps/messages/notifications/
subbar*/pageHeader*/activityPanel/chat/footer); `slots.*` lets apps
inject content; `labels` overrides the next-intl "chrome" namespace.
Locale-aware navigation: chrome calls useLocale() and prepends
/{locale} to internal menu URLs, leaving externals (http(s)://…) and
the "#" sentinel alone. Breadcrumbs and the path-derived page title
strip the leading locale segment so they read "Contacts" not
"En › Contacts". Necessary for `localePrefix: 'always'` consumers like
gscCRM.
Phosphor 2.x icons: `normalizeIconClass` prepends the base `ph` class
(compound selectors `.ph.ph-house:before` require both). All hardcoded
`<i className="ph-…">` sites switched to `ph ph-…`.
`next-intl` and `next-auth` moved to peerDependencies (with devDep
copies for the kit's own typecheck/build). Consumers must symlink their
installed copies into the kit's node_modules at build time — otherwise
useTranslations()/useSession() bind to a separate React context and
next-intl throws Error(void 0) on render.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
104 lines
3.3 KiB
TypeScript
104 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useState } from "react";
|
|
|
|
export function SearchOptions() {
|
|
const [showSearchOptions, setShowSearchOptions] = useState(false);
|
|
|
|
const close = () => {
|
|
if (showSearchOptions) setShowSearchOptions(false);
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<Link
|
|
href="#"
|
|
className="navbar-nav-link align-items-center justify-content-center w-40px h-32px rounded-pill position-absolute end-0 top-50 translate-middle-y p-0 me-1"
|
|
onClick={() => setShowSearchOptions(!showSearchOptions)}
|
|
>
|
|
<i className="ph ph-faders-horizontal"></i>
|
|
</Link>
|
|
|
|
<div
|
|
className={
|
|
showSearchOptions
|
|
? "dropdown-menu w-100 p-3 show"
|
|
: "dropdown-menu w-100 p-3"
|
|
}
|
|
onMouseLeave={close}
|
|
>
|
|
<div className="d-flex align-items-center mb-3">
|
|
<h6 className="mb-0">Search options</h6>
|
|
<Link href="#" className="text-body rounded-pill ms-auto">
|
|
<i className="ph ph-clock-counter-clockwise"></i>
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="mb-3">
|
|
<span className="d-block form-label">Category</span>
|
|
<label className="form-check form-check-inline">
|
|
<input type="checkbox" className="form-check-input" />
|
|
<span className="form-check-label">Invoices</span>
|
|
</label>
|
|
<label className="form-check form-check-inline">
|
|
<input type="checkbox" className="form-check-input" />
|
|
<span className="form-check-label">Files</span>
|
|
</label>
|
|
<label className="form-check form-check-inline">
|
|
<input type="checkbox" className="form-check-input" />
|
|
<span className="form-check-label">Users</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div className="mb-3">
|
|
<label className="form-label">Addition</label>
|
|
<div className="input-group">
|
|
<select className="form-select w-auto flex-grow-0">
|
|
<option value="1">has</option>
|
|
<option value="2">has not</option>
|
|
</select>
|
|
<input
|
|
type="text"
|
|
className="form-control"
|
|
placeholder="Enter the word(s)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mb-3">
|
|
<label className="form-label">Status</label>
|
|
<div className="input-group">
|
|
<select className="form-select w-auto flex-grow-0">
|
|
<option value="1">is</option>
|
|
<option value="2">is not</option>
|
|
</select>
|
|
<select className="form-select">
|
|
<option value="1">Active</option>
|
|
<option value="2">Inactive</option>
|
|
<option value="3">New</option>
|
|
<option value="4">Expired</option>
|
|
<option value="5">Pending</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="d-flex">
|
|
<button type="button" className="btn btn-light">
|
|
Reset
|
|
</button>
|
|
|
|
<div className="ms-auto">
|
|
<button type="button" className="btn btn-light">
|
|
Cancel
|
|
</button>
|
|
<button type="button" className="btn btn-primary ms-2">
|
|
Apply
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|