Skip to content
Merged
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
45 changes: 0 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,51 +31,6 @@

Explore the API documentation at [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs).

## Frontend (`/frontend`)

```plaintext
frontend/
├── public/ # Static assets and translations (i18n)
├── src/
│ ├── assets/ # Images, SVGs, and static media
│ ├── client/ # Generated API client (OpenAPI)
│ ├── components/ # Reusable UI components (cards, collections, stats, etc.)
│ ├── db/ # IndexedDB (Dexie.js) setup for offline/guest mode
│ ├── data/localDB/ # Local DB logic for guest/offline mode (CRUD, stats, etc.)
│ ├── hooks/ # Custom React hooks (auth, data fetching, etc.)
│ ├── repositories/ # Data access layer (API/local switch for cards, collections, stats)
│ ├── routes/ # Application routes (pages, layouts)
│ ├── services/ # Business logic for cards, collections, practice, stats
│ ├── utils/ # Utility functions (auth, stats, etc.)
│ └── main.tsx # App entry point
├── package.json # Frontend dependencies and scripts
├── pnpm-lock.yaml # Lockfile for reproducible installs
├── tsconfig*.json # TypeScript configuration
├── vite.config.ts # Vite build configuration
└── index.html # Main HTML template
```

## Backend (`/backend`)

```plaintext
backend/
├── src/
│ ├── api/ # FastAPI route definitions
│ ├── core/ # Core logic (auth, config, security)
│ ├── db/ # Database models and access (SQLAlchemy)
│ ├── schemas/ # Pydantic models (request/response)
│ ├── services/ # Business logic (users, flashcards, etc.)
│ └── main.py # FastAPI app entry point
├── tests/ # Backend tests (pytest)
├── pyproject.toml # Python dependencies and project config
├── uv.lock # Poetry/uv lockfile for reproducible installs
├── Dockerfile # Production Docker build
├── Dockerfile.pip # Alternative Docker build (pip)
├── entrypoint.sh # Docker entrypoint script
├── prestart.sh # Pre-start script (migrations, etc.)
└── alembic.ini # Alembic DB migration config
```

## Setup Instructions

### Backend Setup
Expand Down
7 changes: 6 additions & 1 deletion frontend/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
"publicLayout": {
"index": {
"title": "Learn Better with FlashNotes",
"description": "A simple flashcard app that helps you learn. Create cards,practice regularly, and remember what matters.",
"description": "Capture your ideas, turn them into flashcards, and practice often so you can remember more!",
"offlineMode": "Offline Mode",
"offlineModeDescription": "Use FlashNotes anywhere, even without an internet connection. Guest mode and all your data work fully offline!",
"aiGeneration": "AI Generation",
Expand All @@ -181,6 +181,11 @@
},
"signUp": {
"alreadyHaveAccount": "Already have an account?"
},
"thanks": {
"title": "Thank You to All Contributors!",
"description": "This project would not be possible without the amazing work and support of our contributors.",
"link": "Thanks to all contributors"
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion frontend/public/locales/es/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
"publicLayout": {
"index": {
"title": "Aprende Mejor con FlashNotes",
"description": "Una aplicación de tarjetas de memoria simple que te ayuda a aprender. Crea tarjetas, practica regularmente y recuerda lo que importa.",
"description": "Captura tus ideas, conviértelas en tarjetas de memoria y practica a menudo para recordar más!",
"offlineMode": "Modo sin conexión",
"offlineModeDescription": "Usa FlashNotes en cualquier lugar, incluso sin conexión a internet. ¡El modo invitado y todos tus datos funcionan completamente sin conexión!",
"aiGeneration": "Generación con IA",
Expand All @@ -181,6 +181,11 @@
},
"signUp": {
"alreadyHaveAccount": "¿Ya tienes una cuenta?"
},
"thanks": {
"title": "¡Gracias a todos los colaboradores!",
"description": "Este proyecto no sería posible sin el increíble trabajo y apoyo de nuestros colaboradores.",
"link": "Gracias a todos los colaboradores"
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion frontend/public/locales/nl/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
"publicLayout": {
"index": {
"title": "Beter Leren met FlashNotes",
"description": "Een eenvoudige flashcard-app die je helpt te leren. Maak kaarten, oefen regelmatig en onthoud wat belangrijk is.",
"description": "Leg je ideeën vast, maak er flashcards van en oefen vaak zodat je meer onthoudt!",
"offlineMode": "Offline Modus",
"offlineModeDescription": "Gebruik FlashNotes overal, zelfs zonder internetverbinding. Gastmodus en al je gegevens werken volledig offline!",
"aiGeneration": "AI Generatie",
Expand All @@ -181,6 +181,11 @@
},
"signUp": {
"alreadyHaveAccount": "Heb je al een account?"
},
"thanks": {
"title": "Dank aan alle bijdragers!",
"description": "Dit project zou niet mogelijk zijn zonder het geweldige werk en de steun van onze bijdragers.",
"link": "Dank aan alle bijdragers"
}
}
}
Expand Down
50 changes: 50 additions & 0 deletions frontend/src/assets/contributors.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"login": "jose-fernandez",
"name": "Jose Fernandez",
"avatar_url": "https://avatars.githubusercontent.com/u/22930011?v=4",
"profile": "https://github.com/jose-fernandez"
},
{
"login": "ryanli",
"name": "Ryan Li",
"avatar_url": "https://avatars.githubusercontent.com/u/148289?v=4",
"profile": "https://github.com/ryanli"
},
{
"login": "VictoriaTskhondia",
"name": "VictoriaTskhondia",
"avatar_url": "https://avatars.githubusercontent.com/u/48713882?v=4",
"profile": "https://github.com/VictoriaTskhondia"
},
{
"login": "sebampuero",
"name": "Sebastian",
"avatar_url": "https://avatars.githubusercontent.com/u/20564582?v=4",
"profile": "https://sebampuerom.de/"
},
{
"login": "mohsenkhosroanjam",
"name": "Mohsen Khosroanjam",
"avatar_url": "https://avatars.githubusercontent.com/u/60619215?v=4",
"profile": "https://github.com/mohsenkhosroanjam"
},
{
"login": "muhammedsirajudeen",
"name": "MuhammedSirajudeen ",
"avatar_url": "https://avatars.githubusercontent.com/u/43089951?v=4",
"profile": "https://github.com/muhammedsirajudeen"
},
{
"login": "sonegs",
"name": "Miguel Cobo",
"avatar_url": "https://avatars.githubusercontent.com/u/47485321?v=4",
"profile": "https://github.com/sonegs"
},
{
"login": "jcmc0011",
"name": "jcmc0011",
"avatar_url": "https://avatars.githubusercontent.com/u/11525905?v=4",
"profile": "https://github.com/jcmc0011"
}
]
65 changes: 36 additions & 29 deletions frontend/src/components/commonUI/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Stack, Text } from '@chakra-ui/react'
import { Link } from '@tanstack/react-router'
import { useTranslation } from 'react-i18next'
import { ImGithub } from 'react-icons/im'

