chore: UI and i18n updates — HomeScreen, ProfileScreen, Documents, Generate and locales

This commit is contained in:
2025-10-07 19:07:10 +05:30
parent 50972239b3
commit e0c68dbbd2
14 changed files with 1399 additions and 570 deletions

3
add-translations.ps1 Normal file
View File

@@ -0,0 +1,3 @@
# Script to add translations - this will be a reference
Write-Host 'Adding translations to locale files...'
Write-Host 'Files to update: bn, te, gu, kn, ml, mr, pa'

View File

@@ -299,6 +299,57 @@ export const bn = {
error: 'ত্রুটি', error: 'ত্রুটি',
success: 'সফলতা', success: 'সফলতা',
// Documents Screen
documentsScreen: {
title: 'নথি',
subtitle: 'AI-চালিত নথি ব্যবস্থাপনা',
overview: 'সারসংক্ষেপ',
recentActivity: 'সাম্প্রতিক কার্যকলাপ',
quickActions: 'দ্রুত কাজ',
activities: {
invoiceUploaded: 'ইনভয়েস #2024-089 আপলোড করা হয়েছে',
contractSigned: 'চুক্তি স্বাক্ষরিত ও সংরক্ষিত',
legalUpdated: 'আইনি নথি আপডেট করা হয়েছে',
hoursAgo: '{{hours}} ঘন্টা আগে',
yesterday: 'গতকাল',
daysAgo: '{{days}} দিন আগে',
},
actions: {
searchDocuments: 'নথি খুঁজুন',
searchDescription: 'যেকোনো নথি তাৎক্ষণিক খুঁজে পান',
bulkUpload: 'বাল্ক আপলোড',
bulkUploadDescription: 'একসাথে একাধিক ফাইল আপলোড করুন',
},
},
// Generate Screen
generateScreen: {
title: 'তৈরি করুন',
subtitle: 'AI-চালিত বিষয়বস্তু তৈরি',
seasonalCampaigns: 'মৌসুমী প্রচারাভিযান',
contentTemplates: 'বিষয়বস্তু টেমপ্লেট',
customization: 'কাস্টমাইজেশন',
templates: {
blogPost: 'ব্লগ পোস্ট',
blogPostDescription: 'SEO-অপ্টিমাইজড ব্লগ কনটেন্ট তৈরি করুন',
emailCampaign: 'ইমেল প্রচারাভিযান',
emailCampaignDescription: 'আকর্ষণীয় ইমেল নিউজলেটার তৈরি করুন',
socialMedia: 'সোশ্যাল মিডিয়া',
socialMediaDescription: 'সকল প্ল্যাটফর্মের জন্য পোস্ট তৈরি করুন',
designAssets: 'ডিজাইন সম্পদ',
designAssetsDescription: 'ব্র্যান্ডেড ভিজ্যুয়াল তৈরি করুন',
},
brandVoiceDescription: 'আপনার অনন্য ব্র্যান্ড টোন সংজ্ঞায়িত করুন',
},
// Profile Screen
profileScreen: {
profileSettings: 'প্রোফাইল ও সেটিংস',
generateContent: 'বিষয়বস্তু তৈরি করুন',
more: 'আরও',
signOut: 'সাইন আউট',
},
tasksScreen: { tasksScreen: {
tabs: { tabs: {
hr: 'মানব সম্পদ', hr: 'মানব সম্পদ',

View File

@@ -337,6 +337,57 @@ export const en = {
subtitle: 'Choose your preferred language to localise the experience.', subtitle: 'Choose your preferred language to localise the experience.',
}, },
// Documents Screen
documentsScreen: {
title: 'Documents',
subtitle: 'AI-powered document management',
overview: 'Overview',
recentActivity: 'Recent Activity',
quickActions: 'Quick Actions',
activities: {
invoiceUploaded: 'Invoice #2024-089 uploaded',
contractSigned: 'Contract signed & archived',
legalUpdated: 'Legal doc updated',
hoursAgo: '{{hours}} hours ago',
yesterday: 'Yesterday',
daysAgo: '{{days}} days ago',
},
actions: {
searchDocuments: 'Search Documents',
searchDescription: 'Find any document instantly',
bulkUpload: 'Bulk Upload',
bulkUploadDescription: 'Upload multiple files at once',
},
},
// Generate Screen
generateScreen: {
title: 'Generate',
subtitle: 'AI-powered content creation',
seasonalCampaigns: 'Seasonal Campaigns',
contentTemplates: 'Content Templates',
customization: 'Customization',
templates: {
blogPost: 'Blog Post',
blogPostDescription: 'Generate SEO-optimized blog content',
emailCampaign: 'Email Campaign',
emailCampaignDescription: 'Create engaging email newsletters',
socialMedia: 'Social Media',
socialMediaDescription: 'Craft posts for all platforms',
designAssets: 'Design Assets',
designAssetsDescription: 'Generate branded visuals',
},
brandVoiceDescription: 'Define your unique brand tone',
},
// Profile Screen
profileScreen: {
profileSettings: 'Profile & Settings',
generateContent: 'Generate Content',
more: 'More',
signOut: 'Sign Out',
},
// Tasks Screen // Tasks Screen
tasksScreen: { tasksScreen: {
tabs: { tabs: {

View File

@@ -337,6 +337,57 @@ export const hi = {
subtitle: 'अपनी पसंदीदा भाषा चुनें ताकि अनुभव स्थानीय हो सके।', subtitle: 'अपनी पसंदीदा भाषा चुनें ताकि अनुभव स्थानीय हो सके।',
}, },
// Documents Screen
documentsScreen: {
title: 'दस्तावेज़',
subtitle: 'AI-संचालित दस्तावेज़ प्रबंधन',
overview: 'अवलोकन',
recentActivity: 'हाल की गतिविधि',
quickActions: 'त्वरित कार्य',
activities: {
invoiceUploaded: 'चालान #2024-089 अपलोड किया गया',
contractSigned: 'अनुबंध हस्ताक्षरित और संग्रहीत',
legalUpdated: 'कानूनी दस्तावेज़ अपडेट किया गया',
hoursAgo: '{{hours}} घंटे पहले',
yesterday: 'कल',
daysAgo: '{{days}} दिन पहले',
},
actions: {
searchDocuments: 'दस्तावेज़ खोजें',
searchDescription: 'किसी भी दस्तावेज़ को तुरंत खोजें',
bulkUpload: 'बल्क अपलोड',
bulkUploadDescription: 'एक साथ कई फाइलें अपलोड करें',
},
},
// Generate Screen
generateScreen: {
title: 'उत्पन्न करें',
subtitle: 'AI-संचालित सामग्री निर्माण',
seasonalCampaigns: 'मौसमी अभियान',
contentTemplates: 'सामग्री टेम्पलेट',
customization: 'अनुकूलन',
templates: {
blogPost: 'ब्लॉग पोस्ट',
blogPostDescription: 'SEO-अनुकूलित ब्लॉग सामग्री उत्पन्न करें',
emailCampaign: 'ईमेल अभियान',
emailCampaignDescription: 'आकर्षक ईमेल न्यूज़लेटर बनाएं',
socialMedia: 'सोशल मीडिया',
socialMediaDescription: 'सभी प्लेटफ़ॉर्म के लिए पोस्ट तैयार करें',
designAssets: 'डिज़ाइन संपत्ति',
designAssetsDescription: 'ब्रांडेड विज़ुअल उत्पन्न करें',
},
brandVoiceDescription: 'अपना अनूठा ब्रांड टोन परिभाषित करें',
},
// Profile Screen
profileScreen: {
profileSettings: 'प्रोफ़ाइल और सेटिंग्स',
generateContent: 'सामग्री उत्पन्न करें',
more: 'अधिक',
signOut: 'साइन आउट',
},
// Tasks Screen // Tasks Screen
tasksScreen: { tasksScreen: {
tabs: { tabs: {

View File

@@ -299,6 +299,57 @@ export const ta = {
subtitle: 'அனுபவத்தை உள்ளூர்மயமாக்க உங்கள் விருப்ப மொழியைத் தேர்வு செய்யவும்.', subtitle: 'அனுபவத்தை உள்ளூர்மயமாக்க உங்கள் விருப்ப மொழியைத் தேர்வு செய்யவும்.',
}, },
// Documents Screen
documentsScreen: {
title: 'ஆவணங்கள்',
subtitle: 'AI-இயக்கப்படும் ஆவண மேலாண்மை',
overview: 'கண்ணோட்டம்',
recentActivity: 'சமீபத்திய செயல்பாடு',
quickActions: 'விரைவு செயல்கள்',
activities: {
invoiceUploaded: 'விலைப்பட்டியல் #2024-089 பதிவேற்றப்பட்டது',
contractSigned: 'ஒப்பந்தம் கையெழுத்திடப்பட்டது & காப்பகப்படுத்தப்பட்டது',
legalUpdated: 'சட்ட ஆவணம் புதுப்பிக்கப்பட்டது',
hoursAgo: '{{hours}} மணி நேரம் முன்பு',
yesterday: 'நேற்று',
daysAgo: '{{days}} நாட்களுக்கு முன்பு',
},
actions: {
searchDocuments: 'ஆவணங்களைத் தேடு',
searchDescription: 'எந்த ஆவணத்தையும் உடனடியாக கண்டறியவும்',
bulkUpload: 'மொத்த பதிவேற்றம்',
bulkUploadDescription: 'ஒரே நேரத்தில் பல கோப்புகளை பதிவேற்றவும்',
},
},
// Generate Screen
generateScreen: {
title: 'உருவாக்கு',
subtitle: 'AI-இயக்கப்படும் உள்ளடக்க உருவாக்கம்',
seasonalCampaigns: 'பருவகால பிரச்சாரங்கள்',
contentTemplates: 'உள்ளடக்க வார்ப்புருக்கள்',
customization: 'தனிப்பயனாக்கம்',
templates: {
blogPost: 'வலைப்பதிவு இடுகை',
blogPostDescription: 'SEO-உகந்த வலைப்பதிவு உள்ளடக்கத்தை உருவாக்கவும்',
emailCampaign: 'மின்னஞ்சல் பிரச்சாரம்',
emailCampaignDescription: 'ஈர்க்கும் மின்னஞ்சல் செய்திமடல்களை உருவாக்கவும்',
socialMedia: 'சமூக ஊடகம்',
socialMediaDescription: 'அனைத்து தளங்களுக்கும் இடுகைகளை உருவாக்கவும்',
designAssets: 'வடிவமைப்பு சொத்துக்கள்',
designAssetsDescription: 'பிராண்ட் காட்சிப்படுத்தல்களை உருவாக்கவும்',
},
brandVoiceDescription: 'உங்கள் தனித்துவமான பிராண்ட் குரலை வரையறுக்கவும்',
},
// Profile Screen
profileScreen: {
profileSettings: 'சுயவிவரம் & அமைப்புகள்',
generateContent: 'உள்ளடக்கத்தை உருவாக்கு',
more: 'மேலும்',
signOut: 'வெளியேறு',
},
tasksScreen: { tasksScreen: {
tabs: { tabs: {
hr: 'மனிதவள', hr: 'மனிதவள',

View File

@@ -1,81 +1,276 @@
import React from 'react'; import React, { useMemo } from 'react';
import { StyleSheet, Text, View } from 'react-native'; import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { Screen } from '../components/Screen'; import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard'; import { AgentCard } from '../components/AgentCard';
import { ListButton } from '../components/ListButton'; import { colors, typography, spacing, borderRadius, shadows, iconSizes } from '../theme';
import { colors } from '../theme/colors';
type Agent = {
id: string;
name: string;
role: string;
avatar: string;
status: 'active' | 'idle' | 'busy';
};
const agentConfigs: Array<{
id: string;
avatar: string;
status: Agent['status'];
nameKey: string;
roleKey: string;
}> = [
{
id: 'evelyn',
avatar: 'https://i.pravatar.cc/120?img=1',
status: 'active',
nameKey: 'evelyn',
roleKey: 'agentsScreen.roles.accountant',
},
{
id: 'malik',
avatar: 'https://i.pravatar.cc/120?img=2',
status: 'active',
nameKey: 'malik',
roleKey: 'agentsScreen.roles.hrManager',
},
{
id: 'aria',
avatar: 'https://i.pravatar.cc/120?img=3',
status: 'idle',
nameKey: 'aria',
roleKey: 'agentsScreen.roles.adminAssistant',
},
{
id: 'marcus',
avatar: 'https://i.pravatar.cc/120?img=4',
status: 'active',
nameKey: 'agentsScreen.names.marcus',
roleKey: 'agentsScreen.roles.strategyAdvisor',
},
{
id: 'sofia',
avatar: 'https://i.pravatar.cc/120?img=5',
status: 'busy',
nameKey: 'agentsScreen.names.sofia',
roleKey: 'agentsScreen.roles.crmSpecialist',
},
{
id: 'alex',
avatar: 'https://i.pravatar.cc/120?img=6',
status: 'idle',
nameKey: 'agentsScreen.names.alex',
roleKey: 'agentsScreen.roles.contentDesigner',
},
];
export const AgentsScreen: React.FC = () => { export const AgentsScreen: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const agents: Agent[] = useMemo(
() =>
agentConfigs.map((config) => ({
id: config.id,
avatar: config.avatar,
status: config.status,
name: t(config.nameKey),
role: t(config.roleKey),
})),
[t]
);
const statusSummary = useMemo(
() => [
{
color: '#4ADE80',
label: t('agentsScreen.statusSummary.active', { count: 3 }),
},
{
color: '#FBBF24',
label: t('agentsScreen.statusSummary.idle', { count: 2 }),
},
{
color: '#F87171',
label: t('agentsScreen.statusSummary.busy', { count: 1 }),
},
],
[t]
);
const quickActions = useMemo(
() => [
{
icon: 'message-text',
label: t('agentsScreen.actions.chat'),
},
{
icon: 'history',
label: t('agentsScreen.actions.reports'),
},
],
[t]
);
return ( return (
<Screen> <Screen>
<View style={styles.headerRow}> <View style={styles.header}>
<Text style={styles.title}>{t('aiAgents')}</Text> <View>
<Text style={styles.title}>{t('agentsScreen.title')}</Text>
<Text style={styles.subtitle}>{t('agentsScreen.subtitle')}</Text>
</View>
<TouchableOpacity
style={styles.addButton}
accessibilityRole="button"
accessibilityLabel={t('agentsScreen.actions.addAgent')}
>
<MaterialCommunityIcons name="plus" size={iconSizes.md} color={colors.background} />
</TouchableOpacity>
</View> </View>
<SectionCard title={t('campaignArchitect')} description={t('pipelineOrchestrator')}> {/* Active Agents Stats */}
<View style={styles.agentCard}> <View style={styles.statsCard}>
<View style={styles.statusPill}> {statusSummary.map((item, index) => (
<Text style={styles.statusLabel}>{t('transcodingDataFeeds')}</Text> <React.Fragment key={item.label}>
</View> {index > 0 && <View style={styles.statDivider} />}
<Text style={styles.agentSummary}> <View style={styles.statItem}>
{t('agentSummary')} <View style={[styles.statDot, { backgroundColor: item.color }]} />
</Text> <Text style={styles.statLabel}>{item.label}</Text>
</View> </View>
</SectionCard> </React.Fragment>
))}
</View>
<View style={styles.actionsList}> {/* Agents Grid */}
<ListButton label={t('transcoved')} /> <View style={styles.sectionHeader}>
<ListButton label={t('invoices')} /> <Text style={styles.sectionTitle}>{t('agentsScreen.availableTitle')}</Text>
<ListButton label={t('reports')} /> <Text style={styles.sectionSubtitle}>{t('agentsScreen.availableSubtitle')}</Text>
</View>
<View style={styles.agentsGrid}>
{agents.map((agent) => (
<AgentCard
key={agent.id}
name={agent.name}
role={agent.role}
avatar={agent.avatar}
status={agent.status}
onPress={() => {}}
/>
))}
</View>
{/* Quick Actions */}
<View style={styles.quickActions}>
<Text style={styles.sectionTitle}>{t('agentsScreen.quickActionsTitle')}</Text>
<View style={styles.actionsGrid}>
{quickActions.map((action) => (
<TouchableOpacity key={action.label} style={styles.actionButton}>
<MaterialCommunityIcons name={action.icon} size={iconSizes.lg} color={colors.highlight} />
<Text style={styles.actionLabel}>{action.label}</Text>
</TouchableOpacity>
))}
</View>
</View> </View>
</Screen> </Screen>
); );
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
headerRow: { header: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'flex-start',
marginBottom: spacing.lg,
}, },
title: { title: {
fontSize: 32, ...typography.h1,
fontWeight: '900',
color: colors.highlightAlt, color: colors.highlightAlt,
letterSpacing: 0.8,
}, },
agentCard: { subtitle: {
gap: 16, ...typography.body,
},
statusPill: {
alignSelf: 'flex-start',
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 20,
backgroundColor: 'rgba(14, 95, 79, 0.9)',
borderWidth: 2,
borderColor: colors.borderStrong,
shadowColor: colors.highlight,
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.4,
shadowRadius: 10,
elevation: 6,
},
statusLabel: {
fontSize: 13,
fontWeight: '700',
color: colors.highlightAlt,
letterSpacing: 0.4,
},
agentSummary: {
fontSize: 14,
color: colors.textSecondary, color: colors.textSecondary,
lineHeight: 22, marginTop: spacing.xs,
}, },
actionsList: { addButton: {
gap: 14, width: 48,
height: 48,
borderRadius: borderRadius.md,
backgroundColor: colors.highlight,
alignItems: 'center',
justifyContent: 'center',
...shadows.glow,
},
statsCard: {
flexDirection: 'row',
padding: spacing.lg,
borderRadius: borderRadius.lg,
backgroundColor: colors.surfaceAlt,
borderWidth: 2,
borderColor: colors.border,
marginBottom: spacing.lg,
...shadows.md,
},
statItem: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
gap: spacing.sm,
},
statDot: {
width: 8,
height: 8,
borderRadius: 4,
},
statLabel: {
...typography.bodyBold,
color: colors.textPrimary,
},
statDivider: {
width: 1,
height: '100%',
backgroundColor: colors.border,
},
sectionHeader: {
marginBottom: spacing.lg,
},
sectionTitle: {
...typography.h3,
color: colors.highlightAlt,
},
sectionSubtitle: {
...typography.caption,
color: colors.textSecondary,
marginTop: 4,
},
agentsGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: spacing.md,
marginBottom: spacing.lg,
},
quickActions: {
marginTop: spacing.lg,
},
actionsGrid: {
flexDirection: 'row',
gap: spacing.md,
marginTop: spacing.lg,
},
actionButton: {
flex: 1,
padding: spacing.lg,
borderRadius: borderRadius.lg,
backgroundColor: colors.surfaceAlt,
borderWidth: 2,
borderColor: colors.border,
alignItems: 'center',
gap: spacing.sm,
...shadows.md,
},
actionLabel: {
...typography.caption,
color: colors.textPrimary,
textAlign: 'center',
}, },
}); });

View File

@@ -1,50 +1 @@
import React from 'react'; export { TasksScreen as CRMScreen } from './TasksScreen';
import { StyleSheet, Text, View } from 'react-native';
import { useTranslation } from 'react-i18next';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard';
import { ListButton } from '../components/ListButton';
import { TasksStackParamList } from '../types/navigation';
import { TaskHeader } from '../components/TaskHeader';
import { colors } from '../theme/colors';
type Props = NativeStackScreenProps<TasksStackParamList, 'CRM'>;
export const CRMScreen: React.FC<Props> = ({ navigation }) => {
const { t } = useTranslation();
return (
<Screen>
<TaskHeader
title={t('crm')}
caption={t('signalStudio')}
active="CRM"
onNavigate={screen => navigation.navigate(screen)}
/>
<SectionCard title={t('aiMisceles')} description={t('leadsMonitor')}>
<Text style={styles.cardBody}>
{t('pipelineExposure')}
</Text>
</SectionCard>
<View style={styles.actionsList}>
<ListButton label={t('aiInsights')} />
<ListButton label={t('recommendations')} />
<ListButton label={t('playbooks')} />
</View>
</Screen>
);
};
const styles = StyleSheet.create({
cardBody: {
fontSize: 14,
color: colors.textSecondary,
lineHeight: 22,
},
actionsList: {
gap: 14,
},
});

View File

@@ -1,45 +1,212 @@
import React from 'react'; import React from 'react';
import { StyleSheet, Text, View } from 'react-native'; import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { Screen } from '../components/Screen'; import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard'; import { QuickActionCard } from '../components/QuickActionCard';
import { ListButton } from '../components/ListButton'; import { StatCard } from '../components/StatCard';
import { colors } from '../theme/colors'; import { colors, spacing, borderRadius, typography, shadows, iconSizes } from '../theme';
type DocumentCategory = {
id: string;
icon: string;
label: string;
count: number;
color?: string;
};
export const DocumentsScreen: React.FC = () => { export const DocumentsScreen: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const documentCategories: DocumentCategory[] = [
{ id: 'invoices', icon: 'file-document', label: t('invoices'), count: 24 },
{ id: 'contracts', icon: 'file-sign', label: t('contracts'), count: 8, color: '#4ADE80' },
{ id: 'legal', icon: 'scale-balance', label: t('legal'), count: 12, color: '#F59E0B' },
{ id: 'hr', icon: 'account-tie', label: t('hr'), count: 16, color: '#3B82F6' },
];
return ( return (
<Screen> <Screen showBackground={true}>
<View style={styles.headerRow}> {/* Header */}
<Text style={styles.title}>{t('documents')}</Text> <View style={styles.header}>
<View>
<Text style={styles.title}>{t('documentsScreen.title')}</Text>
<Text style={styles.subtitle}>{t('documentsScreen.subtitle')}</Text>
</View>
<TouchableOpacity style={styles.addButton}>
<MaterialCommunityIcons name="plus" size={iconSizes.md} color={colors.background} />
</TouchableOpacity>
</View> </View>
<SectionCard title={t('newDocument')} description={t('autoPrepped')}> {/* Stats Overview */}
<View style={styles.actionsList}> <View style={styles.section}>
<ListButton label={t('invoices')} /> <Text style={styles.sectionLabel}>{t('documentsScreen.overview')}</Text>
<ListButton label={t('contracts')} /> <View style={styles.statsGrid}>
<ListButton label={t('legal')} /> {documentCategories.map((category) => (
<ListButton label={t('hr')} /> <StatCard
key={category.id}
icon={category.icon}
label={category.label}
value={category.count.toString()}
color={category.color}
style={styles.statCard}
/>
))}
</View> </View>
</SectionCard> </View>
{/* Recent Activity */}
<View style={styles.section}>
<Text style={styles.sectionLabel}>{t('documentsScreen.recentActivity')}</Text>
<View style={styles.activityCard}>
<View style={styles.activityItem}>
<View style={styles.activityIcon}>
<MaterialCommunityIcons name="file-upload" size={iconSizes.md} color={colors.highlight} />
</View>
<View style={styles.activityContent}>
<Text style={styles.activityTitle}>{t('documentsScreen.activities.invoiceUploaded')}</Text>
<Text style={styles.activityTime}>{t('documentsScreen.activities.hoursAgo', { hours: 2 })}</Text>
</View>
</View>
<View style={styles.activityDivider} />
<View style={styles.activityItem}>
<View style={styles.activityIcon}>
<MaterialCommunityIcons name="file-check" size={iconSizes.md} color="#4ADE80" />
</View>
<View style={styles.activityContent}>
<Text style={styles.activityTitle}>{t('documentsScreen.activities.contractSigned')}</Text>
<Text style={styles.activityTime}>{t('documentsScreen.activities.yesterday')}</Text>
</View>
</View>
<View style={styles.activityDivider} />
<View style={styles.activityItem}>
<View style={styles.activityIcon}>
<MaterialCommunityIcons name="file-document-edit" size={iconSizes.md} color="#F59E0B" />
</View>
<View style={styles.activityContent}>
<Text style={styles.activityTitle}>{t('documentsScreen.activities.legalUpdated')}</Text>
<Text style={styles.activityTime}>{t('documentsScreen.activities.daysAgo', { days: 3 })}</Text>
</View>
</View>
</View>
</View>
{/* Quick Actions */}
<View style={styles.section}>
<Text style={styles.sectionLabel}>{t('documentsScreen.quickActions')}</Text>
<View style={styles.actionsContainer}>
<QuickActionCard
icon="file-plus"
label={t('newDocument')}
description={t('autoPrepped')}
onPress={() => {}}
/>
<QuickActionCard
icon="magnify"
label={t('documentsScreen.actions.searchDocuments')}
description={t('documentsScreen.actions.searchDescription')}
onPress={() => {}}
/>
<QuickActionCard
icon="cloud-upload"
label={t('documentsScreen.actions.bulkUpload')}
description={t('documentsScreen.actions.bulkUploadDescription')}
onPress={() => {}}
/>
</View>
</View>
</Screen> </Screen>
); );
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
headerRow: { header: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'flex-start',
marginBottom: spacing.lg,
}, },
title: { title: {
fontSize: 32, ...typography.h1,
fontWeight: '900',
color: colors.highlightAlt, color: colors.highlightAlt,
letterSpacing: 0.8,
}, },
actionsList: { subtitle: {
gap: 14, ...typography.body,
color: colors.textSecondary,
marginTop: spacing.xs,
},
addButton: {
width: 48,
height: 48,
borderRadius: borderRadius.md,
backgroundColor: colors.highlight,
alignItems: 'center',
justifyContent: 'center',
...shadows.glow,
},
section: {
marginBottom: spacing.xl,
},
sectionLabel: {
...typography.caption,
fontSize: 11,
fontWeight: '800',
color: colors.textSecondary,
textTransform: 'uppercase',
letterSpacing: 1.2,
marginBottom: spacing.md,
},
statsGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: spacing.md,
},
statCard: {
flex: 1,
minWidth: 150,
},
activityCard: {
backgroundColor: colors.surfaceAlt,
borderRadius: borderRadius.lg,
padding: spacing.lg,
borderWidth: 2,
borderColor: colors.border,
...shadows.md,
},
activityItem: {
flexDirection: 'row',
alignItems: 'center',
gap: spacing.md,
},
activityIcon: {
width: 44,
height: 44,
borderRadius: borderRadius.md,
backgroundColor: colors.surface,
borderWidth: 2,
borderColor: colors.border,
alignItems: 'center',
justifyContent: 'center',
},
activityContent: {
flex: 1,
gap: spacing.xs,
},
activityTitle: {
...typography.bodyBold,
fontSize: 15,
color: colors.textPrimary,
},
activityTime: {
...typography.caption,
color: colors.textSecondary,
},
activityDivider: {
height: 1,
backgroundColor: colors.border,
marginVertical: spacing.md,
},
actionsContainer: {
gap: spacing.md,
}, },
}); });

View File

@@ -1,85 +1,158 @@
import React from 'react'; import React from 'react';
import { StyleSheet, Text, View } from 'react-native'; import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { Screen } from '../components/Screen'; import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard'; import { QuickActionCard } from '../components/QuickActionCard';
import { ListButton } from '../components/ListButton'; import { colors, spacing, borderRadius, typography, shadows, iconSizes } from '../theme';
import { colors } from '../theme/colors';
export const GenerateScreen: React.FC = () => { export const GenerateScreen: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const campaigns = [ const campaigns = [
{ key: 'festivities', label: t('festivities') }, { key: 'festivities', label: t('festivities'), icon: 'party-popper' },
{ key: 'diwali', label: t('diwali') }, { key: 'diwali', label: t('diwali'), icon: 'candle' },
{ key: 'newYear', label: t('newYear') } { key: 'newYear', label: t('newYear'), icon: 'firework' }
]; ];
return ( return (
<Screen> <Screen showBackground={true}>
<View style={styles.headerRow}> {/* Header */}
<Text style={styles.title}>{t('generate')}</Text> <View style={styles.header}>
<View>
<Text style={styles.title}>{t('generateScreen.title')}</Text>
<Text style={styles.subtitle}>{t('generateScreen.subtitle')}</Text>
</View>
</View> </View>
<SectionCard title={t('seasonalKits')} description={t('aiGenerated')}> {/* Seasonal Campaigns */}
<View style={styles.chipList}> <View style={styles.section}>
<Text style={styles.sectionLabel}>{t('generateScreen.seasonalCampaigns')}</Text>
<View style={styles.campaignGrid}>
{campaigns.map(item => ( {campaigns.map(item => (
<View key={item.key} style={styles.chip}> <TouchableOpacity key={item.key} style={styles.campaignCard}>
<Text style={styles.chipLabel}>{item.label}</Text> <View style={styles.campaignIcon}>
<Text style={styles.chipCaption}>{t('campaignBlueprint')}</Text> <MaterialCommunityIcons name={item.icon} size={iconSizes.xl} color={colors.highlight} />
</View> </View>
<View style={styles.campaignContent}>
<Text style={styles.campaignLabel}>{item.label}</Text>
<Text style={styles.campaignCaption}>{t('campaignBlueprint')}</Text>
</View>
<MaterialCommunityIcons name="chevron-right" size={iconSizes.md} color={colors.textSecondary} />
</TouchableOpacity>
))} ))}
</View> </View>
</SectionCard> </View>
<View style={styles.actionsList}> {/* Content Templates */}
<ListButton label={t('aiGenerated')} /> <View style={styles.section}>
<ListButton label={t('brandVoice')} /> <Text style={styles.sectionLabel}>{t('generateScreen.contentTemplates')}</Text>
<View style={styles.actionsContainer}>
<QuickActionCard
icon="file-document-edit"
label={t('generateScreen.templates.blogPost')}
description={t('generateScreen.templates.blogPostDescription')}
onPress={() => {}}
/>
<QuickActionCard
icon="email-newsletter"
label={t('generateScreen.templates.emailCampaign')}
description={t('generateScreen.templates.emailCampaignDescription')}
onPress={() => {}}
/>
<QuickActionCard
icon="post"
label={t('generateScreen.templates.socialMedia')}
description={t('generateScreen.templates.socialMediaDescription')}
onPress={() => {}}
/>
</View>
</View>
{/* Brand Voice */}
<View style={styles.section}>
<Text style={styles.sectionLabel}>{t('generateScreen.customization')}</Text>
<View style={styles.actionsContainer}>
<QuickActionCard
icon="microphone"
label={t('brandVoice')}
description={t('generateScreen.brandVoiceDescription')}
onPress={() => {}}
/>
<QuickActionCard
icon="palette"
label={t('generateScreen.templates.designAssets')}
description={t('generateScreen.templates.designAssetsDescription')}
onPress={() => {}}
/>
</View>
</View> </View>
</Screen> </Screen>
); );
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
headerRow: { header: {
flexDirection: 'row', marginBottom: spacing.xl,
justifyContent: 'space-between',
alignItems: 'center',
}, },
title: { title: {
fontSize: 32, ...typography.h1,
fontWeight: '900',
color: colors.highlightAlt, color: colors.highlightAlt,
letterSpacing: 0.8,
}, },
chipList: { subtitle: {
gap: 16, ...typography.body,
color: colors.textSecondary,
marginTop: spacing.xs,
}, },
chip: { section: {
padding: 20, marginBottom: spacing.xl,
borderRadius: 20, },
backgroundColor: 'rgba(26, 64, 54, 0.92)', sectionLabel: {
...typography.caption,
fontSize: 11,
fontWeight: '800',
color: colors.textSecondary,
textTransform: 'uppercase',
letterSpacing: 1.2,
marginBottom: spacing.md,
},
campaignGrid: {
gap: spacing.md,
},
campaignCard: {
flexDirection: 'row',
alignItems: 'center',
padding: spacing.lg,
borderRadius: borderRadius.lg,
backgroundColor: colors.surfaceAlt,
borderWidth: 2,
borderColor: colors.border,
gap: spacing.md,
...shadows.md,
},
campaignIcon: {
width: 52,
height: 52,
borderRadius: borderRadius.md,
backgroundColor: colors.surface,
borderWidth: 2, borderWidth: 2,
borderColor: colors.borderStrong, borderColor: colors.borderStrong,
shadowColor: colors.highlight, alignItems: 'center',
shadowOffset: { width: 0, height: 12 }, justifyContent: 'center',
shadowOpacity: 0.4,
shadowRadius: 16,
elevation: 10,
gap: 8,
}, },
chipLabel: { campaignContent: {
fontSize: 17, flex: 1,
fontWeight: '800', gap: spacing.xs,
},
campaignLabel: {
...typography.h4,
fontSize: 16,
color: colors.highlightAlt, color: colors.highlightAlt,
letterSpacing: 0.4,
}, },
chipCaption: { campaignCaption: {
fontSize: 13, ...typography.caption,
color: colors.textSecondary, color: colors.textSecondary,
fontWeight: '600',
letterSpacing: 0.2,
}, },
actionsList: { actionsContainer: {
gap: 14, gap: spacing.md,
}, },
}); });

