v0.9.18 branding fixes
This commit is contained in:
@@ -10,7 +10,7 @@
|
|||||||
PROJECT_NAME=jama
|
PROJECT_NAME=jama
|
||||||
|
|
||||||
# Image version to run (set by build.sh, or use 'latest')
|
# Image version to run (set by build.sh, or use 'latest')
|
||||||
JAMA_VERSION=0.9.17
|
JAMA_VERSION=0.9.18
|
||||||
|
|
||||||
# App port — the host port Docker maps to the container
|
# App port — the host port Docker maps to the container
|
||||||
PORT=3000
|
PORT=3000
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jama-backend",
|
"name": "jama-backend",
|
||||||
"version": "0.9.17",
|
"version": "0.9.18",
|
||||||
"description": "TeamChat backend server",
|
"description": "TeamChat backend server",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
2
build.sh
2
build.sh
@@ -13,7 +13,7 @@
|
|||||||
# ─────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
VERSION="${1:-0.9.17}"
|
VERSION="${1:-0.9.18}"
|
||||||
ACTION="${2:-}"
|
ACTION="${2:-}"
|
||||||
REGISTRY="${REGISTRY:-}"
|
REGISTRY="${REGISTRY:-}"
|
||||||
IMAGE_NAME="jama"
|
IMAGE_NAME="jama"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jama-frontend",
|
"name": "jama-frontend",
|
||||||
"version": "0.9.17",
|
"version": "0.9.18",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -13,21 +13,13 @@ const COLOUR_SUGGESTIONS = [
|
|||||||
// A single colour picker card: shows suggestions by default, Custom button opens native picker
|
// A single colour picker card: shows suggestions by default, Custom button opens native picker
|
||||||
function ColourPicker({ label, value, onChange, preview }) {
|
function ColourPicker({ label, value, onChange, preview }) {
|
||||||
const [mode, setMode] = useState('suggestions'); // 'suggestions' | 'custom'
|
const [mode, setMode] = useState('suggestions'); // 'suggestions' | 'custom'
|
||||||
const inputRef = useRef(null);
|
const [draft, setDraft] = useState(value);
|
||||||
|
|
||||||
// Auto-close custom mode as soon as a new colour is committed
|
// Keep draft in sync if parent value changes (e.g. reset)
|
||||||
const handleCustomChange = (e) => {
|
useEffect(() => { setDraft(value); }, [value]);
|
||||||
onChange(e.target.value);
|
|
||||||
// 'change' fires on close of native picker on most platforms;
|
|
||||||
// we also listen to 'input' for live preview but only close on 'change'
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCustomInput = (e) => {
|
const handleSet = () => {
|
||||||
onChange(e.target.value);
|
onChange(draft);
|
||||||
};
|
|
||||||
|
|
||||||
const handleCustomChangeClose = (e) => {
|
|
||||||
onChange(e.target.value);
|
|
||||||
setMode('suggestions');
|
setMode('suggestions');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -62,7 +54,7 @@ function ColourPicker({ label, value, onChange, preview }) {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<button className="btn btn-secondary btn-sm" onClick={() => setMode('custom')}>
|
<button className="btn btn-secondary btn-sm" onClick={() => { setDraft(value); setMode('custom'); }}>
|
||||||
Custom
|
Custom
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
@@ -70,26 +62,28 @@ function ColourPicker({ label, value, onChange, preview }) {
|
|||||||
|
|
||||||
{mode === 'custom' && (
|
{mode === 'custom' && (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||||||
{/* Colour input rendered as a large clickable swatch — works on mobile and desktop */}
|
{/* Large label-wrapped swatch triggers the colour input — reliable on mobile and desktop */}
|
||||||
<label style={{ display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer' }}>
|
<label style={{ display: 'flex', alignItems: 'center', gap: 12, cursor: 'pointer' }}>
|
||||||
<span style={{
|
<span style={{
|
||||||
display: 'inline-block', width: 56, height: 44,
|
display: 'inline-block', width: 56, height: 44,
|
||||||
borderRadius: 8, background: value,
|
borderRadius: 8, background: draft,
|
||||||
border: '2px solid var(--border)',
|
border: '2px solid var(--border)',
|
||||||
boxShadow: '0 1px 4px rgba(0,0,0,0.15)',
|
boxShadow: '0 1px 4px rgba(0,0,0,0.15)',
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
}} />
|
}} />
|
||||||
<input
|
<input
|
||||||
ref={inputRef}
|
|
||||||
type="color"
|
type="color"
|
||||||
value={value}
|
value={draft}
|
||||||
onInput={handleCustomInput}
|
onInput={e => setDraft(e.target.value)}
|
||||||
onChange={handleCustomChangeClose}
|
onChange={e => setDraft(e.target.value)}
|
||||||
style={{ position: 'absolute', opacity: 0, width: 0, height: 0, pointerEvents: 'none' }}
|
style={{ position: 'absolute', opacity: 0, width: 0, height: 0, pointerEvents: 'none' }}
|
||||||
/>
|
/>
|
||||||
<span style={{ fontSize: 13, color: 'var(--text-secondary)', fontFamily: 'monospace' }}>{value}</span>
|
<span style={{ fontSize: 13, color: 'var(--text-secondary)', fontFamily: 'monospace' }}>{draft}</span>
|
||||||
</label>
|
</label>
|
||||||
<div>
|
<div style={{ display: 'flex', gap: 8 }}>
|
||||||
|
<button className="btn btn-primary btn-sm" onClick={handleSet}>
|
||||||
|
Set
|
||||||
|
</button>
|
||||||
<button className="btn btn-secondary btn-sm" onClick={() => setMode('suggestions')}>
|
<button className="btn btn-secondary btn-sm" onClick={() => setMode('suggestions')}>
|
||||||
Back
|
Back
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user