├── jest.setup.ts ├── src ├── vite-env.d.ts ├── types │ ├── MapProp.ts │ ├── HistorySkeletonType.ts │ ├── ErrorObject.ts │ ├── ProtectedRouteProps.ts │ ├── BlogPageProps.ts │ ├── AccordionProps.ts │ ├── CardProps.ts │ ├── LoadingContext.ts │ ├── SignInProps.ts │ ├── BlogCardProps.ts │ ├── ModalProps.ts │ ├── BlogGridProps.ts │ ├── BlogPost.ts │ ├── OverviewType.ts │ ├── CitySuggestion.ts │ ├── SidebarTypes.ts │ ├── DayFragmentTypes.ts │ ├── ItineraryContextTypes.ts │ ├── ItineraryTypes.ts │ ├── AuthContextTypes.ts │ ├── GeneralProps.ts │ ├── CostBreakdownTypes.ts │ └── ResponseTypes.ts ├── assets │ ├── ai.webp │ ├── map.webp │ └── passport.webp ├── lib │ └── utils.ts ├── pages │ ├── 404 │ │ └── index.tsx │ ├── auth │ │ ├── account │ │ │ ├── AccountBug.tsx │ │ │ ├── AccountHelp.tsx │ │ │ ├── AccountSubscription.tsx │ │ │ ├── HistorySkeleton.tsx │ │ │ ├── AccountSidebar.tsx │ │ │ └── History.tsx │ │ ├── index.tsx │ │ └── auth │ │ │ ├── AuthWrapper.tsx │ │ │ ├── SignIn.tsx │ │ │ └── SignUp.tsx │ ├── home │ │ ├── index.tsx │ │ ├── Accordion.tsx │ │ ├── CtaSection.tsx │ │ ├── Hero.tsx │ │ ├── AccordionItem.tsx │ │ ├── TypeEffect.tsx │ │ └── About.tsx │ ├── blog │ │ ├── BlogGrid.tsx │ │ ├── index.tsx │ │ ├── __tests__ │ │ │ └── Blogcard.test.tsx │ │ ├── Modal.tsx │ │ └── Blogcard.tsx │ └── planner │ │ ├── Overview.tsx │ │ ├── index.tsx │ │ ├── __tests__ │ │ ├── Overview.test.tsx │ │ └── General.test.tsx │ │ ├── DayFragment.tsx │ │ ├── General.tsx │ │ ├── Map.tsx │ │ ├── CostBreakdown.tsx │ │ ├── ItineraryDisplay.tsx │ │ └── Itinerary.tsx ├── helpers │ └── truncate.ts ├── styles │ ├── animations.css │ ├── blog.css │ └── index.css ├── main.tsx ├── components │ ├── ui │ │ ├── Navbar.tsx │ │ ├── Loading.tsx │ │ ├── Footer.tsx │ │ ├── popover.tsx │ │ ├── card.tsx │ │ ├── button.tsx │ │ ├── DesktopNav.tsx │ │ ├── calendar.tsx │ │ ├── MobileNav.tsx │ │ ├── select.tsx │ │ └── calendar-date-picker.tsx │ └── protected-routes │ │ ├── ProtectedRoute.tsx │ │ └── UserProtectedRoute.tsx ├── hooks │ ├── useResetForm.ts │ ├── __tests__ │ │ ├── useresetForm.test.ts │ │ └── useInputChange.test.ts │ ├── useCityAutocomplete.ts │ ├── useInputChange.ts │ ├── useSubmitItinerary.ts │ └── useItineraryFormValidation.ts ├── context │ ├── LoadingContext.tsx │ ├── ItineraryContext.tsx │ └── AuthContext.tsx ├── services │ ├── placesAPI.ts │ └── gptService.ts ├── utils │ ├── firebaseConfig.ts │ └── firestoreFunctions.ts ├── App.tsx └── data │ ├── faqData.ts │ ├── buttonData.ts │ └── exampleResponse.json ├── public ├── icon16.png ├── logo_1.png ├── icon114.png ├── logo.svg └── logo_1.svg ├── vercel.json ├── postcss.config.js ├── .prettierrc ├── vite.config.ts ├── tsconfig.node.json ├── jest.config.ts ├── .gitignore ├── .swcrc ├── .eslintrc.cjs ├── tsconfig.json ├── index.html ├── tailwind.config.js ├── package.json ├── README.md └── LICENSE.md /jest.setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; -------------------------------------------------------------------------------- /src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/types/MapProp.ts: -------------------------------------------------------------------------------- 1 | export interface MapProps { 2 | location: string; 3 | } -------------------------------------------------------------------------------- /public/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xszilard/voyagio/HEAD/public/icon16.png -------------------------------------------------------------------------------- /public/logo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xszilard/voyagio/HEAD/public/logo_1.png -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [{ "source": "/(.*)", "destination": "/" }] 3 | } 4 | -------------------------------------------------------------------------------- /public/icon114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xszilard/voyagio/HEAD/public/icon114.png -------------------------------------------------------------------------------- /src/assets/ai.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xszilard/voyagio/HEAD/src/assets/ai.webp -------------------------------------------------------------------------------- /src/assets/map.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xszilard/voyagio/HEAD/src/assets/map.webp -------------------------------------------------------------------------------- /src/types/HistorySkeletonType.ts: -------------------------------------------------------------------------------- 1 | export type FragmentType = { 2 | times: number; 3 | }; -------------------------------------------------------------------------------- /src/types/ErrorObject.ts: -------------------------------------------------------------------------------- 1 | export interface ErrorObject { 2 | [key: string]: string | null; 3 | } -------------------------------------------------------------------------------- /src/assets/passport.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xszilard/voyagio/HEAD/src/assets/passport.webp -------------------------------------------------------------------------------- /src/types/ProtectedRouteProps.ts: -------------------------------------------------------------------------------- 1 | export type ProtectedRouteProps = { 2 | component: React.ComponentType; 3 | }; -------------------------------------------------------------------------------- /src/types/BlogPageProps.ts: -------------------------------------------------------------------------------- 1 | // src/types/BlogPageProps.ts 2 | export interface BlogPageProps { 3 | 4 | } 5 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /src/types/AccordionProps.ts: -------------------------------------------------------------------------------- 1 | export interface AccordionItemProps { 2 | question: string; 3 | answer: string; 4 | } -------------------------------------------------------------------------------- /src/types/CardProps.ts: -------------------------------------------------------------------------------- 1 | export interface CardProps { 2 | title: string; 3 | description: string; 4 | imageUrl: string; 5 | } -------------------------------------------------------------------------------- /src/types/LoadingContext.ts: -------------------------------------------------------------------------------- 1 | export interface LoadingContextType { 2 | isLoading: boolean; 3 | setLoading: (isLoading: boolean) => void; 4 | } -------------------------------------------------------------------------------- /src/types/SignInProps.ts: -------------------------------------------------------------------------------- 1 | export interface Props { 2 | setState: SetSignInType; 3 | } 4 | 5 | export type SetSignInType = (isSignIn: boolean) => void; -------------------------------------------------------------------------------- /src/types/BlogCardProps.ts: -------------------------------------------------------------------------------- 1 | import { BlogPost } from './BlogPost'; 2 | 3 | export interface BlogCardProps { 4 | post: BlogPost; 5 | onClick: () => void; 6 | } 7 | -------------------------------------------------------------------------------- /src/types/ModalProps.ts: -------------------------------------------------------------------------------- 1 | // src/types/ModalProps.ts 2 | import { BlogPost } from './BlogPost'; 3 | 4 | export interface ModalProps { 5 | post: BlogPost; 6 | onClose: () => void; 7 | } 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"], 3 | "useTabs": true, 4 | "semi": true, 5 | "importFormatting": "singleLine", 6 | "printWidth": 400, 7 | "trailingComma": "es5" 8 | } -------------------------------------------------------------------------------- /src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react-swc' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | -------------------------------------------------------------------------------- /src/pages/404/index.tsx: -------------------------------------------------------------------------------- 1 | const NotFound = () => { 2 | return ( 3 |
4 |