View File

@@ -1,50 +1 @@
import React from 'react'; export { TasksScreen as HRScreen } from './TasksScreen';
import { StyleSheet, Text, View } from 'react-native';
import { useTranslation } from 'react-i18next';
import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard';
import { ListButton } from '../components/ListButton';
import { colors } from '../theme/colors';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { TaskHeader } from '../components/TaskHeader';
import { TasksStackParamList } from '../types/navigation';
type Props = NativeStackScreenProps<TasksStackParamList, 'HR'>;
export const HRScreen: React.FC<Props> = ({ navigation }) => {
const { t } = useTranslation();
return (
<Screen>
<TaskHeader
title={t('hr')}
caption={t('peoplePulse')}
onNavigate={screen => navigation.navigate(screen)}
active="HR"
/>
<SectionCard title={t('engagement')} description={t('aiBrief')}>
<Text style={styles.cardBody}>
{t('cultureIntelligence')}
</Text>
</SectionCard>
<View style={styles.actionsList}>
<ListButton label={t('employees')} />
<ListButton label={t('attendance')} />
<ListButton label={t('invoices')} />
</View>
</Screen>
);
};
const styles = StyleSheet.create({
cardBody: {
fontSize: 14,
color: colors.textSecondary,
lineHeight: 22,
},
actionsList: {
gap: 14,
},
});