Expand All @@ -15,36 +16,42 @@ export function Footer({
}: FooterProps) {
const { t } = useTranslation()
return (
<Stack
direction={{ base: 'column', md: 'row' }}
justify="center"
align="center"
gap={4}
mt={16}
pb={8}
color="gray.500"
fontSize="sm"
>
<a
href={githubUrl}
target="_blank"
rel="noopener noreferrer"
style={{ textDecoration: 'none', color: 'inherit' }}
<>
<Stack
direction={{ base: 'column', md: 'row' }}
justify="center"
align="center"
gap={4}
mt={16}
pb={8}
color="gray.500"
fontSize="sm"
>
<Stack direction="row" align="center" gap={2}>
<ImGithub />

<Text>{t('general.words.github')}</Text>
</Stack>
</a>
<Text>•</Text>
<Text color="gray.500">
{t('general.words.version')} {version}
</Text>
<Text>•</Text>
<Text>
© {copyrightYear} {t('general.words.flashNotes')}
<a
href={githubUrl}
target="_blank"
rel="noopener noreferrer"
style={{ textDecoration: 'none', color: 'inherit' }}
>
<Stack direction="row" align="center" gap={2}>
<ImGithub />
<Text>{t('general.words.github')}</Text>
</Stack>
</a>
<Text>•</Text>
<Text color="gray.500">
{t('general.words.version')} {version}
</Text>
<Text>•</Text>
<Text>
© {copyrightYear} {t('general.words.flashNotes')}
</Text>
</Stack>
<Text mt={2} fontSize="sm" color="gray.400" textAlign="center">
<Link to="/thanks">
{t('routes.publicLayout.thanks.link', 'Thanks to all contributors')}
</Link>
</Text>
</Stack>
</>
)
}
27 changes: 27 additions & 0 deletions frontend/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Route as rootRoute } from './routes/__root'
import { Route as PublicLayoutImport } from './routes/_publicLayout'
import { Route as LayoutImport } from './routes/_layout'
import { Route as PublicLayoutIndexImport } from './routes/_publicLayout/index'
import { Route as PublicLayoutThanksImport } from './routes/_publicLayout/thanks'
import { Route as PublicLayoutSignupImport } from './routes/_publicLayout/signup'
import { Route as PublicLayoutLoginImport } from './routes/_publicLayout/login'
import { Route as LayoutCollectionsIndexImport } from './routes/_layout/collections/index'
Expand Down Expand Up @@ -41,6 +42,12 @@ const PublicLayoutIndexRoute = PublicLayoutIndexImport.update({
getParentRoute: () => PublicLayoutRoute,
} as any)