404

5 |
6 | ); 7 | }; 8 | 9 | export default NotFound; 10 | -------------------------------------------------------------------------------- /src/types/BlogGridProps.ts: -------------------------------------------------------------------------------- 1 | // src/types/BlogGridProps.ts 2 | import { BlogPost } from './BlogPost'; 3 | 4 | export interface BlogGridProps { 5 | posts: BlogPost[]; 6 | onCardClick: (post: BlogPost) => void; 7 | } 8 | -------------------------------------------------------------------------------- /src/helpers/truncate.ts: -------------------------------------------------------------------------------- 1 | export const trimStringToCharLimit = (inputString: string, limit: number): string => { 2 | if (inputString.length > limit) { 3 | return inputString.substring(0, limit) + "..."; 4 | } 5 | return inputString; 6 | }; -------------------------------------------------------------------------------- /src/types/BlogPost.ts: -------------------------------------------------------------------------------- 1 | // src/types/BlogPost.ts 2 | export interface BlogPost { 3 | id: number; 4 | title: string; 5 | tags: string[]; 6 | image: string; 7 | content: string; 8 | preview: string; 9 | date: string; 10 | } -------------------------------------------------------------------------------- /src/types/OverviewType.ts: -------------------------------------------------------------------------------- 1 | export type OverviewProps = { 2 | setState: React.Dispatch>; 3 | info: DestinationInfo; 4 | }; 5 | 6 | type DestinationInfo = { 7 | shortDescription: string; 8 | shortHistory: string; 9 | }; -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /src/pages/auth/account/AccountBug.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const AccountBug: React.FC = () => { 4 | return ( 5 |
6 |

