1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-08-05 05:05:17 +02:00

Merge pull request #36 from seanmorley15/development

Development
This commit is contained in:
Sean Morley 2024-04-16 20:21:49 -04:00 committed by GitHub
commit fdc0955cc8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 2243 additions and 47 deletions

View file

@ -0,0 +1,6 @@
ALTER TABLE "userVisitedWorldTravel" ADD COLUMN "country_code" text NOT NULL;--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "userVisitedWorldTravel" ADD CONSTRAINT "userVisitedWorldTravel_country_code_worldTravelCountries_country_code_fk" FOREIGN KEY ("country_code") REFERENCES "worldTravelCountries"("country_code") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

View file

@ -0,0 +1 @@
ALTER TABLE "worldTravelCountryRegions" ADD COLUMN "info" json;

View file

@ -0,0 +1,385 @@
{
"id": "4c095e1a-9f13-4899-aa83-f56864191f51",
"prevId": "b6ab23b7-42f0-4475-aa5d-23b92c00e97f",
"version": "5",
"dialect": "pg",
"tables": {
"featuredAdventures": {
"name": "featuredAdventures",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"featuredAdventures_name_unique": {
"name": "featuredAdventures_name_unique",
"nullsNotDistinct": false,
"columns": [
"name"
]
}
}
},
"session": {
"name": "session",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"session_user_id_user_id_fk": {
"name": "session_user_id_user_id_fk",
"tableFrom": "session",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"sharedAdventures": {
"name": "sharedAdventures",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"data": {
"name": "data",
"type": "json",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date": {
"name": "date",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true
},
"first_name": {
"name": "first_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"last_name": {
"name": "last_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"icon": {
"name": "icon",
"type": "text",
"primaryKey": false,
"notNull": false
},
"hashed_password": {
"name": "hashed_password",
"type": "varchar",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"userVisitedAdventures": {
"name": "userVisitedAdventures",
"schema": "",
"columns": {
"adventure_id": {
"name": "adventure_id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"adventure_name": {
"name": "adventure_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "text",
"primaryKey": false,
"notNull": false
},
"visited_date": {
"name": "visited_date",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"userVisitedAdventures_user_id_user_id_fk": {
"name": "userVisitedAdventures_user_id_user_id_fk",
"tableFrom": "userVisitedAdventures",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"userVisitedWorldTravel": {
"name": "userVisitedWorldTravel",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"country_code": {
"name": "country_code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"region_id": {
"name": "region_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"userVisitedWorldTravel_country_code_worldTravelCountries_country_code_fk": {
"name": "userVisitedWorldTravel_country_code_worldTravelCountries_country_code_fk",
"tableFrom": "userVisitedWorldTravel",
"tableTo": "worldTravelCountries",
"columnsFrom": [
"country_code"
],
"columnsTo": [
"country_code"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"userVisitedWorldTravel_user_id_user_id_fk": {
"name": "userVisitedWorldTravel_user_id_user_id_fk",
"tableFrom": "userVisitedWorldTravel",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"userVisitedWorldTravel_region_id_worldTravelCountryRegions_id_fk": {
"name": "userVisitedWorldTravel_region_id_worldTravelCountryRegions_id_fk",
"tableFrom": "userVisitedWorldTravel",
"tableTo": "worldTravelCountryRegions",
"columnsFrom": [
"region_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"worldTravelCountries": {
"name": "worldTravelCountries",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"country_code": {
"name": "country_code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"continent": {
"name": "continent",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"worldTravelCountries_country_code_unique": {
"name": "worldTravelCountries_country_code_unique",
"nullsNotDistinct": false,
"columns": [
"country_code"
]
}
}
},
"worldTravelCountryRegions": {
"name": "worldTravelCountryRegions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"country_code": {
"name": "country_code",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"worldTravelCountryRegions_country_code_worldTravelCountries_country_code_fk": {
"name": "worldTravelCountryRegions_country_code_worldTravelCountries_country_code_fk",
"tableFrom": "worldTravelCountryRegions",
"tableTo": "worldTravelCountries",
"columnsFrom": [
"country_code"
],
"columnsTo": [
"country_code"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"schemas": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View file

@ -0,0 +1,391 @@
{
"id": "91692e84-91ec-4411-ad9d-7b8b14f67dda",
"prevId": "4c095e1a-9f13-4899-aa83-f56864191f51",
"version": "5",
"dialect": "pg",
"tables": {
"featuredAdventures": {
"name": "featuredAdventures",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"featuredAdventures_name_unique": {
"name": "featuredAdventures_name_unique",
"nullsNotDistinct": false,
"columns": [
"name"
]
}
}
},
"session": {
"name": "session",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"session_user_id_user_id_fk": {
"name": "session_user_id_user_id_fk",
"tableFrom": "session",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"sharedAdventures": {
"name": "sharedAdventures",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"data": {
"name": "data",
"type": "json",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"date": {
"name": "date",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true
},
"first_name": {
"name": "first_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"last_name": {
"name": "last_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"icon": {
"name": "icon",
"type": "text",
"primaryKey": false,
"notNull": false
},
"hashed_password": {
"name": "hashed_password",
"type": "varchar",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"userVisitedAdventures": {
"name": "userVisitedAdventures",
"schema": "",
"columns": {
"adventure_id": {
"name": "adventure_id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"adventure_name": {
"name": "adventure_name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"location": {
"name": "location",
"type": "text",
"primaryKey": false,
"notNull": false
},
"visited_date": {
"name": "visited_date",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"userVisitedAdventures_user_id_user_id_fk": {
"name": "userVisitedAdventures_user_id_user_id_fk",
"tableFrom": "userVisitedAdventures",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"userVisitedWorldTravel": {
"name": "userVisitedWorldTravel",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"country_code": {
"name": "country_code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"region_id": {
"name": "region_id",
"type": "varchar",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {
"userVisitedWorldTravel_country_code_worldTravelCountries_country_code_fk": {
"name": "userVisitedWorldTravel_country_code_worldTravelCountries_country_code_fk",
"tableFrom": "userVisitedWorldTravel",
"tableTo": "worldTravelCountries",
"columnsFrom": [
"country_code"
],
"columnsTo": [
"country_code"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"userVisitedWorldTravel_user_id_user_id_fk": {
"name": "userVisitedWorldTravel_user_id_user_id_fk",
"tableFrom": "userVisitedWorldTravel",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"userVisitedWorldTravel_region_id_worldTravelCountryRegions_id_fk": {
"name": "userVisitedWorldTravel_region_id_worldTravelCountryRegions_id_fk",
"tableFrom": "userVisitedWorldTravel",
"tableTo": "worldTravelCountryRegions",
"columnsFrom": [
"region_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
},
"worldTravelCountries": {
"name": "worldTravelCountries",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"country_code": {
"name": "country_code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"continent": {
"name": "continent",
"type": "text",
"primaryKey": false,
"notNull": true
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"worldTravelCountries_country_code_unique": {
"name": "worldTravelCountries_country_code_unique",
"nullsNotDistinct": false,
"columns": [
"country_code"
]
}
}
},
"worldTravelCountryRegions": {
"name": "worldTravelCountryRegions",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "varchar",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"country_code": {
"name": "country_code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"info": {
"name": "info",
"type": "json",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {
"worldTravelCountryRegions_country_code_worldTravelCountries_country_code_fk": {
"name": "worldTravelCountryRegions_country_code_worldTravelCountries_country_code_fk",
"tableFrom": "worldTravelCountryRegions",
"tableTo": "worldTravelCountries",
"columnsFrom": [
"country_code"
],
"columnsTo": [
"country_code"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {}
}
},
"enums": {},
"schemas": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}

View file

@ -8,6 +8,20 @@
"when": 1713037717607,
"tag": "0000_hard_mach_iv",
"breakpoints": true
},
{
"idx": 1,
"version": "5",
"when": 1713050481064,
"tag": "0001_closed_wendell_vaughn",
"breakpoints": true
},
{
"idx": 2,
"version": "5",
"when": 1713125110816,
"tag": "0002_far_mephistopheles",
"breakpoints": true
}
]
}

View file

@ -1,5 +1,222 @@
INSERT INTO "worldTravelCountryRegions" (id, name, country_code)
VALUES
-- INSERT INTO "worldTravelCountryRegions" (id, name, country_code)
-- VALUES
-- ('US-AL', 'Alabama', 'us', '{
-- "name": "Alabama",
-- "abbreviation": "AL",
-- "description": "Alabama is a state located in the southeastern region of the United States. Known for its rich history, including its role in the American Civil War and the Civil Rights Movement, Alabama offers a diverse landscape of mountains, plains, and coastal areas. The state boasts a humid subtropical climate and is known for its strong tradition in college sports, particularly football. Alabama''s economy is diverse, with major industries including automotive manufacturing, agriculture, and aerospace. Tourists are drawn to Alabama''s natural beauty, historical sites, and cultural landmarks.",
-- "capital": "Montgomery",
-- "largest_city": "Birmingham",
-- "area": {
-- "total": 52420,
-- "units": "square miles"
-- },
-- "population": {
-- "estimate": 4903185,
-- "year": 2020
-- },
-- "state_flower": "Camellia",
-- "state_bird": "Yellowhammer",
-- "state_tree": "Southern Longleaf Pine",
-- "climate": {
-- "description": "Humid subtropical",
-- "summer_highs": "80-90°F",
-- "winter_lows": "30-50°F",
-- "precipitation": "Abundant throughout the year"
-- },
-- "economy": {
-- "industries": [
-- "Automotive Manufacturing",
-- "Agriculture",
-- "Mining",
-- "Technology",
-- "Aerospace"
-- ],
-- "agricultural_products": [
-- "Poultry",
-- "Cotton",
-- "Peanuts",
-- "Soybeans",
-- "Corn"
-- ]
-- },
-- "tourism": {
-- "attractions": [
-- "U.S. Space & Rocket Center",
-- "Gulf Shores and Orange Beach",
-- "Rosa Parks Museum",
-- "Civil Rights Institute",
-- "Little River Canyon National Preserve"
-- ]
-- },
-- "major_sports_teams": [
-- "Alabama Crimson Tide (NCAA)",
-- "Auburn Tigers (NCAA)"
-- ]
-- }'),
-- ('US-AK', 'Alaska', 'us', '{
-- "name": "Alaska",
-- "abbreviation": "AK",
-- "description": "Alaska is the largest state in the United States by area, known for its rugged and breathtaking natural beauty. It is situated in the northwesternmost region of North America and is bordered by Canada to the east, the Arctic Ocean to the north, and the Pacific Ocean to the west and south. Alaska is renowned for its diverse wildlife, glaciers, and majestic mountains. The state is sparsely populated, with the majority of its residents living in and around Anchorage and Fairbanks. Alaska''s economy is heavily dependent on oil and gas production, as well as fishing, tourism, and mining.",
-- "capital": "Juneau",
-- "largest_city": "Anchorage",
-- "area": {
-- "total": 663267,
-- "units": "square miles"
-- },
-- "population": {
-- "estimate": 731158,
-- "year": 2020
-- },
-- "state_flower": "Forget-Me-Not",
-- "state_bird": "Willow Ptarmigan",
-- "state_tree": "Sitka Spruce",
-- "climate": {
-- "description": "Varies by region, with subarctic and arctic climates in the interior and north and more temperate maritime climates along the coast.",
-- "summer_highs": "50-70°F (varies by region)",
-- "winter_lows": "-40 to 20°F (varies by region)",
-- "precipitation": "Ranges from low in the interior to high along the coast"
-- },
-- "economy": {
-- "industries": [
-- "Oil and Gas",
-- "Fishing",
-- "Mining",
-- "Tourism",
-- "Forestry"
-- ],
-- "agricultural_products": [
-- "Cattle",
-- "Hay",
-- "Vegetables",
-- "Barley",
-- "Dairy products"
-- ]
-- },
-- "tourism": {
-- "attractions": [
-- "Denali National Park",
-- "Glacier Bay National Park",
-- "Kenai Fjords National Park",
-- "Sitka National Historical Park",
-- "Anchorage Museum"
-- ]
-- },
-- "major_sports_teams": [
-- "Anchorage Wolverines (NAHL)",
-- "Alaska Aces (ECHL, formerly)"
-- ]
-- }
-- '),
-- ('US-AZ', 'Arizona', 'us', '{
-- "name": "Arizona",
-- "abbreviation": "AZ",
-- "description": "Arizona is a state located in the southwestern region of the United States, known for its dramatic desert landscapes and vibrant history. The state is home to iconic landmarks such as the Grand Canyon and Monument Valley. Arizona''s diverse geography includes mountain ranges, forests, and high plateaus. The state has a warm desert climate in the southern and central areas and cooler mountain climates in the northern region. Arizona''s economy is driven by industries such as healthcare, technology, manufacturing, and tourism.",
-- "capital": "Phoenix",
-- "largest_city": "Phoenix",
-- "area": {
-- "total": 113990,
-- "units": "square miles"
-- },
-- "population": {
-- "estimate": 7151502,
-- "year": 2020
-- },
-- "state_flower": "Saguaro Cactus Blossom",
-- "state_bird": "Cactus Wren",
-- "state_tree": "Palo Verde",
-- "climate": {
-- "description": "Mostly arid and semi-arid, with desert climates in the southern and central regions and temperate climates in the north.",
-- "summer_highs": "85-120°F (varies by region)",
-- "winter_lows": "30-60°F (varies by region)",
-- "precipitation": "Low in most areas, with higher amounts in mountain regions"
-- },
-- "economy": {
-- "industries": [
-- "Healthcare",
-- "Technology",
-- "Manufacturing",
-- "Tourism",
-- "Agriculture"
-- ],
-- "agricultural_products": [
-- "Cattle",
-- "Dairy",
-- "Lettuce",
-- "Cotton",
-- "Alfalfa"
-- ]
-- },
-- "tourism": {
-- "attractions": [
-- "Grand Canyon National Park",
-- "Sedona",
-- "Monument Valley",
-- "Saguaro National Park",
-- "Petrified Forest National Park"
-- ]
-- },
-- "major_sports_teams": [
-- "Arizona Cardinals (NFL)",
-- "Phoenix Suns (NBA)",
-- "Arizona Diamondbacks (MLB)",
-- "Arizona Coyotes (NHL)"
-- ]
-- }
-- '),
-- ('US-AR', 'Arkansas', 'us', '{
-- "name": "Arkansas",
-- "abbreviation": "AR",
-- "description": "Arkansas is a state located in the southeastern region of the United States, known for its natural beauty and diverse landscapes that include mountains, forests, and rivers. The state is nicknamed ''The Natural State'' due to its abundant natural resources and outdoor recreational opportunities. Arkansas has a rich history and played a significant role during the American Civil War. The state''s economy is driven by agriculture, manufacturing, and tourism, with key agricultural products including rice, poultry, and soybeans.",
-- "capital": "Little Rock",
-- "largest_city": "Little Rock",
-- "area": {
-- "total": 53179,
-- "units": "square miles"
-- },
-- "population": {
-- "estimate": 3013756,
-- "year": 2020
-- },
-- "state_flower": "Apple Blossom",
-- "state_bird": "Northern Mockingbird",
-- "state_tree": "Pine",
-- "climate": {
-- "description": "Humid subtropical climate, with hot summers and mild winters.",
-- "summer_highs": "80-90°F",
-- "winter_lows": "20-40°F",
-- "precipitation": "High, especially in the spring"
-- },
-- "economy": {
-- "industries": [
-- "Agriculture",
-- "Manufacturing",
-- "Retail",
-- "Tourism",
-- "Education"
-- ],
-- "agricultural_products": [
-- "Rice",
-- "Poultry",
-- "Soybeans",
-- "Cotton",
-- "Catfish"
-- ]
-- },
-- "tourism": {
-- "attractions": [
-- "Hot Springs National Park",
-- "Buffalo National River",
-- "Crater of Diamonds State Park",
-- "Little Rock Central High School National Historic Site",
-- "Ozark National Forest"
-- ]
-- },
-- "major_sports_teams": [
-- "Arkansas Razorbacks (NCAA)"
-- ]
-- }
-- '),
INSERT INTO "worldTravelCountryRegions" (id, name, country_code) VALUES
('US-AL', 'Alabama', 'us'),
('US-AK', 'Alaska', 'us'),
('US-AZ', 'Arizona', 'us'),

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="en" data-theme="">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />

View file

@ -1,7 +1,8 @@
import { lucia } from "$lib/server/auth";
import type { Handle } from "@sveltejs/kit";
import { sequence } from '@sveltejs/kit/hooks';
export const handle: Handle = async ({ event, resolve }) => {
export const authHook: Handle = async ({ event, resolve }) => {
const sessionId = event.cookies.get(lucia.sessionCookieName);
if (!sessionId) {
event.locals.user = null;
@ -20,7 +21,7 @@ export const handle: Handle = async ({ event, resolve }) => {
});
}
if (!session) {
const sessionCookie = lucia.createBlankSessionCookie();
const sessionCookie:any = lucia.createBlankSessionCookie();
event.cookies.set(sessionCookie.name, sessionCookie.value, {
path: ".",
...sessionCookie.attributes,
@ -30,3 +31,26 @@ export const handle: Handle = async ({ event, resolve }) => {
event.locals.session = session;
return resolve(event);
};
export const themeHook: Handle = async ({ event, resolve }) => {
let theme:String | null = null;
const newTheme = event.url.searchParams.get("theme");
const cookieTheme = event.cookies.get("colortheme");
if(newTheme) {
theme = newTheme;
} else if (cookieTheme) {
theme = cookieTheme;
}
if (theme) {
return await resolve(event, {
transformPageChunk: ({ html }) =>
html.replace('data-theme=""', `data-theme="${theme}"`)
})
}
return await resolve(event);
}
export const handle = sequence(authHook, themeHook);

View file

@ -2,6 +2,7 @@
import { createEventDispatcher } from "svelte";
import locationDot from "$lib/assets/locationDot.svg";
import calendar from "$lib/assets/calendar.svg";
import { goto } from "$app/navigation";
const dispatch = createEventDispatcher();
export let type: String;
@ -12,6 +13,7 @@
export let id: Number | undefined = undefined;
export let regionId: String | undefined = undefined;
export let visited: Boolean | undefined = undefined;
export let countryCode: String | undefined = undefined;
function remove() {
dispatch("remove", id);
@ -30,11 +32,15 @@
dispatch("removeVisit", regionId);
visited = false;
}
function moreInfo() {
goto(`/worldtravel/${countryCode}/${regionId}`);
}
</script>
{#if type === "mylog"}
<div
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden"
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-primary-content shadow-xl overflow-hidden text-base-content"
>
<div class="card-body">
<h2 class="card-title overflow-ellipsis">{name}</h2>
@ -66,7 +72,7 @@
{#if type === "featured"}
<div
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden"
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-primary-content shadow-xl overflow-hidden text-base-content"
>
<div class="card-body">
<h2 class="card-title overflow-ellipsis">{name}</h2>
@ -88,7 +94,7 @@
{#if type === "shared"}
<div
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden"
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-primary-content shadow-xl overflow-hidden text-base-content"
>
<div class="card-body">
<h2 class="card-title overflow-ellipsis">{name}</h2>
@ -116,12 +122,13 @@
{#if type === "worldtravelregion"}
<div
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-neutral shadow-xl overflow-hidden"
class="card min-w-max lg:w-96 md:w-80 sm:w-60 xs:w-40 bg-primary-content shadow-xl overflow-hidden text-base-content"
>
<div class="card-body">
<h2 class="card-title overflow-ellipsis">{name}</h2>
<p>{regionId}</p>
<div class="card-actions justify-end">
<!-- <button class="btn btn-info" on:click={moreInfo}>More Info</button> -->
{#if !visited}
<button class="btn btn-primary" on:click={markVisited}
>Mark Visited</button

View file

@ -8,6 +8,7 @@
import { onMount } from "svelte";
import InfoModal from "./InfoModal.svelte";
import infoIcon from "$lib/assets/info.svg";
import type { SubmitFunction } from "@sveltejs/kit";
async function goHome() {
goto("/");
}
@ -27,6 +28,13 @@
goto("/worldtravel");
}
const submitUpdateTheme: SubmitFunction = ({ action }) => {
const theme = action.searchParams.get("theme");
if (theme) {
document.documentElement.setAttribute("data-theme", theme);
}
};
let count = 0;
let infoModalOpen = false;
@ -97,5 +105,22 @@
<UserAvatar {user} />
{/if}
<button class="btn btn-neutral ml-4" on:click={showModal}>About</button>
<div class="dropdown dropdown-bottom dropdown-end">
<div tabindex="0" role="button" class="btn m-1 ml-4">Themes</div>
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<ul
tabindex="0"
class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52"
>
<form method="POST" use:enhance={submitUpdateTheme}>
<li><button formaction="/?/setTheme&theme=light">Light</button></li>
<li><button formaction="/?/setTheme&theme=dark">Dark</button></li>
<li><button formaction="/?/setTheme&theme=night">Night</button></li>
<!-- <li><button formaction="/?/setTheme&theme=nord">Nord</button></li> -->
<!-- <li><button formaction="/?/setTheme&theme=retro">Retro</button></li> -->
<li><button formaction="/?/setTheme&theme=forest">Forest</button></li>
</form>
</ul>
</div>
</div>
</div>

View file

@ -37,8 +37,8 @@
<li><a>Profile</a></li>
<li><button on:click={navToLog}>My Log</button></li>
<li><button on:click={navToSettings}>Settings</button></li>
<form method="post" action="/" use:enhance>
<li><button>Logout</button></li>
<form method="post">
<li><button formaction="/?/logout">Logout</button></li>
</form>
</ul>
</div>

File diff suppressed because one or more lines are too long

View file

@ -66,10 +66,14 @@ export const worldTravelCountryRegions = pgTable("worldTravelCountryRegions", {
country_code: text("country_code")
.notNull()
.references(() => worldTravelCountries.country_code),
info: json("info"),
});
export const userVisitedWorldTravel = pgTable("userVisitedWorldTravel", {
id: serial("id").primaryKey(),
country_code: text("country_code")
.notNull()
.references(() => worldTravelCountries.country_code),
userId: text("user_id")
.notNull()
.references(() => userTable.id),

View file

@ -4,3 +4,36 @@ export interface Adventure {
location: string;
created: string;
}
export interface RegionInfo {
name: string;
abbreviation: string;
description: string;
capital: string;
largest_city: string;
area: {
total: number;
units: string;
};
population: {
estimate: number;
year: number;
};
state_flower: string;
state_bird: string;
state_tree: string;
climate: {
description: string;
summer_highs: string;
winter_lows: string;
precipitation: string;
};
economy: {
industries: string[];
agricultural_products: string[];
};
tourism: {
attractions: string[];
};
major_sports_teams: string[];
};

View file

@ -2,8 +2,8 @@
export let data;
import Footer from "$lib/components/Footer.svelte";
import Navbar from "$lib/components/Navbar.svelte";
import type { SubmitFunction } from "@sveltejs/kit";
import "../app.css";
// only show footer if scrolled to the bottom
</script>
<!-- passes the user object to the navbar component -->

View file

@ -3,7 +3,7 @@ import { fail, redirect } from "@sveltejs/kit";
import type { Actions, PageServerLoad } from "./$types";
export const load: PageServerLoad = async (event) => {
export const load: PageServerLoad = async (event: { locals: { user: any; }; }) => {
if (event.locals.user)
return {
user: event.locals.user,
@ -15,7 +15,7 @@ export const load: PageServerLoad = async (event) => {
// handle the logout action
export const actions: Actions = {
default: async (event) => {
logout: async (event) => {
if (!event.locals.session) {
return fail(401);
}
@ -28,4 +28,14 @@ export const actions: Actions = {
});
return redirect(302, "/login");
},
setTheme: async ( { url, cookies }) => {
const theme = url.searchParams.get("theme");
// change the theme only if it is one of the allowed themes
if (theme && ["light", "dark", "night", "retro", "forest", "nord"].includes(theme)) {
cookies.set("colortheme", theme, {
path: "/",
maxAge: 60 * 60 * 24 * 365,
});
}
},
};

View file

@ -18,6 +18,7 @@ export async function POST(event: RequestEvent): Promise<Response> {
.values({
userId: event.locals.user.id,
region_id: body.region_id,
country_code: body.country_code,
})
.execute();
return new Response(JSON.stringify({ res: res }), {

View file

@ -6,7 +6,6 @@
import AdventureCard from "$lib/components/AdventureCard.svelte";
import type { Adventure } from "$lib/utils/types";
import { onMount } from "svelte";
import { exportData } from "../../services/export";
import exportFile from "$lib/assets/exportFile.svg";
import deleteIcon from "$lib/assets/deleteIcon.svg";
import SucessToast from "$lib/components/SucessToast.svelte";
@ -48,6 +47,18 @@
}, 3000);
}
function exportData() {
let jsonString = JSON.stringify(adventures);
let blob = new Blob([jsonString], { type: "application/json" });
let url = URL.createObjectURL(blob);
let link = document.createElement("a");
link.download = "adventurelog-export.json";
link.href = url;
link.click();
URL.revokeObjectURL(url);
}
const createNewAdventure = () => {
let currentDate = new Date();
let dateString = currentDate.toISOString().slice(0, 10); // Get date in "yyyy-mm-dd" format
@ -290,12 +301,7 @@
<div
class="flex flex-row items-center justify-center mt-2 gap-4 mb-4 flex-wrap"
>
<button
class="btn btn-neutral"
on:click={async () => {
window.location.href = exportData();
}}
>
<button class="btn btn-neutral" on:click={exportData}>
<img src={exportFile} class="inline-block -mt-1" alt="Logo" /> Save as File
</button>
<button class="btn btn-neutral" on:click={deleteData}>

View file

@ -1,5 +1,5 @@
import { lucia } from "$lib/server/auth";
import { fail, redirect } from "@sveltejs/kit";
import { error, fail, redirect } from "@sveltejs/kit";
import { Argon2id } from "oslo/password";
import { db } from "$lib/db/db.server";
@ -22,8 +22,8 @@ export const actions: Actions = {
const password = formData.get("password");
if (!username || !password) {
return fail(400, {
message: "Invalid request",
return error(400, {
message: "Missing username or password",
});
}
@ -33,7 +33,7 @@ export const actions: Actions = {
username.length > 31 ||
!/^[a-z0-9_-]+$/.test(username)
) {
return fail(400, {
return error(400, {
message: "Invalid username",
});
}
@ -42,7 +42,7 @@ export const actions: Actions = {
password.length < 6 ||
password.length > 255
) {
return fail(400, {
return error(400, {
message: "Invalid password",
});
}
@ -55,7 +55,7 @@ export const actions: Actions = {
.then((results) => results[0] as unknown as DatabaseUser | undefined);
if (!existingUser) {
return fail(400, {
return error(400, {
message: "Incorrect username or password",
});
}
@ -65,7 +65,7 @@ export const actions: Actions = {
password
);
if (!validPassword) {
return fail(400, {
return error(400, {
message: "Incorrect username or password",
});
}
@ -78,5 +78,6 @@ export const actions: Actions = {
});
return redirect(302, "/");
},
};

View file

@ -1,12 +1,34 @@
<!-- routes/login/+page.svelte -->
<script lang="ts">
import { enhance } from "$app/forms";
import { goto } from "$app/navigation";
import { getRandomQuote } from "$lib";
import { redirect, type SubmitFunction } from "@sveltejs/kit";
import { onMount } from "svelte";
let quote: string = "";
let errors: { message?: string } = {};
onMount(async () => {
quote = getRandomQuote();
});
const handleSubmit: SubmitFunction = async ({ formData, action, cancel }) => {
const response = await fetch(action, {
method: "POST",
body: formData,
});
if (response.ok) {
errors = {};
goto("/login");
return;
}
const { type, error } = await response.json();
if (type === "error") {
errors = { message: error.message };
}
console.log(errors);
cancel();
};
</script>
<article class="text-center text-4xl font-extrabold">
@ -14,7 +36,7 @@
</article>
<div class="flex justify-center">
<form method="post" use:enhance class="w-full max-w-xs">
<form method="post" use:enhance={handleSubmit} class="w-full max-w-xs">
<label for="username">Username</label>
<input
name="username"
@ -32,6 +54,12 @@
</form>
</div>
{#if errors.message}
<div class="text-center text-error mt-4">
{errors.message}
</div>
{/if}
<div class="flex justify-center mt-12 mr-25 ml-25">
<blockquote class="w-80 text-center text-lg break-words">
{#if quote != ""}

View file

@ -1,6 +1,6 @@
import { db } from '$lib/db/db.server.js';
import { userVisitedWorldTravel, worldTravelCountryRegions } from '$lib/db/schema.js';
import { eq } from 'drizzle-orm';
import { and, eq } from 'drizzle-orm';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ params, locals }) => {
@ -13,10 +13,16 @@ export const load: PageServerLoad = async ({ params, locals }) => {
let visitedRegions: { id: number; userId: string; region_id: string; }[] = [];
if (locals.user) {
let countryCode = params.countrycode
visitedRegions = await db
.select()
.from(userVisitedWorldTravel)
.where(eq(userVisitedWorldTravel.userId, locals.user.id))
.where(
and(
eq(userVisitedWorldTravel.userId, locals.user.id),
eq(userVisitedWorldTravel.country_code, countryCode)
)
)
.execute();
}

View file

@ -5,6 +5,9 @@
import { getFlag } from "$lib";
import { goto } from "$app/navigation";
import { onMount } from "svelte";
import Us from "$lib/components/maps/US.svelte";
let viewType: String = "cards";
function markVisited(event: { detail: string }) {
console.log(`Marked ${event.detail} as visited`);
@ -15,6 +18,7 @@
},
body: JSON.stringify({
region_id: event.detail,
country_code: data.countrycode,
}),
}).then((response) => {
if (response.status === 401) {
@ -42,6 +46,10 @@
});
}
function setViewType(type: String) {
viewType = type;
}
onMount(() => {
console.log(data.visitedRegions);
});
@ -56,19 +64,46 @@
/>
</h1>
<div
class="grid xl:grid-cols-3 lg:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-4 mt-4 content-center auto-cols-auto ml-6 mr-6"
>
{#each data.regions as region (region.id)}
<AdventureCard
type="worldtravelregion"
regionId={region.id}
name={region.name}
on:markVisited={markVisited}
visited={data.visitedRegions.some(
(visitedRegion) => visitedRegion.region_id === region.id,
)}
on:removeVisit={removeVisit}
/>
{/each}
<div class="join items-center justify-center flex">
<input
class="join-item btn btn-neutral"
type="radio"
name="viewtype"
checked
aria-label="Cards"
on:click={() => setViewType("cards")}
/>
<input
class="join-item btn btn-neutral"
type="radio"
name="viewtype"
aria-label="Map"
on:click={() => setViewType("map")}
/>
</div>
{#if viewType == "cards"}
<div
class="grid xl:grid-cols-3 lg:grid-cols-3 md:grid-cols-2 sm:grid-cols-1 gap-4 mt-4 content-center auto-cols-auto ml-6 mr-6"
>
{#each data.regions as region (region.id)}
<AdventureCard
type="worldtravelregion"
countryCode={data.countrycode}
regionId={region.id}
name={region.name}
on:markVisited={markVisited}
visited={data.visitedRegions.some(
(visitedRegion) => visitedRegion.region_id === region.id,
)}
on:removeVisit={removeVisit}
/>
{/each}
</div>
{/if}
{#if viewType == "map"}
{#if data.countrycode.toLowerCase() == "us"}
<Us on:marked={markVisited} />
{/if}
{/if}

View file

@ -0,0 +1,34 @@
import { db } from '$lib/db/db.server.js';
import { userVisitedWorldTravel, worldTravelCountryRegions } from '$lib/db/schema.js';
import { and, eq } from 'drizzle-orm';
import type { PageServerLoad } from './$types';
import InfoModal from '$lib/components/InfoModal.svelte';
export const load: PageServerLoad = async ({ params, locals }) => {
const { regioncode } = params;
let info = await db
.select({data: worldTravelCountryRegions})
.from(worldTravelCountryRegions)
.where(eq(worldTravelCountryRegions.id, regioncode))
.limit(1)
.execute();
let visited = false;
if (locals.user) {
let userVisited = await db
.select({data: userVisitedWorldTravel})
.from(userVisitedWorldTravel)
.where(and(eq(userVisitedWorldTravel.userId, locals.user.id), eq(userVisitedWorldTravel.region_id, regioncode)))
.limit(1)
.execute();
if (userVisited.length !== 0) {
visited = true;
}
}
return {
info : info[0],
visited : visited,
};
}

View file

@ -0,0 +1,88 @@
<script lang="ts">
import { countryCodeToName } from "$lib";
import type { RegionInfo } from "$lib/utils/types.js";
export let data;
let info = data.info.data.info as RegionInfo;
let country = countryCodeToName(data.info.data.country_code);
let regionName = data.info.data.name;
let visited = data.visited;
</script>
{#if info}
<div class="flex justify-center content-center text-center">
<article class="prose">
<h1>Info About {regionName} in {country}</h1>
{#if visited}
<p>You have visited this region!</p>
{/if}
<h2>Region Info</h2>
{#if info.description}
<p>{info.description}</p>
{/if}
{#if info.capital}
<p><b>Capital:</b> {info.capital}</p>
{/if}
{#if info.population}
<p>
<b>Population:</b>
{info.population.estimate} ({info.population.year})
</p>
{/if}
{#if info.area}
<p><b>Area:</b> {info.area.total} {info.area.units}</p>
{/if}
{#if info.state_flower}
<p><b>State Flower:</b> {info.state_flower}</p>
{/if}
{#if info.state_bird}
<p><b>State Bird:</b> {info.state_bird}</p>
{/if}
{#if info.state_tree}
<p><b>State Tree:</b> {info.state_tree}</p>
{/if}
{#if info.climate}
<p><b>Climate:</b> {info.climate.description}</p>
<p><b>Summer Highs:</b> {info.climate.summer_highs}</p>
<p><b>Winter Lows:</b> {info.climate.winter_lows}</p>
<p><b>Precipitation:</b> {info.climate.precipitation}</p>
{/if}
{#if info.economy}
{#if info.economy.industries && info.economy.industries.length}
<p>
<b>Industries:</b>
{info.economy.industries.join(", ")}
</p>
{/if}
{#if info.economy.agricultural_products && info.economy.agricultural_products.length}
<p>
<b>Agricultural Products:</b>
{info.economy.agricultural_products.join(", ")}
</p>
{/if}
{/if}
{#if info.tourism}
{#if info.tourism.attractions && info.tourism.attractions.length}
<p>
<b>Tourism Attractions:</b>
{info.tourism.attractions.join(", ")}
</p>
{/if}
{/if}
{#if info.major_sports_teams && info.major_sports_teams.length}
<p>
<b>Major Sports Teams:</b>
{info.major_sports_teams.join(", ")}
</p>
{/if}
</article>
</div>
{:else}
<div class="flex justify-center content-center text-center">
<article class="prose">
<h1>Region Not Found</h1>
<p>Sorry, we couldn't find the region you were looking for.</p>
</article>
</div>
{/if}

View file

@ -6,6 +6,6 @@ export default {
},
plugins: [require("@tailwindcss/typography"), require("daisyui")],
daisyui: {
themes: ["night"],
themes: ["light", "dark", "night", "retro", "forest", "nord"],
},
};