const PublicLayoutThanksRoute = PublicLayoutThanksImport.update({
id: '/thanks',
path: '/thanks',
getParentRoute: () => PublicLayoutRoute,
} as any)

const PublicLayoutSignupRoute = PublicLayoutSignupImport.update({
id: '/signup',
path: '/signup',
Expand Down Expand Up @@ -126,6 +133,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof PublicLayoutSignupImport
parentRoute: typeof PublicLayoutImport
}
'/_publicLayout/thanks': {
id: '/_publicLayout/thanks'
path: '/thanks'
fullPath: '/thanks'
preLoaderRoute: typeof PublicLayoutThanksImport
parentRoute: typeof PublicLayoutImport
}
'/_publicLayout/': {
id: '/_publicLayout/'
path: '/'
Expand Down Expand Up @@ -209,12 +223,14 @@ const LayoutRouteWithChildren =
interface PublicLayoutRouteChildren {
PublicLayoutLoginRoute: typeof PublicLayoutLoginRoute
PublicLayoutSignupRoute: typeof PublicLayoutSignupRoute
PublicLayoutThanksRoute: typeof PublicLayoutThanksRoute
PublicLayoutIndexRoute: typeof PublicLayoutIndexRoute
}

const PublicLayoutRouteChildren: PublicLayoutRouteChildren = {
PublicLayoutLoginRoute: PublicLayoutLoginRoute,
PublicLayoutSignupRoute: PublicLayoutSignupRoute,
PublicLayoutThanksRoute: PublicLayoutThanksRoute,
PublicLayoutIndexRoute: PublicLayoutIndexRoute,
}

Expand All @@ -226,6 +242,7 @@ export interface FileRoutesByFullPath {
'': typeof PublicLayoutRouteWithChildren
'/login': typeof PublicLayoutLoginRoute
'/signup': typeof PublicLayoutSignupRoute
'/thanks': typeof PublicLayoutThanksRoute
'/': typeof PublicLayoutIndexRoute
'/collections': typeof LayoutCollectionsIndexRoute
'/collections/$collectionId/practice': typeof LayoutCollectionsCollectionIdPracticeRoute
Expand All @@ -239,6 +256,7 @@ export interface FileRoutesByTo {
'': typeof LayoutRouteWithChildren
'/login': typeof PublicLayoutLoginRoute
'/signup': typeof PublicLayoutSignupRoute
'/thanks': typeof PublicLayoutThanksRoute
'/': typeof PublicLayoutIndexRoute
'/collections': typeof LayoutCollectionsIndexRoute
'/collections/$collectionId/practice': typeof LayoutCollectionsCollectionIdPracticeRoute
Expand All @@ -254,6 +272,7 @@ export interface FileRoutesById {
'/_publicLayout': typeof PublicLayoutRouteWithChildren
'/_publicLayout/login': typeof PublicLayoutLoginRoute
'/_publicLayout/signup': typeof PublicLayoutSignupRoute
'/_publicLayout/thanks': typeof PublicLayoutThanksRoute
'/_publicLayout/': typeof PublicLayoutIndexRoute
'/_layout/collections/': typeof LayoutCollectionsIndexRoute
'/_layout/collections/$collectionId/practice': typeof LayoutCollectionsCollectionIdPracticeRoute
Expand All @@ -269,6 +288,7 @@ export interface FileRouteTypes {
| ''
| '/login'
| '/signup'
| '/thanks'
| '/'
| '/collections'
| '/collections/$collectionId/practice'
Expand All @@ -281,6 +301,7 @@ export interface FileRouteTypes {
| ''
| '/login'
| '/signup'
| '/thanks'
| '/'
| '/collections'
| '/collections/$collectionId/practice'
Expand All @@ -294,6 +315,7 @@ export interface FileRouteTypes {
| '/_publicLayout'
| '/_publicLayout/login'
| '/_publicLayout/signup'
| '/_publicLayout/thanks'
| '/_publicLayout/'
| '/_layout/collections/'
| '/_layout/collections/$collectionId/practice'
Expand Down Expand Up @@ -344,6 +366,7 @@ export const routeTree = rootRoute
"children": [
"/_publicLayout/login",
"/_publicLayout/signup",
"/_publicLayout/thanks",
"/_publicLayout/"
]
},
Expand All @@ -355,6 +378,10 @@ export const routeTree = rootRoute
"filePath": "_publicLayout/signup.tsx",
"parent": "/_publicLayout"
},
"/_publicLayout/thanks": {
"filePath": "_publicLayout/thanks.tsx",
"parent": "/_publicLayout"
},
"/_publicLayout/": {
"filePath": "_publicLayout/index.tsx",
"parent": "/_publicLayout"
Expand Down
Loading