Report a Bug

7 |
8 | ); 9 | }; 10 | 11 | export default AccountBug; 12 | -------------------------------------------------------------------------------- /src/pages/auth/account/AccountHelp.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const AccountHelp: React.FC = () => { 4 | return ( 5 |
6 |

Guides & Support

7 |
8 | ); 9 | }; 10 | 11 | export default AccountHelp; 12 | -------------------------------------------------------------------------------- /src/styles/animations.css: -------------------------------------------------------------------------------- 1 | @keyframes fade-in-up { 2 | 0% { 3 | opacity: 0; 4 | transform: translateY(10px); 5 | } 6 | 100% { 7 | opacity: 100; 8 | transform: translateY(0); 9 | } 10 | } 11 | 12 | .animate-fade-in { 13 | animation: fade-in-up 0.5s ease-out forwards; 14 | } -------------------------------------------------------------------------------- /src/types/CitySuggestion.ts: -------------------------------------------------------------------------------- 1 | // src/types/CitySuggestion.ts 2 | export interface CitySuggestion { 3 | name: string; 4 | coordinates: [number, number]; 5 | } 6 | 7 | export interface MapboxFeature { 8 | text: string; // Place name 9 | center: [number, number]; // Coordinates as a tuple of [longitude, latitude] 10 | } 11 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from '@jest/types'; 2 | 3 | const config: Config.InitialOptions = { 4 | preset: 'ts-jest', 5 | testEnvironment: 'jest-environment-jsdom', 6 | transform: { 7 | '^.+\\.(js|jsx|ts|tsx)$': '@swc/jest', 8 | }, 9 | setupFilesAfterEnv: ['/jest.setup.ts'], 10 | }; 11 | 12 | export default config; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /src/styles/blog.css: -------------------------------------------------------------------------------- 1 | .blog-content h3 { 2 | font-weight: bold; 3 | font-size: 1.25rem; 4 | line-height: 1.4; 5 | margin-bottom: 0.5rem; 6 | color: rgb(31 41 55) 7 | } 8 | 9 | .blog-content p { 10 | font-weight: normal; 11 | font-size: 1rem; 12 | line-height: 2; 13 | text-align: justify; 14 | margin-bottom: 1.25rem; 15 | color: rgb(107 114 128); 16 | } -------------------------------------------------------------------------------- /src/pages/home/index.tsx: -------------------------------------------------------------------------------- 1 | import Hero from "./Hero"; 2 | import About from "./About"; 3 | import Accordion from "./Accordion"; 4 | import Footer from "../../components/ui/Footer"; 5 | import CtaSection from "./CtaSection"; 6 | 7 | const Home = () => { 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 |