Skip to content

Commit

Permalink
barcode reader
Browse files Browse the repository at this point in the history
  • Loading branch information
memmer57 committed Dec 13, 2023
1 parent b711685 commit e4509be
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 74 deletions.
14 changes: 14 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import QuizPage from "./app/Quiz"
import MapPage from "./app/Map"
import CitationsPage from "./app/Citations"
import CouponsPage from "./app/Coupons"
import QRReaderPage from "./app/QRReader"

const Drawer = createDrawerNavigator()

Expand Down Expand Up @@ -61,6 +62,19 @@ export default function App() {
),
}}
/>
<Drawer.Screen
name="QR čtečka"
component={QRReaderPage}
options={{
drawerIcon: ({ focused, size }) => (
<Ionicons
name="md-qr-code"
size={size}
color={focused ? "green" : "#aaa"}
/>
),
}}
/>
<Drawer.Screen
name="Mapa"
component={MapPage}
Expand Down
8 changes: 2 additions & 6 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,13 @@
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "dark",
"plugins": [
"./plugins/android-manifest.plugin.js"
],
"plugins": ["./plugins/android-manifest.plugin.js", "expo-barcode-scanner"],
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"assetBundlePatterns": ["**/*"],
"ios": {
"supportsTablet": true
},
Expand Down
5 changes: 5 additions & 0 deletions app/QRReader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import QRReader from "../components/QRReader/QRReader"