View File

@@ -1,87 +1,295 @@
import React, { useState } from 'react'; import React, { useMemo, useState } from 'react';
import { Image, StyleSheet, Text, View, ImageBackground, TouchableOpacity } from 'react-native'; import { Image, StyleSheet, Text, View, TouchableOpacity, ScrollView, Modal } from 'react-native';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useNavigation } from '@react-navigation/native';
import type { BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
import { Screen } from '../components/Screen'; import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard'; import { SummaryCard } from '../components/SummaryCard';
import { ListButton } from '../components/ListButton'; import { StatCard } from '../components/StatCard';
import { QuickActionCard } from '../components/QuickActionCard';
import { LanguageSelector } from '../components/LanguageSelector'; import { LanguageSelector } from '../components/LanguageSelector';
import { colors } from '../theme/colors'; import { colors, typography, spacing, borderRadius, shadows } from '../theme';
import type { MainTabParamList } from '../types/navigation';
type Avatar = { const logo = require('../assets/ic_launcher_foreground.png');
type NavigationProp = BottomTabNavigationProp<MainTabParamList, 'Home'>;
interface Company {
id: string;
name: string; name: string;
role: string; industry: string;
}; revenue: string;
employees: number;
growth: string;
invoicesPending: number;
hrApprovals: number;
renewalDays: number;
}
const avatars: Avatar[] = [ const COMPANIES: Company[] = [
{ name: 'Evelyn', role: 'Accountant' }, {
{ name: 'Malik', role: 'HR' }, id: '1',
{ name: 'Aria', role: 'Admin' }, name: 'TechCorp Solutions',
industry: 'Technology',
revenue: '₹1.2M',
employees: 45,
growth: '+18%',
invoicesPending: 5,
hrApprovals: 3,
renewalDays: 7,
},
{
id: '2',
name: 'Green Retail Pvt Ltd',
industry: 'Retail',
revenue: '₹850K',
employees: 28,
growth: '+12%',
invoicesPending: 8,
hrApprovals: 2,
renewalDays: 14,
},
{
id: '3',
name: 'Skyline Manufacturing',
industry: 'Manufacturing',
revenue: '₹2.5M',
employees: 120,
growth: '+25%',
invoicesPending: 12,
hrApprovals: 7,
renewalDays: 3,
},
]; ];
const ActionItem: React.FC<{ icon: string; label: string }> = ({ icon, label }) => (
<View style={styles.actionItem}>
<MaterialCommunityIcons name={icon} size={24} color={colors.highlight} />
<Text style={styles.actionLabel}>{label}</Text>
<MaterialCommunityIcons name="chevron-right" size={24} color={colors.highlight} />
</View>
);
export const HomeScreen: React.FC = () => { export const HomeScreen: React.FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const navigation = useNavigation<NavigationProp>();
const [languageSelectorVisible, setLanguageSelectorVisible] = useState(false); const [languageSelectorVisible, setLanguageSelectorVisible] = useState(false);
const [companyDropdownVisible, setCompanyDropdownVisible] = useState(false);
const [selectedCompany, setSelectedCompany] = useState<Company>(COMPANIES[0]);
// User name from profile - this can be made dynamic later
const userName = t('johnDoe'); // John Doe
const greeting = useMemo(() => {
return `Hi, ${userName}`;
}, [userName]);
const summaryItems = useMemo(
() => [
{
icon: 'file-document-outline',
count: selectedCompany.invoicesPending,
label: t('homeScreen.summary.invoicesPending', { count: selectedCompany.invoicesPending }),
color: colors.highlight,
},
{
icon: 'account-check',
count: selectedCompany.hrApprovals,
label: t('homeScreen.summary.hrApprovals', { count: selectedCompany.hrApprovals }),
color: '#4ADE80',
},
{
icon: 'refresh',
count: 1,
label: `Renewal in ${selectedCompany.renewalDays} days`,
color: '#FBBF24',
},
],
[t, selectedCompany]
);
const statItems = useMemo(
() => [
{
icon: 'cash',
label: t('homeScreen.stats.revenue'),
value: selectedCompany.revenue,
trend: { value: selectedCompany.growth, isPositive: true },
},
{
icon: 'account-group',
label: t('homeScreen.stats.employees'),
value: selectedCompany.employees.toString(),
trend: { value: '+2', isPositive: true },
},
{
icon: 'chart-line',
label: t('homeScreen.stats.growth'),
value: selectedCompany.growth,
trend: { value: '+5%', isPositive: true },
},
],
[t, selectedCompany]
);
const quickActions = useMemo(
() => [
{
icon: 'email-send',
label: t('homeScreen.actions.sendSalarySlips.label'),
description: t('homeScreen.actions.sendSalarySlips.description', { count: 15 }),
badge: 15,
color: undefined,
},
{
icon: 'file-refresh',
label: t('homeScreen.actions.renewVendorContract.label'),
description: t('homeScreen.actions.renewVendorContract.description', { days: 5 }),
badge: '!',
color: '#FBBF24',
},
{
icon: 'chart-box',
label: t('homeScreen.actions.reviewPnLReport.label'),
description: t('homeScreen.actions.reviewPnLReport.description'),
badge: undefined,
color: undefined,
},
],
[t]
);
return ( return (
<Screen showBackground={true}> <Screen showBackground={true}>
<View style={styles.headerRow}> {/* Top Bar */}
<Text style={styles.title}>{t('home')}</Text> <View style={styles.topBar}>
<View style={styles.headerRight}> <View style={styles.topBarLeft}>
<Text style={styles.greeting}>{greeting}</Text>
</View>
<View style={styles.topBarRight}>
<TouchableOpacity <TouchableOpacity
style={styles.languageButton} style={styles.profileButton}
onPress={() => {/* Navigate to profile */}}
>
<MaterialCommunityIcons name="account-circle" size={28} color={colors.highlight} />
</TouchableOpacity>
<TouchableOpacity
style={styles.iconButton}
onPress={() => setLanguageSelectorVisible(true)} onPress={() => setLanguageSelectorVisible(true)}
> >
<MaterialCommunityIcons <MaterialCommunityIcons name="translate" size={24} color={colors.highlight} />
name="translate"
size={24}
color={colors.highlight}
/>
</TouchableOpacity> </TouchableOpacity>
<View style={styles.avatarShell}> <TouchableOpacity style={styles.iconButton}>
<Image <MaterialCommunityIcons name="bell-outline" size={24} color={colors.highlight} />
source={{ uri: 'https://i.pravatar.cc/80?img=65' }} <View style={styles.notificationBadge}>
style={styles.avatar} <Text style={styles.notificationText}>6</Text>
/>
</View>
</View>
</View>
<SectionCard title={t('aiToday')} description={t('activeSpecialists')}>
<View style={styles.avatarRow}>
{avatars.map(avatar => (
<View key={avatar.role} style={styles.avatarCard}>
<View style={styles.avatarGlow}>
<Image
source={{ uri: `https://i.pravatar.cc/120?u=${avatar.role}` }}
style={styles.avatarLarge}
/>
</View>
<Text style={styles.avatarName}>{t(avatar.name.toLowerCase())}</Text>
<Text style={styles.avatarRole}>{t(avatar.role.toLowerCase())}</Text>
</View> </View>
))} </TouchableOpacity>
</View> </View>
</SectionCard> </View>
{/* Company Selector Below Greeting */}
<TouchableOpacity
style={styles.companySelector}
onPress={() => setCompanyDropdownVisible(true)}
>
<Image source={logo} style={styles.companyLogo} resizeMode="contain" />
<View style={styles.companyInfo}>
<Text style={styles.companyName}>{selectedCompany.name}</Text>
<Text style={styles.industryLabel}>{selectedCompany.industry}</Text>
</View>
<MaterialCommunityIcons name="chevron-down" size={20} color={colors.highlightAlt} />
</TouchableOpacity>
{/* Decorative Divider */}
<View style={styles.decorativeDivider} />
{/* Quick Stats Cards */}
<View style={styles.statsSection}>
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
style={styles.statsScroll}
contentContainerStyle={styles.statsContainer}
>
{statItems.map((item) => (
<StatCard
key={item.label}
icon={item.icon}
label={item.label}
value={item.value}
trend={item.trend}
style={{ width: 160 }}
/>
))}
</ScrollView>
</View>
{/* AI Insights Summary */}
<SummaryCard
title="AI Insights"
items={summaryItems}
style={{ marginTop: spacing.md, marginBottom: spacing.lg }}
/>
{/* Suggested Actions */}
<View style={styles.sectionHeader}> <View style={styles.sectionHeader}>
<Text style={styles.sectionTitle}>{t('suggestedActions')}</Text> <Text style={styles.sectionTitle}>{t('homeScreen.suggestedActions')}</Text>
<Text style={styles.sectionCaption}>{t('tailoredFocus')}</Text> <Text style={styles.sectionSubtitle}>{t('homeScreen.suggestionsSubtitle')}</Text>
</View> </View>
<View style={styles.actionsList}>
<ActionItem icon="file-document" label={t('invoices')} /> <View style={styles.actionsContainer}>
<ActionItem icon="chart-bar" label={t('reports')} /> {quickActions.map((action) => (
<ActionItem icon="brain" label={t('aiDigest')} /> <QuickActionCard
key={action.label}
icon={action.icon}
label={action.label}
description={action.description}
badge={action.badge}
color={action.color}
onPress={() => {}}
/>
))}
</View> </View>
{/* Company Dropdown Modal */}
<Modal
visible={companyDropdownVisible}
transparent={true}
animationType="fade"
onRequestClose={() => setCompanyDropdownVisible(false)}
>
<TouchableOpacity
style={styles.modalOverlay}
activeOpacity={1}
onPress={() => setCompanyDropdownVisible(false)}
>
<View style={styles.companyDropdownModal}>
<View style={styles.modalHeader}>
<Text style={styles.modalTitle}>Select Company</Text>
<TouchableOpacity onPress={() => setCompanyDropdownVisible(false)}>
<MaterialCommunityIcons name="close" size={24} color={colors.highlightAlt} />
</TouchableOpacity>
</View>
{COMPANIES.map((company) => (
<TouchableOpacity
key={company.id}
style={[
styles.companyOption,
selectedCompany.id === company.id && styles.companyOptionSelected,
]}
onPress={() => {
setSelectedCompany(company);
setCompanyDropdownVisible(false);
}}
>
<View style={styles.companyOptionContent}>
<Text style={styles.companyOptionName}>{company.name}</Text>
<Text style={styles.companyOptionIndustry}>{company.industry}</Text>
</View>
{selectedCompany.id === company.id && (
<MaterialCommunityIcons name="check-circle" size={24} color={colors.highlight} />
)}
</TouchableOpacity>
))}
</View>
</TouchableOpacity>
</Modal>
<LanguageSelector <LanguageSelector
visible={languageSelectorVisible} visible={languageSelectorVisible}
onClose={() => setLanguageSelectorVisible(false)} onClose={() => setLanguageSelectorVisible(false)}
@@ -91,137 +299,209 @@ export const HomeScreen: React.FC = () => {
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
headerRow: { topBar: {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
marginBottom: spacing.md,
}, },
title: { topBarLeft: {
fontSize: 36,
fontWeight: '900',
color: colors.highlightAlt,
letterSpacing: 0.8,
},
headerRight: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
languageButton: {
width: 48,
height: 48,
borderRadius: 16,
backgroundColor: colors.surfaceAlt,
borderWidth: 2,
borderColor: colors.borderStrong,
alignItems: 'center',
justifyContent: 'center',
shadowColor: colors.highlight,
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.3,
shadowRadius: 12,
elevation: 6,
},
avatarShell: {
width: 52,
height: 52,
borderRadius: 18,
borderWidth: 2,
borderColor: colors.borderStrong,
backgroundColor: colors.surfaceAlt,
alignItems: 'center',
justifyContent: 'center',
shadowColor: colors.highlight,
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.3,
shadowRadius: 12,
elevation: 6,
},
avatar: {
width: 42,
height: 42,
borderRadius: 16,
},
avatarRow: {
flexDirection: 'row',
justifyContent: 'space-between',
},
avatarCard: {
alignItems: 'center',
gap: 8,
flex: 1, flex: 1,
}, },
avatarGlow: { topBarRight: {
width: 100, flexDirection: 'row',
height: 100, alignItems: 'center',
borderRadius: 32, gap: spacing.sm,
backgroundColor: 'rgba(26, 64, 54, 0.95)', },
greeting: {
...typography.h2,
fontSize: 22,
color: colors.highlightAlt,
fontWeight: '700',
},
profileButton: {
width: 44,
height: 44,
borderRadius: borderRadius.md,
backgroundColor: colors.surfaceAlt,
borderWidth: 2, borderWidth: 2,
borderColor: colors.borderStrong, borderColor: colors.border,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
shadowColor: colors.highlight,
shadowOffset: { width: 0, height: 16 },
shadowOpacity: 0.45,
shadowRadius: 24,
elevation: 14,
}, },
avatarLarge: { iconButton: {
width: 78, width: 44,
height: 78, height: 44,
borderRadius: 26, borderRadius: borderRadius.md,
backgroundColor: colors.surfaceAlt,
borderWidth: 2,
borderColor: colors.border,
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
}, },
avatarName: { notificationBadge: {
fontSize: 16, position: 'absolute',
top: -4,
right: -4,
minWidth: 18,
height: 18,
borderRadius: 9,
backgroundColor: '#EF4444',
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 4,
borderWidth: 2,
borderColor: colors.background,
},
notificationText: {
...typography.caption,
fontSize: 10,
color: '#FFFFFF',
fontWeight: '800', fontWeight: '800',
color: colors.highlightAlt,
letterSpacing: 0.4,
}, },
avatarRole: { companySelector: {
fontSize: 13, flexDirection: 'row',
alignItems: 'center',
gap: spacing.md,
paddingVertical: spacing.sm,
paddingHorizontal: spacing.md,
borderRadius: borderRadius.lg,
backgroundColor: colors.surfaceAlt,
borderWidth: 2,
borderColor: colors.border,
marginBottom: spacing.lg,
...shadows.md,
},
companyLogo: {
width: 44,
height: 44,
},
companyInfo: {
flex: 1,
},
companyName: {
...typography.h4,
fontSize: 16,
color: colors.highlightAlt,
fontWeight: '700',
},
industryLabel: {
...typography.caption,
fontSize: 11,
color: colors.textSecondary,
marginTop: 2,
},
decorativeDivider: {
height: 1,
backgroundColor: colors.highlight,
marginVertical: spacing.lg,
opacity: 0.5,
},
statsSection: {
marginBottom: spacing.lg,
},
welcomeSection: {
marginBottom: spacing.lg,
},
subtitle: {
...typography.body,
color: colors.textSecondary, color: colors.textSecondary,
fontWeight: '600',
letterSpacing: 0.2,
}, },
sectionHeader: { sectionHeader: {
gap: 6, marginBottom: spacing.lg,
}, },
sectionTitle: { sectionTitle: {
fontSize: 22, ...typography.h3,
fontWeight: '800',
color: colors.highlightAlt, color: colors.highlightAlt,
letterSpacing: 0.4,
}, },
sectionCaption: { sectionSubtitle: {
fontSize: 14, ...typography.caption,
color: colors.textSecondary, color: colors.textSecondary,
fontWeight: '600', marginTop: 4,
letterSpacing: 0.2,
}, },
actionsList: { statsScroll: {
gap: 14, marginBottom: spacing.sm,
marginHorizontal: -spacing.xl,
paddingHorizontal: spacing.xl,
}, },
actionItem: { companyDropdownButton: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
paddingVertical: 18, gap: spacing.sm,
paddingHorizontal: 22, paddingVertical: spacing.xs,
borderRadius: 18, },
backgroundColor: 'rgba(26, 64, 54, 0.92)', businessName: {
...typography.h3,
fontSize: 18,
color: colors.highlightAlt,
fontWeight: '700',
},
logoImage: {
width: 52,
height: 52,
},
logoText: {
...typography.h4,
color: colors.background,
fontWeight: '900',
},
statsContainer: {
gap: spacing.md,
paddingRight: spacing.xl,
},
actionsContainer: {
gap: spacing.md,
},
modalOverlay: {
flex: 1,
backgroundColor: 'rgba(0, 0, 0, 0.5)',
justifyContent: 'center',
alignItems: 'center',
padding: spacing.xl,
},
companyDropdownModal: {
backgroundColor: colors.surface,
borderRadius: borderRadius.lg,
width: '100%',
maxWidth: 400,
borderWidth: 2, borderWidth: 2,
borderColor: colors.borderStrong, borderColor: colors.borderStrong,
shadowColor: colors.shadow, ...shadows.lg,
shadowOffset: { width: 0, height: 12 },
shadowOpacity: 0.4,
shadowRadius: 16,
elevation: 8,
gap: 14,
}, },
actionLabel: { modalHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: spacing.lg,
borderBottomWidth: 2,
borderBottomColor: colors.border,
},
modalTitle: {
...typography.h3,
color: colors.highlightAlt,
},
companyOption: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: spacing.lg,
borderBottomWidth: 1,
borderBottomColor: colors.border,
},
companyOptionSelected: {
backgroundColor: colors.surfaceAlt,
},
companyOptionContent: {
flex: 1, flex: 1,
color: colors.textPrimary, },
fontSize: 16, companyOptionName: {
fontWeight: '700', ...typography.h4,
letterSpacing: 0.5, color: colors.highlightAlt,
marginBottom: 4,
},
companyOptionIndustry: {
...typography.caption,
color: colors.textSecondary,
}, },
}); });

