100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
/*
|
|
* 현장 탭 — 역할별 현장 기능 허브.
|
|
* 장치업체 → 현장 체크리스트(SCR-M1), 홀매니저 → 현장 검수(SCR-M2).
|
|
*/
|
|
import { Ionicons } from '@expo/vector-icons';
|
|
import { router } from 'expo-router';
|
|
import React from 'react';
|
|
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
|
|
import { Banner } from '../../components/Banner';
|
|
import { useAuth } from '../../context/AuthContext';
|
|
import { colors, radius, spacing, type } from '../../theme';
|
|
|
|
export default function FieldScreen() {
|
|
const { activeWorkspace, user } = useAuth();
|
|
const role = activeWorkspace?.myRole;
|
|
const isHallManager = user?.hallManager || role === 'HALL_MANAGER';
|
|
const isContractor = role === 'CONTRACTOR';
|
|
|
|
return (
|
|
<ScrollView contentContainerStyle={styles.scroll}>
|
|
<Text style={styles.title}>현장 업무</Text>
|
|
|
|
{!isContractor && !isHallManager ? (
|
|
<Banner tone="info">
|
|
현장 기능은 장치·시공업체(체크리스트)와 홀매니저(검수) 역할에서 제공됩니다.
|
|
</Banner>
|
|
) : null}
|
|
|
|
{isContractor ? (
|
|
<Tile
|
|
icon="clipboard-outline"
|
|
title="현장 체크리스트"
|
|
desc="장치 공정 확인 · 사진 첨부 · 검수 요청"
|
|
onPress={() => router.push('/checklist')}
|
|
/>
|
|
) : null}
|
|
|
|
{isHallManager ? (
|
|
<Tile
|
|
icon="shield-checkmark-outline"
|
|
title="현장 검수"
|
|
desc="승인 도면 vs 현장 사진 · 적합/부적합 판정"
|
|
onPress={() => router.push('/inspection')}
|
|
/>
|
|
) : null}
|
|
</ScrollView>
|
|
);
|
|
}
|
|
|
|
function Tile({
|
|
icon,
|
|
title,
|
|
desc,
|
|
onPress,
|
|
}: {
|
|
icon: keyof typeof Ionicons.glyphMap;
|
|
title: string;
|
|
desc: string;
|
|
onPress: () => void;
|
|
}) {
|
|
return (
|
|
<Pressable style={styles.tile} onPress={onPress}>
|
|
<View style={styles.tileIcon}>
|
|
<Ionicons name={icon} size={24} color={colors.primary600} />
|
|
</View>
|
|
<View style={styles.tileBody}>
|
|
<Text style={styles.tileTitle}>{title}</Text>
|
|
<Text style={styles.tileDesc}>{desc}</Text>
|
|
</View>
|
|
<Ionicons name="chevron-forward" size={20} color={colors.neutral500} />
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
scroll: { padding: spacing.md, gap: spacing.md },
|
|
title: { fontSize: type.h2.fontSize, fontWeight: '700', color: colors.neutral900 },
|
|
tile: {
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
gap: 12,
|
|
backgroundColor: colors.white,
|
|
borderWidth: 1,
|
|
borderColor: colors.neutral200,
|
|
borderRadius: radius.md,
|
|
padding: spacing.md,
|
|
},
|
|
tileIcon: {
|
|
width: 44,
|
|
height: 44,
|
|
borderRadius: radius.sm,
|
|
backgroundColor: colors.primary050,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
tileBody: { flex: 1, gap: 2 },
|
|
tileTitle: { fontSize: type.h3.fontSize, fontWeight: '600', color: colors.neutral900 },
|
|
tileDesc: { fontSize: type.caption.fontSize, color: colors.neutral500 },
|
|
});
|