export default function QRReaderPage() {
return <QRReader />
}
6 changes: 6 additions & 0 deletions components/Citations/CitationStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ export const citationStyles = StyleSheet.create({
text: {
marginBottom: 4,
},
authorText: {
fontWeight: "bold",
fontSize: 16,
marginBottom: 42,
textAlign: "center",
},
})
12 changes: 7 additions & 5 deletions components/Citations/Citations.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { ScrollView, Text, View } from "react-native"
import { citationStyles } from "./CitationStyles"
import { citationStyles as styles } from "./CitationStyles"
import { blurhash, quizImages } from "../../helpers/quizImages"
import { Image } from "expo-image"
import { useAssets } from "expo-asset"
Expand All @@ -11,15 +11,15 @@ export default function Citations() {

return (
<ScrollView
style={citationStyles.container}
style={styles.container}
contentContainerStyle={{ justifyContent: "center" }}
>
{assets
? assets.map((asset, index) => (
<View style={citationStyles.citationContainer} key={index}>
<View style={styles.citationContainer} key={index}>
<Image
style={[
citationStyles.image,
styles.image,
{
aspectRatio:
asset.width && asset.height
Expand All @@ -33,13 +33,15 @@ export default function Citations() {
focusable={true}
/>
{data[index].map((text, i) => (
<Text key={i} style={citationStyles.text}>
<Text key={i} style={styles.text}>
{text}
</Text>
))}
</View>
))
: null}

<Text style={styles.authorText}>Made with ❤️ by Matěj Emmer</Text>
</ScrollView>
)
}
29 changes: 10 additions & 19 deletions components/Coupons/CouponCard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useState } from "react"
import { View, Text, TouchableOpacity } from "react-native"
import { couponCardStyles } from "./CouponCardStyles"
import { View, Text } from "react-native"
import { couponCardStyles as styles } from "./CouponCardStyles"
import Ionicons from "@expo/vector-icons/Ionicons"

interface IProps {
Expand All @@ -11,26 +10,18 @@ interface IProps {
}

export default function CouponCard(props: IProps) {
const [isPopupOpen, setIsPopupOpen] = useState(false)

const handleCardClick = () => {
setIsPopupOpen(true)
}

return (
<View style={couponCardStyles.couponCard}>
<Text style={couponCardStyles.couponTitle}>{props.title}</Text>
<Text style={couponCardStyles.couponDescription}>
{props.description}
</Text>
<View style={couponCardStyles.icon}>
<View style={styles.couponCard}>
<Text style={styles.couponTitle}>{props.title}</Text>
<Text style={styles.couponDescription}>{props.description}</Text>
<View style={styles.icon}>
<Ionicons name="md-barcode-outline" size={70} color="black" />
</View>
<Text style={couponCardStyles.couponPoints}>
Potřebné body: <Text style={couponCardStyles.bold}>{props.points}</Text>
<Text style={styles.couponPoints}>
Potřebné body: <Text style={styles.bold}>{props.points}</Text>
</Text>
<Text style={couponCardStyles.couponCode}>
Kód: <Text style={couponCardStyles.bold}>{props.code}</Text>
<Text style={styles.couponCode}>
Kód: <Text style={styles.bold}>{props.code}</Text>
</Text>
</View>
)
Expand Down
28 changes: 3 additions & 25 deletions components/Coupons/Coupons.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,16 @@
import { View } from "react-native"
import CouponCard from "./CouponCard"
import { couponsStyles } from "./CouponsStyles"
import { couponsStyles as styles } from "./CouponsStyles"
import { ScrollView } from "react-native-gesture-handler"
import data from "../../coupons.json"
import { useState, useEffect } from "react"
import { getPoints } from "../../helpers/quizPoints"
import { pointsForCoupon } from "../../helpers/constants"

export default function Coupons() {
const [points, setPoints] = useState<number>(0)
const [couponsAvailable, setCouponsAvailable] = useState<number>(0)

const fetchPoints = async () => {
const pointsValue = await getPoints()
setPoints(pointsValue)
setCouponsAvailable(Math.floor(pointsValue / pointsForCoupon))
}

useEffect(() => {
fetchPoints()

const interval = setInterval(() => {
fetchPoints()
}, 5000)

return () => clearInterval(interval)
}, [])

return (
<ScrollView style={couponsStyles.container}>
<ScrollView style={styles.container}>
{data.map(
(coupon, index) =>
index % 2 === 0 && (
<View key={index} style={couponsStyles.row}>
<View key={index} style={styles.row}>
<CouponCard
title={coupon.title}
description={coupon.description}
Expand Down
20 changes: 9 additions & 11 deletions components/Home/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react"
import { useState, useEffect } from "react"
import { View, Text } from "react-native"
import { homeStyles } from "./HomeStyles"
import { homeStyles as styles } from "./HomeStyles"
import { blurhash, quizImages } from "../../helpers/quizImages"
import { Image } from "expo-image"
import { useAssets } from "expo-asset"
Expand Down Expand Up @@ -35,24 +35,22 @@ export default function Home() {
}

return (
<View style={homeStyles.container}>
<Text style={homeStyles.greeting}>
Vítejte v Jizerskohorských bučinách!
<View style={styles.container}>
<Text style={styles.greeting}>Vítejte v Jizerskohorských bučinách!</Text>
<Text style={styles.stats}>Vaše statistiky:</Text>
<Text style={styles.points}>
Počet bodů: <Text style={styles.bold}>{points}</Text>
</Text>
<Text style={homeStyles.stats}>Vaše statistiky:</Text>
<Text style={homeStyles.points}>
Počet bodů: <Text style={homeStyles.bold}>{points}</Text>
</Text>
<Text style={homeStyles.coupons}>
<Text style={styles.coupons}>
Počet dostupných kupónů:{" "}
<Text style={homeStyles.bold}>{couponsAvailable}</Text>
<Text style={styles.bold}>{couponsAvailable}</Text>
</Text>
{randomImage ? (
<View>
<Text>I takto vypadají Jizerskohorské bučiny: </Text>
<Image
style={[
homeStyles.image,
styles.image,
{
aspectRatio:
randomImage.width && randomImage.height
Expand Down
51 changes: 51 additions & 0 deletions components/QRReader/QRReader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { View, Text, Button, StyleSheet } from "react-native"
import { QRReaderStyles as styles } from "./QRReaderStyles"
import { useState, useEffect } from "react"
import { BarCodeScanner } from "expo-barcode-scanner"

export default function QRReader() {
const [hasPermission, setHasPermission] = useState<boolean>()
const [scanned, setScanned] = useState(false)
const [scanResult, setScanResult] = useState("")

useEffect(() => {
const getBarCodeScannerPermissions = async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync()
setHasPermission(status === "granted")
}

getBarCodeScannerPermissions()
}, [])

const handleBarCodeScanned = ({ type, data }: any) => {
setScanned(true)
setScanResult("Výsledek: " + data)
}

const handleNewScan = () => {
setScanned(false)
setScanResult("")
}

if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>
}
if (hasPermission === false) {
return <Text>No access to camera</Text>
}

return (
<View style={styles.container}>
{scanResult !== "" && <Text style={styles.resultText}>{scanResult}</Text>}
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
{scanned && (
<View style={styles.newScanButton}>
<Button title={"Skenovat znovu"} onPress={() => handleNewScan()} />
</View>
)}
</View>
)
}
25 changes: 25 additions & 0 deletions components/QRReader/QRReaderStyles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { StyleSheet } from "react-native"

export const QRReaderStyles = StyleSheet.create({
container: {
flex: 1,
gap: 16,
paddingVertical: 16,
paddingHorizontal: 16,
},
image: {
width: "100%",
height: undefined,
marginBottom: 16,
},
resultText: {
fontSize: 16,
fontWeight: "bold",
},
newScanButton: {
position: "absolute",
width: "70%",
top: "50%",
alignSelf: "center",
},
})
14 changes: 7 additions & 7 deletions components/Quiz/Quiz.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useState, useEffect } from "react"
import { quizStyles } from "./QuizStyles"
import { quizStyles as styles } from "./QuizStyles"
import { StatusBar } from "expo-status-bar"
import { Text, ScrollView, Button } from "react-native"
import { Image } from "expo-image"
Expand Down Expand Up @@ -87,21 +87,21 @@ export default function Quiz() {

return (
<ScrollView
style={quizStyles.container}
style={styles.container}
contentContainerStyle={{
rowGap: 12,
}}
>
<Text style={quizStyles.pointsTextWrapper}>
<Text style={styles.pointsTextWrapper}>
<Text>Body: </Text>
<Text style={quizStyles.pointsTextBold}>{points}</Text>
<Text style={styles.pointsTextBold}>{points}</Text>
</Text>
<Text>{questionData.name}</Text>

{randomImage ? (
<Image
style={[
quizStyles.image,
styles.image,
{
aspectRatio:
randomImage.width && randomImage.height
Expand All @@ -128,13 +128,13 @@ export default function Quiz() {
/>
))}

<Text style={quizStyles.statusText}>{statusText}</Text>
<Text style={styles.statusText}>{statusText}</Text>

{answerSelected && (
<Button title="Další otázka" onPress={getNewQuestion} />
)}

<Text style={quizStyles.bottomSpacer} />
<Text style={styles.bottomSpacer} />

<StatusBar style="auto" />
</ScrollView>
Expand Down
Loading

0 comments on commit e4509be

Please sign in to comment.