View File

@@ -1,98 +1,214 @@
import React from 'react'; import React from 'react';
import { Image, StyleSheet, Text, View } from 'react-native'; import { Image, StyleSheet, Text, View, TouchableOpacity, ScrollView } from 'react-native';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { Screen } from '../components/Screen'; import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard'; import { colors, spacing, borderRadius, typography, shadows, iconSizes } from '../theme';
import { ListButton } from '../components/ListButton';
import { colors } from '../theme/colors';
import { NativeStackScreenProps } from '@react-navigation/native-stack'; import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { MoreStackParamList } from '../types/navigation'; import { MoreStackParamList } from '../types/navigation';
import { PrimaryButton } from '../components/PrimaryButton';
type Props = NativeStackScreenProps<MoreStackParamList, 'Profile'>; type Props = NativeStackScreenProps<MoreStackParamList, 'Profile'>;
export const ProfileScreen: React.FC<Props> = ({ navigation }) => { export const ProfileScreen: React.FC<Props> = ({ navigation }) => {
const { t } = useTranslation(); const { t } = useTranslation();
// Profile Section Options
const profileOptions = [
{ icon: 'account-circle', label: t('userInfo') },
{ icon: 'credit-card', label: t('subscription') },
{ icon: 'connection', label: t('integrations') },
{ icon: 'bell', label: t('notifications') },
];
// Generate Section Options
const generateOptions = [
{ icon: 'party-popper', label: t('festivities') },
{ icon: 'candle', label: t('diwali') },
{ icon: 'firework', label: t('newYear') },
{ icon: 'file-document-edit', label: t('generateScreen.templates.blogPost') },
{ icon: 'email-newsletter', label: t('generateScreen.templates.emailCampaign') },
{ icon: 'post', label: t('generateScreen.templates.socialMedia') },
{ icon: 'microphone', label: t('brandVoice') },
{ icon: 'palette', label: t('generateScreen.templates.designAssets') },
];
// Other Options
const otherOptions = [
{ icon: 'cog', label: t('settings') },
{ icon: 'translate', label: t('language') },
{ icon: 'help-circle', label: t('help') },
{ icon: 'logout', label: t('profileScreen.signOut') },
];
return ( return (
<Screen> <Screen showBackground={true}>
<View style={styles.headerRow}> {/* Header with Profile Info */}
<Text style={styles.title}>{t('profile')}</Text> <View style={styles.header}>
<PrimaryButton <Image
label={t('generate')} source={{ uri: 'https://i.pravatar.cc/140?img=68' }}
variant="outline" style={styles.profileAvatar}
style={styles.generateButton}
onPress={() => navigation.navigate('Generate')}
/> />
<View style={styles.profileInfo}>
<Text style={styles.profileName}>{t('johnDoe')}</Text>
<Text style={styles.profileRole}>{t('executiveDirector')}</Text>
<Text style={styles.profileCompany}>{t('businessInc')}</Text>
</View>
</View> </View>
<SectionCard title={t('johnDoe')} description={t('businessInc')}> <ScrollView showsVerticalScrollIndicator={false}>
<View style={styles.profileRow}> {/* Profile Section */}
<Image <View style={styles.section}>
source={{ uri: 'https://i.pravatar.cc/140?img=68' }} <Text style={styles.sectionTitle}>{t('profileScreen.profileSettings')}</Text>
style={styles.profileAvatar} <View style={styles.optionsGrid}>
/> {profileOptions.map((option, index) => (
<View style={styles.profileMeta}> <TouchableOpacity key={index} style={styles.optionCard}>
<Text style={styles.profileTitle}>{t('executiveDirector')}</Text> <View style={styles.iconContainer}>
<Text style={styles.profileCaption}>{t('memberSince')}</Text> <MaterialCommunityIcons
name={option.icon}
size={iconSizes.xl}
color={colors.highlight}
/>
</View>
<Text style={styles.optionLabel} numberOfLines={2}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View> </View>
</View> </View>
</SectionCard>
<View style={styles.actionsList}> {/* Generate Section */}
<ListButton label={t('userInfo')} /> <View style={styles.section}>
<ListButton label={t('subscription')} /> <Text style={styles.sectionTitle}>{t('profileScreen.generateContent')}</Text>
<ListButton label={t('integrations')} /> <View style={styles.optionsGrid}>
<ListButton label={t('notifications')} /> {generateOptions.map((option, index) => (
</View> <TouchableOpacity
key={index}
style={styles.optionCard}
onPress={() => navigation.navigate('Generate')}
>
<View style={styles.iconContainer}>
<MaterialCommunityIcons
name={option.icon}
size={iconSizes.xl}
color={colors.highlight}
/>
</View>
<Text style={styles.optionLabel} numberOfLines={2}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
{/* Other Options Section */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>{t('profileScreen.more')}</Text>
<View style={styles.optionsGrid}>
{otherOptions.map((option, index) => (
<TouchableOpacity key={index} style={styles.optionCard}>
<View style={styles.iconContainer}>
<MaterialCommunityIcons
name={option.icon}
size={iconSizes.xl}
color={colors.highlight}
/>
</View>
<Text style={styles.optionLabel} numberOfLines={2}>
{option.label}
</Text>
</TouchableOpacity>
))}
</View>
</View>
</ScrollView>
</Screen> </Screen>
); );
}; };
const styles = StyleSheet.create({ const styles = StyleSheet.create({
headerRow: { header: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
title: {
fontSize: 32,
fontWeight: '900',
color: colors.highlightAlt,
letterSpacing: 0.8,
},
generateButton: {
width: 120,
height: 42,
},
profileRow: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
gap: 18, gap: spacing.lg,
marginBottom: spacing.xxl,
paddingBottom: spacing.lg,
borderBottomWidth: 2,
borderBottomColor: colors.border,
}, },
profileAvatar: { profileAvatar: {
width: 92, width: 72,
height: 92, height: 72,
borderRadius: 30, borderRadius: borderRadius.xl,
borderWidth: 3, borderWidth: 3,
borderColor: colors.borderStrong, borderColor: colors.borderStrong,
}, },
profileMeta: { profileInfo: {
gap: 4, flex: 1,
gap: spacing.xs,
}, },
profileTitle: { profileName: {
fontSize: 17, ...typography.h2,
fontWeight: '800', fontSize: 20,
color: colors.highlightAlt, color: colors.highlightAlt,
letterSpacing: 0.4,
}, },
profileCaption: { profileRole: {
...typography.bodyBold,
fontSize: 14, fontSize: 14,
color: colors.textSecondary, color: colors.textPrimary,
fontWeight: '600',
letterSpacing: 0.2,
}, },
actionsList: { profileCompany: {
gap: 14, ...typography.caption,
color: colors.textSecondary,
},
section: {
marginBottom: spacing.xxl,
},
sectionTitle: {
...typography.h3,
fontSize: 18,
color: colors.highlightAlt,
marginBottom: spacing.lg,
fontWeight: '700',
},
optionsGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: spacing.md,
justifyContent: 'space-between',
},
optionCard: {
width: '31%',
minWidth: 100,
aspectRatio: 1,
backgroundColor: colors.surfaceAlt,
borderRadius: borderRadius.lg,
borderWidth: 2,
borderColor: colors.border,
padding: spacing.md,
alignItems: 'center',
justifyContent: 'center',
...shadows.md,
},
iconContainer: {
width: 52,
height: 52,
borderRadius: borderRadius.md,
backgroundColor: colors.surface,
borderWidth: 2,
borderColor: colors.borderStrong,
alignItems: 'center',
justifyContent: 'center',
marginBottom: spacing.sm,
},
optionLabel: {
...typography.caption,
fontSize: 11,
fontWeight: '700',
color: colors.highlightAlt,
textAlign: 'center',
lineHeight: 14,
paddingHorizontal: spacing.xs,
}, },
}); });

View File

@@ -1,85 +1 @@
import React from 'react'; export { TasksScreen as StrategyScreen } from './TasksScreen';
import { StyleSheet, Text, View } from 'react-native';
import { useTranslation } from 'react-i18next';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { Screen } from '../components/Screen';
import { SectionCard } from '../components/SectionCard';
import { ListButton } from '../components/ListButton';
import { TaskHeader } from '../components/TaskHeader';
import { TasksStackParamList } from '../types/navigation';
import { colors } from '../theme/colors';
type Props = NativeStackScreenProps<TasksStackParamList, 'Strategy'>;
export const StrategyScreen: React.FC<Props> = ({ navigation }) => {
const { t } = useTranslation();
return (
<Screen>
<TaskHeader
title={t('strategy')}
caption={t('warRoom')}
active="Strategy"
onNavigate={screen => navigation.navigate(screen)}
/>
<SectionCard title={t('swot')} description={t('boardSnapshot')}>
<View style={styles.grid}>
{['S', 'W', 'O', 'T'].map(letter => (
<View key={letter} style={styles.gridCell}>
<Text style={styles.gridLetter}>{letter}</Text>
</View>
))}
</View>
</SectionCard>
<SectionCard title={t('aiItsuline')} description={t('momentumPlay')}>
<Text style={styles.cardBody}>
{t('rivalExpansion')}
</Text>
</SectionCard>
<View style={styles.actionsList}>
<ListButton label={t('initiatives')} />
<ListButton label={t('scorecards')} />
</View>
</Screen>
);
};
const styles = StyleSheet.create({
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 12,
},
gridCell: {
width: '47%',
aspectRatio: 1,
borderRadius: 20,
borderWidth: 2,
borderColor: colors.borderStrong,
backgroundColor: 'rgba(26, 64, 54, 0.92)',
alignItems: 'center',
justifyContent: 'center',
shadowColor: colors.highlight,
shadowOffset: { width: 0, height: 12 },
shadowOpacity: 0.4,
shadowRadius: 16,
elevation: 12,
},
gridLetter: {
fontSize: 38,
fontWeight: '900',
color: colors.highlightAlt,
letterSpacing: 1,
},
cardBody: {
fontSize: 14,
color: colors.textSecondary,
lineHeight: 22,
},
actionsList: {
gap: 14,
},
});

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { StyleSheet, Text, View } from 'react-native'; import { StyleSheet, Text, View, Image } from 'react-native';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { NativeStackScreenProps } from '@react-navigation/native-stack'; import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { Screen } from '../components/Screen'; import { Screen } from '../components/Screen';
@@ -7,18 +7,17 @@ import { PrimaryButton } from '../components/PrimaryButton';
import { colors } from '../theme/colors'; import { colors } from '../theme/colors';
import { RootStackParamList } from '../types/navigation'; import { RootStackParamList } from '../types/navigation';
const logo = require('../assets/ic_launcher_foreground.png');
type Props = NativeStackScreenProps<RootStackParamList, 'Welcome'>; type Props = NativeStackScreenProps<RootStackParamList, 'Welcome'>;
export const WelcomeScreen: React.FC<Props> = ({ navigation }) => { export const WelcomeScreen: React.FC<Props> = ({ navigation }) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Screen scrollable={false} contentStyle={styles.content} showBackground={true}> <Screen scrollable={false} contentStyle={styles.content} showBackground={true} showAssistant={false}>
<View style={styles.brandMark}> <View style={styles.brandMark}>
<View style={styles.glowRing} /> <Image source={logo} style={styles.logoImage} resizeMode="contain" />
<View style={styles.brandBadge}>
<Text style={styles.brandInitial}>PZ</Text>
</View>
</View> </View>
<View style={styles.heroTextWrapper}> <View style={styles.heroTextWrapper}>
<Text style={styles.heroTitle}> <Text style={styles.heroTitle}>
@@ -33,12 +32,12 @@ export const WelcomeScreen: React.FC<Props> = ({ navigation }) => {
<View style={styles.buttonStack}> <View style={styles.buttonStack}>
<PrimaryButton <PrimaryButton
label={t('signUp')} label={t('signUp')}
onPress={() => navigation.replace('MainTabs')} onPress={() => navigation.navigate('Signup')}
/> />
<PrimaryButton <PrimaryButton
label={t('logIn')} label={t('logIn')}
variant="outline" variant="outline"
onPress={() => navigation.replace('MainTabs')} onPress={() => navigation.navigate('Login')}
/> />
</View> </View>
</Screen> </Screen>
@@ -54,40 +53,14 @@ const styles = StyleSheet.create({
gap: 48, gap: 48,
}, },
brandMark: { brandMark: {
width: 130, width: 200,
height: 130, height: 200,
borderRadius: 42,
borderWidth: 3,
borderColor: colors.borderStrong,
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
backgroundColor: 'rgba(6, 35, 31, 0.95)',
shadowColor: colors.highlight,
shadowOffset: { width: 0, height: 18 },
shadowOpacity: 0.5,
shadowRadius: 28,
elevation: 16,
}, },
glowRing: { logoImage: {
position: 'absolute', width: 200,
width: 120, height: 200,
height: 120,
borderRadius: 38,
backgroundColor: colors.glowGold,
opacity: 0.4,
},
brandBadge: {
width: 80,
height: 80,
borderRadius: 28,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: colors.highlight,
shadowColor: colors.highlight,
shadowOffset: { width: 0, height: 8 },
shadowOpacity: 0.6,
shadowRadius: 16,
elevation: 10,
}, },
brandInitial: { brandInitial: {
fontSize: 32, fontSize: 32,