Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
fbbe74a082 | |||
8029204d44 | |||
15ab592513 | |||
beac8b37dc | |||
0793720f70 | |||
|
b789fad149 | ||
|
671639862c | ||
5099e472bc | |||
|
ab6af07a31 | ||
|
66501cc595 | ||
|
fdbbec3e11 |
27
.github/workflows/ci.yml
vendored
Normal file
27
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
name: "ci"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [develop]
|
||||
pull_request:
|
||||
branches: [main, develop, staging]
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- uses: "actions/checkout@v4.1.6"
|
||||
|
||||
- name: "Setup Node.js"
|
||||
uses: "actions/setup-node@v4.0.2"
|
||||
with:
|
||||
node-version: "20.x"
|
||||
cache: "npm"
|
||||
|
||||
- run: "npm clean-install"
|
||||
- run: "npm run expo:typed-routes"
|
||||
- run: 'npm run lint:commit -- --to "${{ github.sha }}"'
|
||||
- run: "npm run lint:prettier"
|
||||
- run: "npm run lint:eslint"
|
||||
- run: "npm run lint:typescript"
|
||||
- run: "npm run test"
|
@ -1,28 +0,0 @@
|
||||
default:
|
||||
image: "node:20.13.1"
|
||||
|
||||
stages:
|
||||
- "test"
|
||||
|
||||
test:
|
||||
stage: "test"
|
||||
only:
|
||||
- "merge_requests"
|
||||
- "develop"
|
||||
script:
|
||||
- "npm clean-install"
|
||||
- "npm run expo:typed-routes"
|
||||
- 'echo "${CI_COMMIT_MESSAGE}" | npm run lint:commit'
|
||||
- "npm run lint:prettier"
|
||||
- "npm run lint:eslint"
|
||||
- "npm run lint:typescript"
|
||||
- "npm run test"
|
||||
# artifacts:
|
||||
# paths:
|
||||
# - "coverage/"
|
||||
# reports:
|
||||
# coverage_report:
|
||||
# coverage_format: "cobertura"
|
||||
# path: "coverage/cobertura-coverage.xml"
|
||||
# junit: "junit.xml"
|
||||
# coverage: '/All files[^|]*\|[^|]*\s+([\d\.]+)/'
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
# MIT License
|
||||
|
||||
Copyright (c) Théo LUDWIG <contact@theoludwig.fr>
|
||||
Copyright (c) Haoxuan LI <haoxuan.li@etu.unistra.fr>
|
||||
Copyright (c) Maxime RUMPLER <mrumpler68@gmail.com>
|
||||
Copyright (c) Maxime RICHARD <maxime.richard2@etu.unistra.fr>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -21,7 +21,6 @@ Un tracker d'habitudes pour performer au boulot et dans la vie de tous les jours
|
||||
|
||||
- [Sujet](./docs/SUJET.md) + [Cahier des charges](./docs/CAHIER-DES-CHARGES.md)
|
||||
- [Modèle Logique des Données (MLD)](./docs/MLD.md)
|
||||
- [Architecture](./docs/ARCHITECTURE.md)
|
||||
- [Conventions développement informatique](./docs/CONVENTIONS.md)
|
||||
- [Kanban Board (Trello)](https://trello.com/b/8kYlcLA8/habits-tracker)
|
||||
|
||||
@ -46,7 +45,7 @@ Un tracker d'habitudes pour performer au boulot et dans la vie de tous les jours
|
||||
|
||||
```sh
|
||||
# Cloner le projet
|
||||
git clone git@git.unistra.fr:rrll/p61-project.git
|
||||
git clone git@github.com:theoludwig/p61-project.git
|
||||
|
||||
# Se déplacer dans le répertoire du projet
|
||||
cd p61-project
|
||||
|
6
app.json
6
app.json
@ -2,7 +2,7 @@
|
||||
"expo": {
|
||||
"name": "Habits Tracker",
|
||||
"slug": "p61-project",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"orientation": "portrait",
|
||||
"icon": "./presentation/assets/images/icon.png",
|
||||
"scheme": "p61-project",
|
||||
@ -15,7 +15,7 @@
|
||||
"assetBundlePatterns": ["**/*"],
|
||||
"ios": {
|
||||
"supportsTablet": true,
|
||||
"buildNumber": "1.0.0"
|
||||
"buildNumber": "1.1.1"
|
||||
},
|
||||
"android": {
|
||||
"adaptiveIcon": {
|
||||
@ -23,7 +23,7 @@
|
||||
"backgroundColor": "#ffffff"
|
||||
},
|
||||
"package": "com.theoludwig.p61project",
|
||||
"versionCode": 4
|
||||
"versionCode": 6
|
||||
},
|
||||
"web": {
|
||||
"bundler": "metro",
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { Button } from "react-native-paper"
|
||||
import { Button, Text } from "react-native-paper"
|
||||
import { View } from "react-native"
|
||||
|
||||
import { About } from "@/presentation/react-native/components/About"
|
||||
import { useAuthentication } from "@/presentation/react/contexts/Authentication"
|
||||
|
||||
const SettingsPage: React.FC = () => {
|
||||
const { logout, authenticationPresenter } = useAuthentication()
|
||||
const { logout, authenticationPresenter, user } = useAuthentication()
|
||||
|
||||
const handleLogout = async (): Promise<void> => {
|
||||
await authenticationPresenter.logout()
|
||||
@ -23,6 +24,34 @@ const SettingsPage: React.FC = () => {
|
||||
Logout
|
||||
</Button>
|
||||
}
|
||||
footer={
|
||||
<View
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginVertical: 20,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
fontSize: 18,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
Currenty logged in as
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
marginTop: 6,
|
||||
fontWeight: "bold",
|
||||
fontSize: 16,
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
{user?.displayName}
|
||||
</Text>
|
||||
</View>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
# Clean Architecture
|
@ -19,7 +19,7 @@ npm run test
|
||||
npm run test -- --u
|
||||
```
|
||||
|
||||
Une pipeline CI ([`.gitlab-ci.yml`](../.gitlab-ci.yml)) est en place pour vérifier que le code respecte ces bonnes pratiques et que les tests passent.
|
||||
Une pipeline CI est en place pour vérifier que le code respecte ces bonnes pratiques et que les tests passent.
|
||||
|
||||
## GitFlow
|
||||
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "p61-project",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "p61-project",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@expo/vector-icons": "14.0.2",
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "p61-project",
|
||||
"private": true,
|
||||
"main": "expo-router/entry",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"scripts": {
|
||||
"start": "expo start",
|
||||
"android": "expo start --android",
|
||||
|
@ -7,10 +7,11 @@ import { getVersion } from "@/utils/version"
|
||||
|
||||
export interface AboutProps {
|
||||
actionButton: React.ReactNode
|
||||
footer?: React.ReactNode
|
||||
}
|
||||
|
||||
export const About: React.FC<AboutProps> = (props) => {
|
||||
const { actionButton } = props
|
||||
const { actionButton, footer } = props
|
||||
|
||||
const version = getVersion()
|
||||
|
||||
@ -19,9 +20,15 @@ export const About: React.FC<AboutProps> = (props) => {
|
||||
style={{
|
||||
flex: 1,
|
||||
paddingHorizontal: 20,
|
||||
justifyContent: "center",
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
alignItems: "center",
|
||||
marginVertical: 20,
|
||||
}}
|
||||
>
|
||||
<View style={{ alignItems: "center", marginVertical: 20 }}>
|
||||
<Text
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
@ -67,6 +74,8 @@ export const About: React.FC<AboutProps> = (props) => {
|
||||
P61 Mobile Development
|
||||
</Text>
|
||||
|
||||
{footer}
|
||||
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
|
@ -2,6 +2,8 @@ import { useState } from "react"
|
||||
import { ScrollView, StyleSheet, View } from "react-native"
|
||||
import { Button, Snackbar, Text, TextInput } from "react-native-paper"
|
||||
import { SafeAreaView } from "react-native-safe-area-context"
|
||||
import type { IconName } from "@fortawesome/free-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome"
|
||||
|
||||
import type { GoalNumeric } from "@/domain/entities/Goal"
|
||||
import { GoalNumericProgress } from "@/domain/entities/Goal"
|
||||
@ -28,6 +30,8 @@ export const HabitProgress: React.FC<HabitProgressProps> = ({
|
||||
|
||||
const goalProgress = habitHistory.getGoalProgressByDate(selectedDate)
|
||||
|
||||
const goalProgresses = habitHistory.getProgressesByDate(selectedDate)
|
||||
|
||||
const values = {
|
||||
progress: 0,
|
||||
min: 0,
|
||||
@ -59,13 +63,31 @@ export const HabitProgress: React.FC<HabitProgressProps> = ({
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1, justifyContent: "space-between" }}>
|
||||
<ScrollView
|
||||
contentContainerStyle={{
|
||||
<View
|
||||
style={{
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 20,
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: 15,
|
||||
}}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
size={24}
|
||||
icon={habitHistory.habit.icon as IconName}
|
||||
style={[
|
||||
{
|
||||
width: 30,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
@ -75,6 +97,7 @@ export const HabitProgress: React.FC<HabitProgressProps> = ({
|
||||
>
|
||||
{habitHistory.habit.name}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
@ -112,8 +135,8 @@ export const HabitProgress: React.FC<HabitProgressProps> = ({
|
||||
/>
|
||||
|
||||
<Text style={{ marginVertical: 10, fontWeight: "bold", fontSize: 18 }}>
|
||||
{goalProgress.progress.toLocaleString()} /{" "}
|
||||
{goalProgress.goal.target.value.toLocaleString()}{" "}
|
||||
{goalProgress.progress.toLocaleString(LOCALE)} /{" "}
|
||||
{goalProgress.goal.target.value.toLocaleString(LOCALE)}{" "}
|
||||
{goalProgress.goal.target.unit}
|
||||
</Text>
|
||||
|
||||
@ -174,7 +197,58 @@ export const HabitProgress: React.FC<HabitProgressProps> = ({
|
||||
marginVertical: 10,
|
||||
}}
|
||||
/>
|
||||
|
||||
<Text
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
fontSize: 18,
|
||||
margin: 15,
|
||||
}}
|
||||
>
|
||||
Progress History
|
||||
</Text>
|
||||
|
||||
<ScrollView
|
||||
style={{
|
||||
width: "100%",
|
||||
marginVertical: 20,
|
||||
}}
|
||||
>
|
||||
{goalProgresses.map((habitProgress, index) => {
|
||||
if (!habitProgress.goalProgress.isNumeric()) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
key={habitProgress.id + index}
|
||||
style={{
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 20,
|
||||
borderBottomWidth: 1,
|
||||
borderColor: "#f57c00",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
<Text>
|
||||
{habitProgress.date.toLocaleDateString(LOCALE, {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}
|
||||
</Text>
|
||||
<Text>
|
||||
{habitProgress.goalProgress.progress.toLocaleString(LOCALE)}{" "}
|
||||
{habitProgress.goalProgress.goal.target.unit}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
<Snackbar
|
||||
visible={isVisibleSnackbar}
|
||||
|
@ -2,6 +2,7 @@ import { Card, Divider, Text } from "react-native-paper"
|
||||
import CircularProgress from "react-native-circular-progress-indicator"
|
||||
import { Agenda } from "react-native-calendars"
|
||||
import { useState } from "react"
|
||||
import { ScrollView } from "react-native"
|
||||
|
||||
import { getNowDateUTC, getISODate } from "@/utils/dates"
|
||||
import type { HabitsTracker } from "@/domain/entities/HabitsTracker"
|
||||
@ -39,7 +40,7 @@ export const HabitsStatistics: React.FC<HabitsStatisticsProps> = (props) => {
|
||||
selected={selectedDateISO}
|
||||
renderList={() => {
|
||||
return (
|
||||
<>
|
||||
<ScrollView>
|
||||
<Divider />
|
||||
|
||||
<Text
|
||||
@ -107,7 +108,7 @@ export const HabitsStatistics: React.FC<HabitsStatisticsProps> = (props) => {
|
||||
)
|
||||
},
|
||||
)}
|
||||
</>
|
||||
</ScrollView>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
|
Reference in New Issue
Block a user