feat(tactical): enhance symbols palette, instructions, and fix header layout spacing
This commit is contained in:
@@ -229,7 +229,14 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
// Tactical Symbols Layer
|
||||
initialMap.addSource('tactical-symbols-src', {
|
||||
type: 'geojson',
|
||||
data: { type: 'FeatureCollection', features: [] }
|
||||
data: {
|
||||
type: 'FeatureCollection',
|
||||
features: DEFAULT_SYMBOLS.map(s => ({
|
||||
type: 'Feature',
|
||||
properties: { type: s.type, name: s.name },
|
||||
geometry: { type: 'Point', coordinates: [s.lng, s.lat] }
|
||||
})) as any
|
||||
}
|
||||
});
|
||||
|
||||
initialMap.addLayer({
|
||||
@@ -247,6 +254,7 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
'radar', '#06b6d4',
|
||||
'checkpoint', '#eab308',
|
||||
'minefield', '#dc2626',
|
||||
'hlz', '#10b981',
|
||||
'#a855f7'
|
||||
],
|
||||
'circle-stroke-color': '#ffffff',
|
||||
@@ -433,22 +441,23 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
flexDirection: 'column',
|
||||
background: '#0a0e17',
|
||||
color: '#f8fafc',
|
||||
fontFamily: "'IBM Plex Sans Arabic', Inter, system-ui, sans-serif",
|
||||
fontFamily: '-apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "SF Pro Arabic", system-ui, sans-serif',
|
||||
direction: 'rtl',
|
||||
overflow: 'hidden'
|
||||
overflow: 'hidden',
|
||||
paddingTop: 56
|
||||
}}>
|
||||
{/* Top Military HUD Header */}
|
||||
<header style={{
|
||||
height: 54,
|
||||
background: 'rgba(11, 15, 25, 0.95)',
|
||||
borderBottom: '1px solid rgba(255, 255, 255, 0.1)',
|
||||
backdropFilter: 'blur(16px)',
|
||||
height: 52,
|
||||
background: '#0f172a',
|
||||
borderBottom: '1px solid #1e293b',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: '0 20px',
|
||||
zIndex: 100,
|
||||
gap: 16
|
||||
padding: '0 18px',
|
||||
zIndex: 50,
|
||||
gap: 14,
|
||||
flexShrink: 0
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||
<div style={{
|
||||
@@ -847,6 +856,18 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
background: 'rgba(168, 85, 247, 0.12)',
|
||||
border: '1px solid rgba(168, 85, 247, 0.3)',
|
||||
padding: '8px 10px',
|
||||
borderRadius: 8,
|
||||
fontSize: '0.78rem',
|
||||
color: '#e9d5ff',
|
||||
lineHeight: 1.4
|
||||
}}>
|
||||
🎯 <strong>طريقة التثبيت:</strong> اختر نوع الرمز واسم الوحدة، ثم <strong>انقر على أي نقطة بالخريطة</strong> لإسقاطه فوراً وتثبيت إحداثياته.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style={{ fontSize: '0.75rem', color: '#94a3b8', display: 'block', marginBottom: 4 }}>نوع الرمز العسكري:</label>
|
||||
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
|
||||
@@ -854,22 +875,26 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
{ id: 'friendly', label: '🟦 وحدة صديقة' },
|
||||
{ id: 'hostile', label: '🟥 هدف معادي' },
|
||||
{ id: 'artillery', label: '🟧 مربض مدفعية' },
|
||||
{ id: 'radar', label: '🟦 محطة رادار' },
|
||||
{ id: 'radar', label: '🩵 محطة رادار' },
|
||||
{ id: 'checkpoint', label: '🟨 نقطة سيطرة' },
|
||||
{ id: 'op', label: '🟪 نقطة مراقبة' },
|
||||
{ id: 'minefield', label: '⛔ حقل ألغام' },
|
||||
{ id: 'hlz', label: '🚁 مهبط مروحيات' },
|
||||
].map(sym => (
|
||||
<button
|
||||
key={sym.id}
|
||||
onClick={() => setSelectedSymbolType(sym.id)}
|
||||
style={{
|
||||
background: selectedSymbolType === sym.id ? 'rgba(168, 85, 247, 0.25)' : 'rgba(255,255,255,0.05)',
|
||||
border: selectedSymbolType === sym.id ? '1px solid #a855f7' : '1px solid rgba(255,255,255,0.1)',
|
||||
background: selectedSymbolType === sym.id ? 'rgba(168, 85, 247, 0.35)' : 'rgba(255,255,255,0.05)',
|
||||
border: selectedSymbolType === sym.id ? '1px solid #c084fc' : '1px solid rgba(255,255,255,0.1)',
|
||||
color: '#fff',
|
||||
padding: '6px 8px',
|
||||
borderRadius: 6,
|
||||
fontSize: '0.75rem',
|
||||
fontWeight: selectedSymbolType === sym.id ? 700 : 500,
|
||||
cursor: 'pointer',
|
||||
textAlign: 'right'
|
||||
textAlign: 'right',
|
||||
transition: 'all 0.15s ease'
|
||||
}}
|
||||
>
|
||||
{sym.label}
|
||||
@@ -882,7 +907,7 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
<label style={{ fontSize: '0.75rem', color: '#94a3b8', display: 'block', marginBottom: 4 }}>تسمية الرمز / الوحدة:</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="مثال: سرية الدبابات 1"
|
||||
placeholder="مثال: سرية الدبابات 1 / بطارية صواريخ"
|
||||
value={newSymbolName}
|
||||
onChange={e => setNewSymbolName(e.target.value)}
|
||||
style={{ width: '100%', background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.15)', color: '#fff', padding: '8px', borderRadius: 8, fontSize: '0.8rem' }}
|
||||
@@ -890,12 +915,30 @@ export const TacticalDefenseView: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* Active Symbols List */}
|
||||
<div style={{ marginTop: 8 }}>
|
||||
<div style={{ fontSize: '0.8rem', color: '#94a3b8', marginBottom: 6 }}>الرموز المنتشرة على الخريطة ({symbols.length}):</div>
|
||||
<div style={{ marginTop: 4 }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
|
||||
<span style={{ fontSize: '0.8rem', color: '#94a3b8' }}>الرموز المنتشرة ({symbols.length}):</span>
|
||||
{symbols.length > 0 && (
|
||||
<button
|
||||
onClick={() => setSymbols([])}
|
||||
style={{ background: 'none', border: 'none', color: '#ef4444', fontSize: '0.72rem', cursor: 'pointer', textDecoration: 'underline' }}
|
||||
>
|
||||
مسح الكل
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 6, maxHeight: 180, overflowY: 'auto' }}>
|
||||
{symbols.map(s => (
|
||||
<div key={s.id} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: 'rgba(255,255,255,0.04)', padding: '6px 10px', borderRadius: 6, fontSize: '0.78rem' }}>
|
||||
<span>{s.name}</span>
|
||||
<span style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||
<span style={{
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: '50%',
|
||||
background: s.type === 'friendly' ? '#3b82f6' : s.type === 'hostile' ? '#ef4444' : s.type === 'artillery' ? '#f97316' : s.type === 'radar' ? '#06b6d4' : s.type === 'checkpoint' ? '#eab308' : s.type === 'minefield' ? '#dc2626' : s.type === 'hlz' ? '#10b981' : '#a855f7'
|
||||
}} />
|
||||
<span>{s.name}</span>
|
||||
</span>
|
||||
<button
|
||||
onClick={() => setSymbols(symbols.filter(x => x.id !== s.id))}
|
||||
style={{ background: 'none', border: 'none', color: '#ef4444', cursor: 'pointer', padding: 2 }}
|
||||
|
||||
Reference in New Issue
Block a user