Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public CompanyResponseDTO getCompanyById(@PathVariable Long id) {
}

@GetMapping
@PreAuthorize("hasRole('ADMIN')")
@PreAuthorize("hasAnyRole('ADMIN', 'CUSTOMER', 'DRIVER', 'COMPANY_ADMIN')")
public List<CompanyResponseDTO> getAllCompanies() {
return companyService.getAllCompanies();
}
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/api/companies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import client from "./client";
import type { Company } from "@/types/api";

export async function getCompanies(): Promise<Company[]> {
const response = await client.get<Company[]>("/api/companies");
return response.data;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ import {borderRadius, fontSize, spacing, ThemeColors} from "@/constants/theme";
export const createStyles = (colors: ThemeColors) =>
StyleSheet.create({
trigger: {
paddingHorizontal: spacing.sm + 4,
paddingVertical: spacing.sm,
marginRight: spacing.sm,
paddingHorizontal: spacing.md,
alignSelf: "stretch",
justifyContent: "center",
backgroundColor: colors.surfaceLight,
borderRadius: borderRadius.sm,
borderWidth: 1,
borderColor: colors.border,
},
triggerText: {
fontSize: fontSize.md,
Expand Down
22 changes: 19 additions & 3 deletions frontend/src/components/AccessibilityMenu/AccessibilityMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export default function AccessibilityMenu() {
const triggerRef = useRef<View>(null);
const { locale, setLocale } = useLocaleStore();
const { mode, colors, toggleMode } = useThemeStore();
const showBlobs = useThemeStore((s) => s.showBlobs);
const toggleBlobs = useThemeStore((s) => s.toggleBlobs);
const { t } = useTranslation();
const styles = useMemo(() => createStyles(colors), [colors]);

Expand Down Expand Up @@ -59,8 +61,6 @@ export default function AccessibilityMenu() {
<TouchableWithoutFeedback onPress={() => setOpen(false)}>
<View style={styles.overlay}>
<View style={[styles.menu, { top: menuTop }]}>
{/* Dark Mode Section */}
<Text style={styles.sectionLabel}>{t("common.darkMode")}</Text>
<View style={styles.row}>
<Text style={styles.rowLabel}>{t("common.darkMode")}</Text>
<TouchableOpacity
Expand All @@ -78,9 +78,25 @@ export default function AccessibilityMenu() {
</TouchableOpacity>
</View>

<View style={styles.row}>
<Text style={styles.rowLabel}>{t("common.blobs")}</Text>
<TouchableOpacity
style={[styles.toggle, showBlobs ? styles.toggleOn : styles.toggleOff]}
onPress={toggleBlobs}
>
<Text
style={[
styles.toggleText,
showBlobs ? styles.toggleTextOn : styles.toggleTextOff,
]}
>
{showBlobs ? t("common.on") : t("common.off")}
</Text>
</TouchableOpacity>
Comment thread
StoynovAngel marked this conversation as resolved.
</View>

<View style={styles.divider} />

{/* Language Section */}
<Text style={styles.sectionLabel}>{t("common.language")}</Text>
{LANGUAGES.map(({ code, labelKey }) => {
const active = locale === code;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { StyleSheet } from "react-native";

export const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
overflow: "hidden",
},
});
45 changes: 45 additions & 0 deletions frontend/src/components/BackgroundShapes/BackgroundShapes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { View, Dimensions } from "react-native";
import { useThemeStore } from "@/stores/themeStore";
import { styles } from "./BackgroundShapes.styles";

const { width: W, height: H } = Dimensions.get("window");
Comment thread
StoynovAngel marked this conversation as resolved.
Outdated

type Blob = {
top: number;
left: number;
width: number;
height: number;
rotation: string;
color: string;
};

const BLOBS: Blob[] = [
{ top: -60, left: -70, width: 200, height: 160, rotation: "-15deg", color: "#00E8C5" },
{ top: 0.35 * H, left: W - 70, width: 180, height: 140, rotation: "20deg", color: "#FF6B6B" },
{ top: 0.65 * H, left: -80, width: 190, height: 170, rotation: "10deg", color: "#aa9cfe" },
{ top: 0.9 * H, left: W - 60, width: 170, height: 190, rotation: "-25deg", color: "#FFB347" },
];

export default function BackgroundShapes() {
useThemeStore((s) => s.colors);

return (
<View style={styles.container} pointerEvents="none">
{BLOBS.map((blob, i) => (
<View
key={i}
style={{
position: "absolute",
top: blob.top,
left: blob.left,
width: blob.width,
height: blob.height,
borderRadius: Math.max(blob.width, blob.height) / 2,
backgroundColor: blob.color,
transform: [{ rotate: blob.rotation }],
}}
/>
))}
</View>
);
}
9 changes: 5 additions & 4 deletions frontend/src/constants/locales/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
},
"home": {
"tab": "Начало",
"title": "Добре дошли в AutoNow",
"placeholder": "Вашите пътувания ще се появят тук",
"logout": "Изход"
"searchPlaceholder": "Търси компании...",
"noServices": "Няма налични компании в момента",
"noResults": "Няма компании, отговарящи на търсенето"
},
"errors": {
"emailRequired": "Имейлът е задължителен",
Expand All @@ -31,6 +31,7 @@
"english": "English",
"bulgarian": "Български",
"on": "Вкл",
"off": "Изкл"
"off": "Изкл",
"blobs": "Фонови петна"
}
}
9 changes: 5 additions & 4 deletions frontend/src/constants/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
},
"home": {
"tab": "Home",
"title": "Welcome to AutoNow",
"placeholder": "Your rides will appear here",
"logout": "Log Out"
"searchPlaceholder": "Search companies...",
"noServices": "No companies available at the moment",
"noResults": "No companies match your search"
},
"errors": {
"emailRequired": "Email is required",
Expand All @@ -31,6 +31,7 @@
"english": "English",
"bulgarian": "Bulgarian",
"on": "On",
"off": "Off"
"off": "Off",
"blobs": "Background Blobs"
}
}
9 changes: 9 additions & 0 deletions frontend/src/hooks/useCompanies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { useQuery } from "@tanstack/react-query";
import { getCompanies } from "@/api/companies";

export function useCompanies() {
return useQuery({
queryKey: ["companies"],
queryFn: getCompanies,
});
}
11 changes: 7 additions & 4 deletions frontend/src/navigation/MainTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { MainTabParamList } from "@/types/navigation";
import { useThemeStore } from "@/stores/themeStore";
import { useTranslation } from "@/hooks/useTranslation";
import AccessibilityMenu from "@/components/AccessibilityMenu/AccessibilityMenu";
import { createHeaderScreenOptions, createTabBarStyles, createTabBarColors } from "./navigation.styles";
import { createHeaderScreenOptions, createTabBarStyles, createTabBarColors, createHeaderTitleStyle } from "./navigation.styles";
import HomeScreen from "@/screens/Home/HomeScreen";

const Tab = createBottomTabNavigator<MainTabParamList>();
Expand All @@ -13,17 +13,20 @@ export default function MainTabs() {
const colors = useThemeStore((s) => s.colors);
const { t } = useTranslation();
const headerOptions = useMemo(() => createHeaderScreenOptions(colors), [colors]);
const headerTitleStyle = useMemo(() => createHeaderTitleStyle(colors), [colors]);
const tabBarStyles = useMemo(() => createTabBarStyles(colors), [colors]);
const tabBarColors = useMemo(() => createTabBarColors(colors), [colors]);

return (
<Tab.Navigator
screenOptions={{
...headerOptions,
headerTitle: "AutoNow",
headerTitleStyle: headerTitleStyle,
headerLeft: () => null,
headerRight: () => <AccessibilityMenu />,
tabBarStyle: tabBarStyles.tabBar,
tabBarActiveTintColor: tabBarColors.activeTintColor,
tabBarInactiveTintColor: tabBarColors.inactiveTintColor,
headerRightContainerStyle: { marginRight: 0, paddingRight: 0 },
tabBarStyle: { display: "none" },
}}
>
<Tab.Screen
Expand Down
12 changes: 10 additions & 2 deletions frontend/src/navigation/navigation.styles.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { StyleSheet } from "react-native";
import { StyleSheet, TextStyle } from "react-native";
import { ThemeColors } from "@/constants/theme";

export const createHeaderScreenOptions = (colors: ThemeColors) =>
({
headerTitle: "",
headerShadowVisible: false,
headerStyle: { backgroundColor: colors.background },
headerStyle: { backgroundColor: "#00E8C5" },
}) as const;

export const createHeaderTitleStyle = (colors: ThemeColors): TextStyle =>
({
color: colors.text,
fontSize: 24,
fontWeight: "600",
fontFamily: "Courier New",
});
Comment thread
StoynovAngel marked this conversation as resolved.
Outdated

export const createTabBarStyles = (colors: ThemeColors) =>
StyleSheet.create({
tabBar: {
Expand Down
99 changes: 76 additions & 23 deletions frontend/src/screens/Home/HomeScreen.styles.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,94 @@
import { StyleSheet } from "react-native";
import { ThemeColors, spacing, fontSize, borderRadius } from "@/constants/theme";
import { ThemeColors, spacing, fontSize, borderRadius, fontWeight } from "@/constants/theme";

export const createStyles = (colors: ThemeColors) =>
StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: colors.background,
paddingHorizontal: spacing.lg,
},
title: {
fontSize: fontSize.xxl,
fontWeight: "700",
color: colors.text,
marginBottom: spacing.sm,
searchContainer: {
paddingHorizontal: spacing.md,
paddingVertical: spacing.sm,
backgroundColor: colors.background,
},
email: {
searchInput: {
borderWidth: 1,
borderColor: colors.inputBorder,
borderRadius: borderRadius.md,
paddingHorizontal: spacing.md,
paddingVertical: 12,
marginTop: spacing.md,
fontSize: fontSize.lg,
color: colors.primary,
marginBottom: spacing.md,
backgroundColor: colors.inputBackground,
color: colors.text,
},
placeholder: {
listContent: {
paddingHorizontal: spacing.md,
paddingBottom: spacing.lg,
},
card: {
backgroundColor: colors.surface,
borderRadius: borderRadius.lg,
borderWidth: 1,
borderColor: colors.borderLight,
overflow: "hidden",
marginTop: spacing.sm,
},
cardImage: {
width: "100%",
height: 160,
},
cardContent: {
padding: spacing.md,
},
cardHeader: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginBottom: spacing.xs,
},
cardName: {
fontSize: fontSize.xl,
fontWeight: fontWeight.semibold,
color: colors.text,
flexShrink: 1,
},
badge: {
backgroundColor: colors.primaryLight,
paddingHorizontal: spacing.sm,
paddingVertical: spacing.xs,
borderRadius: borderRadius.sm,
marginLeft: spacing.sm,
},
badgeText: {
fontSize: fontSize.xs,
fontWeight: fontWeight.medium,
color: colors.white,
},
cardDescription: {
fontSize: fontSize.md,
color: colors.textSecondary,
marginBottom: spacing.sm,
},
cardAddress: {
fontSize: fontSize.sm,
color: colors.textDisabled,
marginBottom: spacing.xxl,
},
logoutButton: {
paddingHorizontal: spacing.xl,
paddingVertical: 14,
borderRadius: borderRadius.md,
borderWidth: 1,
borderColor: colors.error,
centered: {
flex: 1,
justifyContent: "center",
alignItems: "center",
paddingHorizontal: spacing.lg,
},
logoutText: {
color: colors.error,
emptyText: {
fontSize: fontSize.lg,
fontWeight: "600",
color: colors.textDisabled,
textAlign: "center",
},
errorText: {
fontSize: fontSize.lg,
color: colors.error,
textAlign: "center",
},
});
Loading
Loading