Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
91 changes: 74 additions & 17 deletions frontend/app/(tabs)/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ export default function HomeScreen() {
</View>
) : null;
const webRows = buildWebRows(listings, homeColumns);
const trustPoints = ['Verified students', 'Fast local pickup', 'No shipping hassle'];

if (isWeb) {
return (
Expand Down Expand Up @@ -377,14 +378,24 @@ export default function HomeScreen() {

<Animated.View style={[styles.webToolbarRow, entranceStyle]}>
<View style={styles.webToolbarCopy}>
<Text style={styles.heroEyebrow}>Campus marketplace</Text>
<Text style={styles.webToolbarTitle}>
{hasSearchQuery ? `Results for "${searchQuery}"` : 'Latest listings'}
</Text>
<Text style={styles.webToolbarBody}>
{hasSearchQuery
? 'Use filters to narrow the results further.'
: 'Fresh campus listings from the PolyBuys marketplace.'}
: 'Buy and sell with Cal Poly students in a marketplace built for quick, trusted handoffs.'}
</Text>
{!hasSearchQuery ? (
<View style={styles.trustRow}>
{trustPoints.map((point) => (
<View key={point} style={styles.trustPill}>
<Text style={styles.trustPillText}>{point}</Text>
</View>
))}
</View>
) : null}
</View>
<Pressable
style={({ pressed }) => [
Expand Down Expand Up @@ -480,7 +491,7 @@ export default function HomeScreen() {
<Animated.View style={[styles.homeTopBlock, entranceStyle]}>
<ScreenHeader
title="Browse"
subtitle="Fresh listings from campus"
subtitle="Fresh campus listings with fast, local pickup"
action={
<Pressable
style={({ pressed }) => [styles.createChip, pressed && styles.createChipPressed]}
Expand All @@ -493,6 +504,13 @@ export default function HomeScreen() {
</Pressable>
}
/>
<View style={styles.trustRow}>
{trustPoints.map((point) => (
<View key={point} style={styles.trustPill}>
<Text style={styles.trustPillText}>{point}</Text>
</View>
))}
</View>
<FilterBar
filters={filters}
sortBy={sortBy}
Expand Down Expand Up @@ -598,37 +616,67 @@ const styles = StyleSheet.create({
width: '100%',
maxWidth: 1120,
alignSelf: 'center',
paddingTop: spacing.lg,
gap: spacing.md,
paddingTop: spacing.xl,
gap: spacing.lg,
},
webScrollView: {
width: '100%',
alignSelf: 'center',
},
webScrollContent: {
paddingTop: spacing.lg,
gap: spacing.lg,
paddingTop: spacing.xl,
gap: spacing.xl,
},
webToolbarRow: {
flexDirection: 'row',
alignItems: 'center',
alignItems: 'flex-end',
justifyContent: 'space-between',
gap: spacing.lg,
backgroundColor: colors.surfaceBrand,
borderRadius: borderRadius.xl,
borderWidth: 1,
borderColor: colors.border,
padding: spacing.xl,
},
webToolbarCopy: {
flex: 1,
minWidth: 0,
gap: spacing.xs,
maxWidth: 720,
},
webToolbarTitle: {
...typography.title1,
color: colors.textDark,
fontSize: 24,
lineHeight: 30,
fontSize: 28,
lineHeight: 34,
},
webToolbarBody: {
...typography.subhead,
color: colors.text,
lineHeight: 21,
},
heroEyebrow: {
...typography.footnoteMed,
color: colors.primary,
textTransform: 'uppercase',
letterSpacing: 1.1,
},
trustRow: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: spacing.sm,
},
trustPill: {
paddingHorizontal: spacing.md,
paddingVertical: spacing.xs,
borderRadius: borderRadius.full,
backgroundColor: colors.white,
borderWidth: 1,
borderColor: colors.border,
},
trustPillText: {
...typography.footnoteMed,
color: colors.primary,
},
webGrid: {
gap: spacing.lg,
Expand Down Expand Up @@ -658,7 +706,12 @@ const styles = StyleSheet.create({
alignItems: 'center',
},
homeTopBlock: {
gap: spacing.md,
gap: spacing.lg,
backgroundColor: colors.surfaceBrand,
borderRadius: borderRadius.xl,
borderWidth: 1,
borderColor: colors.border,
padding: spacing.lg,
},
createChip: {
backgroundColor: colors.primary,
Expand All @@ -668,6 +721,7 @@ const styles = StyleSheet.create({
minHeight: 44,
justifyContent: 'center',
alignItems: 'center',
boxShadow: '0 10px 24px rgba(14, 107, 83, 0.18)',
},
createChipPressed: {
opacity: 0.9,
Expand All @@ -690,32 +744,35 @@ const styles = StyleSheet.create({
alignItems: 'center',
paddingTop: spacing.xxl,
paddingHorizontal: spacing.xl,
paddingBottom: spacing.lg,
},
stateContainer: {
flex: 1,
minHeight: 180,
minHeight: 220,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: spacing.xl,
},
stateCard: {
width: '100%',
maxWidth: 560,
backgroundColor: colors.surface,
backgroundColor: colors.white,
borderRadius: borderRadius.lg,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colors.border,
padding: spacing.lg,
padding: spacing.xl,
gap: spacing.xs,
boxShadow: '0 14px 32px rgba(14, 107, 83, 0.08)',
},
listContainer: {
paddingTop: spacing.xs,
paddingBottom: 26,
paddingTop: spacing.sm,
paddingBottom: spacing.xxl,
},
listContainerDesktop: {
paddingTop: spacing.xs,
paddingTop: spacing.sm,
},
footerLoader: {
paddingVertical: 20,
paddingVertical: spacing.xl,
alignItems: 'center',
justifyContent: 'center',
},
Expand Down
4 changes: 2 additions & 2 deletions frontend/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ function RootLayout() {
<Stack
screenOptions={{
headerBackButtonDisplayMode: 'minimal',
headerStyle: { backgroundColor: colors.surface },
headerStyle: { backgroundColor: colors.background },
headerTintColor: colors.textDark,
headerTitleStyle: {
...typography.heading,
color: colors.textDark,
},
headerShadowVisible: false,
contentStyle: { backgroundColor: colors.surface },
contentStyle: { backgroundColor: colors.background },
}}
>
<Stack.Screen name="(tabs)" options={{ headerShown: false, title: 'Home' }} />
Expand Down
46 changes: 24 additions & 22 deletions frontend/app/listings/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -490,12 +490,14 @@ export default function ListingDetailScreen() {
/>
</View>

<Text style={styles.descriptionLabel}>Description</Text>
<Text style={styles.description}>{listing.description}</Text>
<View style={styles.sectionBlock}>
<Text style={styles.descriptionLabel}>Description</Text>
<Text style={styles.description}>{listing.description}</Text>
</View>

{sellerProfile && (
<Pressable
style={styles.sellerBlock}
style={[styles.sellerBlock, styles.sectionBlock]}
onPress={() => router.push(`/profile/${encodeURIComponent(listing.sellerId)}` as never)}
accessibilityLabel={`View ${sellerProfile.name}'s profile`}
accessibilityRole="button"
Expand Down Expand Up @@ -596,25 +598,25 @@ const styles = StyleSheet.create({
width: '100%',
maxWidth: 980,
alignSelf: 'center',
paddingHorizontal: spacing.lg,
paddingHorizontal: spacing.xl,
paddingTop: spacing.xl,
paddingBottom: spacing.xxl,
paddingBottom: spacing.xxl + spacing.sm,
},
webBannerContainer: {
marginBottom: 12,
marginBottom: spacing.sm,
backgroundColor: colors.infoBg,
borderRadius: borderRadius.sm,
borderWidth: 1,
borderColor: colors.infoBorder,
padding: 12,
padding: spacing.md,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
gap: 12,
},
webBannerTextWrap: {
flex: 1,
gap: 2,
gap: spacing.xs,
},
webBannerSubtext: {
color: colors.infoText,
Expand Down Expand Up @@ -643,12 +645,13 @@ const styles = StyleSheet.create({
borderRadius: borderRadius.lg,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colors.border,
padding: spacing.lg,
gap: spacing.md,
padding: spacing.xl,
gap: spacing.lg,
overflow: 'hidden',
boxShadow: '0 16px 36px rgba(14, 107, 83, 0.08)',
},
imageSection: {
marginBottom: spacing.lg,
gap: spacing.sm,
},
heroImageWrap: {
height: 280,
Expand All @@ -664,7 +667,7 @@ const styles = StyleSheet.create({
imageIndicator: {
alignItems: 'center',
marginTop: spacing.sm,
paddingVertical: spacing.xs,
paddingVertical: spacing.sm,
gap: spacing.xs,
},
imageIndicatorText: {
Expand Down Expand Up @@ -726,7 +729,6 @@ const styles = StyleSheet.create({
borderColor: colors.border,
alignItems: 'center',
justifyContent: 'center',
marginBottom: spacing.lg,
},
placeholderText: {
color: colors.text,
Expand All @@ -736,8 +738,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
alignItems: 'flex-start',
justifyContent: 'space-between',
gap: spacing.md,
marginTop: spacing.xs,
gap: spacing.lg,
},
title: {
...typography.title1,
Expand All @@ -755,6 +756,7 @@ const styles = StyleSheet.create({
flexDirection: 'row',
alignItems: 'center',
gap: spacing.sm,
marginTop: spacing.xs,
},
messageButton: {
flex: 1,
Expand Down Expand Up @@ -785,12 +787,13 @@ const styles = StyleSheet.create({
flexDirection: 'row',
flexWrap: 'wrap',
gap: spacing.sm,
marginTop: spacing.xs,
},
sectionBlock: {
gap: spacing.sm,
},
descriptionLabel: {
...typography.heading,
color: colors.textDark,
marginTop: spacing.sm,
},
description: {
...typography.body,
Expand All @@ -800,13 +803,12 @@ const styles = StyleSheet.create({
sellerBlock: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: colors.surface,
backgroundColor: colors.surfaceBrand,
borderRadius: borderRadius.md,
borderWidth: StyleSheet.hairlineWidth,
borderColor: colors.border,
padding: spacing.md,
gap: spacing.md,
marginTop: spacing.sm,
},
sellerAvatar: {
width: 44,
Expand All @@ -821,6 +823,7 @@ const styles = StyleSheet.create({
},
sellerInfo: {
flex: 1,
gap: 2,
},
sellerName: {
...typography.subhead,
Expand All @@ -833,7 +836,6 @@ const styles = StyleSheet.create({
},
buttonContainer: {
gap: spacing.sm,
marginTop: spacing.sm,
},
markSoldButton: {
backgroundColor: colors.primary,
Expand All @@ -851,7 +853,7 @@ const styles = StyleSheet.create({
editButton: {
borderWidth: StyleSheet.hairlineWidth,
borderColor: colors.border,
backgroundColor: colors.white,
backgroundColor: colors.surfaceWarm,
paddingVertical: spacing.md,
borderRadius: borderRadius.md,
alignItems: 'center',
Expand All @@ -864,7 +866,7 @@ const styles = StyleSheet.create({
fontWeight: '600',
},
reportLink: {
marginTop: spacing.md,
marginTop: spacing.xs,
paddingVertical: spacing.sm,
alignSelf: 'flex-start',
},
Expand Down
Loading
Loading