Notice
Recent Posts
Recent Comments
250x250
Creative Code
Lunar-(14)전체코드 중간 정리1(프론트엔드 부분) 본문
728x90
※pages/login.py 전체 코드
"""Login page. Uses auth_layout to render UI shared with the sign up page."""
import reflex as rx
from lunar.state.auth import AuthState
def login():
return rx.container(
rx.container(height='150px'),
rx.hstack(
rx.vstack(
rx.hstack(
rx.vstack(
rx.container(height='20px'),
rx.image(
src = "/moonico.ico",
width="70px",
height="70px",
),
),
rx.vstack(
rx.container(height='8px'),
rx.container(
rx.text(
"Lunar",
style={
"fontSize": "50px",
"fontWeight": "bolder",
"letterSpacing": "3px",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #24d6d6)",
"-webkit-background-clip": "text",
"color": "black",
},
mb=-3,
),
rx.text(
"Share your daily life with people!",
style={
'background': "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
'background_clip': "text", # 텍스트에만 그라데이션 적용
'color': "transparent", # 텍스트 색상을 투명으로 설정
'font_weight': "bold",
'fontSize':'20px',
},
),
),
),
),
rx.container(height='20px'),
rx.container(
rx.vstack(
rx.container(
rx.input(placeholder="Nickname", on_blur=AuthState.set_username, mb=4),
rx.input(
type_="password",
placeholder="Password",
on_blur=AuthState.set_password,
mb=4,
),
rx.button(
"Log in",
on_click=AuthState.login,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
),
center_content=True,
align_items="left",
bg="white",
border="1px solid #eaeaea",
p=4,
max_width="400px",
border_radius="20px",
background= 'rgb(255,255,255,0.7)'
),
rx.container(height='10px'),
rx.hstack(
rx.container(width='20px'),
rx.vstack(
rx.text(
'Forgot your id? ',
rx.link('Find Id!',href="/findid",color='red.500'),
color='gray.600',
),
rx.text(
'Forgot your password? ',
rx.link('Find Password!',href="/findpassword",color='green.500'),
color="gray.600",
),
rx.text(
"Don't have an account yet? ",
rx.link("Sign up!", href="/signup", color="blue.500"),
color="gray.600",
),
align_items='start',
),
),
rx.container(height='30px') ,
align_items='start',
),
),
width='500px',
height='auto',
center_content=True,
borderRadius='30px',
# boxShadow='10px 10px 100px #79d0ed',
background= 'rgb(255,255,255,0.7)'
),
),
center_content=True,
# justifyContent='center',
maxWidth='auto',
maxHeight='auto',
height='100vh',
background_image = '/deepspace1.gif',
background_size = 'cover',
# background_repeat = 'no-repeat',
# style={
# 'background-image':"url('/space2.jpg')",
# 'background-size':'cover',
# }
)
※pages/findid.py 전체 코드
"""findid page. Uses auth_layout to render UI shared with the sign up page."""
import reflex as rx
from lunar.state.auth import AuthState
def findid():
return rx.container(
rx.container(height='150px'),
rx.hstack(
rx.vstack(
rx.hstack(
rx.vstack(
rx.container(height='20px'),
rx.image(
src = "/moonico.ico",
width="70px",
height="70px",
),
),
rx.vstack(
rx.container(height='8px'),
rx.container(
rx.text(
"Lunar",
style={
"fontSize": "50px",
"fontWeight": "bolder",
"letterSpacing": "3px",
"fontFamily": "Comic Sans MS, Cursive",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #24d6d6)",
"-webkit-background-clip": "text",
"color": "black",
},
mb=-3,
),
rx.text(
"Share your daily life with people!",
style={
'background': "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
'background_clip': "text", # 텍스트에만 그라데이션 적용
'color': "transparent", # 텍스트 색상을 투명으로 설정
'font_weight': "bold",
'fontSize':'20px',
},
),
),
),
),
rx.container(height='30px'),
rx.image(
src = '/space2.jpg',
),
width = '500px',
height= '100%',
),
rx.container(width='30px'),
rx.vstack(
rx.container(height='20px'),
rx.container(
rx.vstack(
rx.container(
rx.input(placeholder="your name", on_blur=AuthState.set_user_find_id_name, mb=4),
rx.input(
placeholder="email",
on_blur=AuthState.set_user_find_id_email,
mb=4,
),
rx.hstack(
rx.input(placeholder='birth year', on_blur=AuthState.set_user_find_id_year),
rx.input(placeholder='birth month', on_blur=AuthState.set_user_find_id_month),
rx.input(placeholder='birth day', on_blur=AuthState.set_user_find_id_day),
),
rx.container(height='10px'),
rx.button(
"Find id",
on_click=AuthState.find_user_id,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
),
center_content=True,
align_items="left",
bg="white",
border="1px solid #eaeaea",
p=4,
max_width="400px",
border_radius="20px",
background= 'rgb(255,255,255,0.7)'
),
rx.container(height='10px'),
rx.vstack(
rx.text(
"Don't have an account yet? ",
rx.link("Sign up!", href="/signup", color="blue.500"),
color="gray.600",
),
rx.text(
"Already have an account? ",
rx.link("Sign in here.", href="/", color="yellow.500"),
color="gray.600",
),
rx.text(
'Forgot your password? ',
rx.link('Find Password!',href='/findpassword', color='green.500'),
color='gray.600',
),
align_items='start',
),
rx.container(height='30px') ,
),
),
width='500px',
height='auto',
center_content=True,
borderRadius='40px',
boxShadow='10px 10px 100px #79d0ed',
background= 'rgb(255,255,255,0.7)'
),
),
center_content=True,
# justifyContent='center',
maxWidth='auto',
maxHeight='auto',
height='100vh',
# style={
# 'background-image':"url('/space2.jpg')",
# 'background-size':'cover',
# }
)
※pages/findpassword.py 전체 코드
"""findpassword page. Uses auth_layout to render UI shared with the sign up page."""
import reflex as rx
from lunar.state.auth import AuthState
def findpassword():
return rx.container(
rx.container(height='150px'),
rx.hstack(
rx.vstack(
rx.hstack(
rx.vstack(
rx.container(height='20px'),
rx.image(
src = "/moonico.ico",
width="70px",
height="70px",
),
),
rx.vstack(
rx.container(height='8px'),
rx.container(
rx.text(
"Lunar",
style={
"fontSize": "50px",
"fontWeight": "bolder",
"letterSpacing": "3px",
"fontFamily": "Comic Sans MS, Cursive",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #24d6d6)",
"-webkit-background-clip": "text",
"color": "black",
},
mb=-3,
),
rx.text(
"Share your daily life with people!",
style={
'background': "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
'background_clip': "text", # 텍스트에만 그라데이션 적용
'color': "transparent", # 텍스트 색상을 투명으로 설정
'font_weight': "bold",
'fontSize':'20px',
},
),
),
),
),
rx.container(height='30px'),
rx.image(
src = '/space2.jpg',
),
width = '500px',
height= '100%',
),
rx.container(width='30px'),
rx.vstack(
rx.container(height='20px'),
rx.container(
rx.vstack(
rx.container(
rx.input(placeholder="id", on_blur=AuthState.set_user_find_password_id, mb=4),
rx.input(
placeholder="email",
on_blur=AuthState.set_user_find_password_email_address,
mb=4,
),
rx.hstack(
rx.input(placeholder='birth year', on_blur=AuthState.set_user_find_password_year),
rx.input(placeholder='birth month', on_blur=AuthState.set_user_find_password_month),
rx.input(placeholder='birth day', on_blur=AuthState.set_user_find_password_day),
),
rx.container(height='10px'),
rx.button(
"Find password",
on_click=AuthState.find_user_password,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
),
center_content=True,
align_items="left",
bg="white",
border="1px solid #eaeaea",
p=4,
max_width="400px",
border_radius="20px",
background= 'rgb(255,255,255,0.7)'
),
rx.container(height='10px'),
rx.vstack(
rx.text(
"Don't have an account yet? ",
rx.link("Sign up!", href="/signup", color="blue.500"),
color="gray.600",
),
rx.text(
"Already have an account? ",
rx.link("Sign in here.", href="/", color="yellow.500"),
color="gray.600",
),
align_items='start',
),
rx.container(height='30px') ,
),
),
width='500px',
height='auto',
center_content=True,
borderRadius='40px',
boxShadow='10px 10px 100px #79d0ed',
background= 'rgb(255,255,255,0.7)'
),
),
center_content=True,
# justifyContent='center',
maxWidth='auto',
maxHeight='auto',
height='100vh',
# style={
# 'background-image':"url('/space2.jpg')",
# 'background-size':'cover',
# }
)
※pages/home.py 전체코드
# lunar.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from lunar.state.base import State
from lunar.state.home import HomeState
# 컴포넌트를 가져옵니다.
from ..components import container
color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(imagepath, href):
"""A tab switcher button."""
return rx.link(
rx.image(
src=imagepath,
height='40px',
width='40px',
),
display="inline-flex",
align_items="center",
py=3,
px=2,
href=href, # 버튼 클릭 시 이동할 경로
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.container(
rx.hstack(
rx.image(
src='/moon.png',
height='60px',
width='60px',
),
rx.text(
"Lunar",
style={
"fontSize": "40px",
"fontWeight": "bolder",
"fontFamily": "Calibri, Calibri",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
rx.container(height='30px'),
rx.vstack(
rx.vstack(
rx.container(height='10px'),
rx.container(
rx.hstack(
rx.image(src='/human.png',height='40px',width='40px'),
rx.text(
'Recommended freinds',
style={
'fontSize':'25px',
'fontWeight':'bolder',
'fontFamily':'Calibri, Calibri',
"background": "-webkit-linear-gradient(-45deg, #8ea6e6, #ad3ce6)",
'-webkit-background-clip':'text',
'color':'transparent',
},
),
),
rx.container(height='10px'),
rx.vstack(
rx.container(height='200px'),
border = '2px solid #000000',
border_radius='30px',
),
),
align_items='start',
),
rx.container(height='30px'),
width = '90%',
align_items="left",
gap=4,
background= 'rgb(255,255,255,0.7)',
border = '2px groove #969394',
box_Shadow = '10px 10px 5px #d61c4e',
border_radius = '30px',
),
py=4,
overflow = 'auto',
)
# 오른쪽에 표시되는 사이드바
def sidebar(HomeState):
"""The sidebar displayed on the right."""
return rx.vstack(
rx.hstack(
rx.image(src='/find2.png',height='35px',width='35px'),
rx.input(
on_change=HomeState.set_friend,
placeholder="Search users", # 사용자 검색을 위한 입력 상자
width="100%",
border = "3px solid #000000",
),
),
rx.container(height='10px'),
rx.foreach(
HomeState.search_users,
lambda user: rx.vstack(
rx.hstack(
rx.avatar(name=user.username, size="sm"), # 검색된 사용자의 아바타 이미지
rx.text(user.username), # 검색된 사용자의 사용자 이름
rx.spacer(),
rx.button(
rx.icon(tag="add"),
on_click=lambda: HomeState.follow_user(user.username), # 사용자를 팔로우하는 버튼
),
width="100%",
),
py=2,
width="100%",
),
),
align_items="start",
gap=4,
h="100%",
py=4,
over_flow='auto',
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.image(src='/find1.png',height='35px',width='35px'),
rx.input(on_change=HomeState.set_search, placeholder="Search contents"), # 콘텐츠 검색을 위한 입력 상자
justify="space-between",
p=4,
)
# 새로운 게시물을 작성하는 컴포저
def composer(HomeState):
"""The composer for new craters."""
return rx.vstack(
rx.container(height='5px'),
rx.vstack(
rx.hstack(
rx.avatar(size="md"), # 사용자의 아바타 이미지
rx.container(width='30px'),
rx.text_area(
value=HomeState.crater,
w='100%',
border=2,
placeholder="What's happening?", # 트윗을 작성하는 입력 상자
resize="none",
py=4,
px=0,
_focus={"border": 0, "outline": 0, "boxShadow": "none"},
on_change=HomeState.set_crater,
),
width='95%',
margin_left = '30px',
),
rx.hstack(
rx.button(
rx.image(src='/fileselect.png',height='35px',width='35px'),
on_click=HomeState.handle_file_selection,
border_radius = '1em',
),
rx.button(
rx.image(src='/selectcancel.png',height='35px',width='35px'),
on_click=HomeState.file_select_cancel,
border_radius = '1em',
),
rx.button(
rx.image(src='/write.png',height='30px',width='30px'),
on_click= HomeState.post_crater,
border_radius="1em",
), # 트윗을 게시하는 버튼
justify_content="flex-end",
px=4,
py=2,
width='100%',
),
rx.modal(
rx.modal_overlay(
rx.modal_content(
rx.modal_header("File upload"),
rx.modal_body(
rx.responsive_grid(
rx.foreach(
HomeState.img,
lambda img: rx.vstack(
rx.image(src=img),
rx.text(img),
),
),
columns=[2],
spacing="5px",
),
),
rx.modal_footer(
rx.button(
"Confirm", on_click=HomeState.change
),
rx.button(
"Cancel",
on_click=HomeState.file_select_cancel,
border_radius="1em",
box_shadow="rgba(151, 65, 252, 0.8) 0 15px 30px -10px",
background_image="linear-gradient(144deg,#AF40FF,#5B42F3 50%,#00DDEB)",
box_sizing="border-box",
color="white",
opacity="0.6",
_hover={"opacity": 1},
),
),
)
),
is_open=HomeState.imgshow,
),
rx.responsive_grid(
rx.foreach(
HomeState.img,
lambda img: rx.vstack(
rx.text(img),
),
),
columns=[2],
spacing="5px",
),
margin_left='5px',
width='97%',
border_radius='20px',
border = '3px solid #000000',
box_Shadow = '10px 10px 5px #dece57',
),
rx.container(height='20px'),
)
# 개별 트윗을 표시하는 함수
def crater(crater):
image_tags = rx.cond(
crater.image_content,
rx.foreach(
crater.image_content.split(", "),
lambda image: rx.image(src=f"/{image}", alt="crater image",max_width = '500px')
),
rx.box() # 이미지가 없는 경우 빈 리스트를 반환합니다.
),
return rx.vstack(
rx.vstack(
rx.hstack(
rx.avatar(name=crater.author, size="md"), # 트윗 작성자의 아바타 이미지
rx.text("@" + crater.author, font_weight="bold",fontSize = '20px'), # 트윗 작성자의 사용자 이름
rx.text("["+ crater.created_at +"]"),
margin='10px',
),
rx.hstack(
rx.container(
width='50px',
),
rx.box(
*image_tags,
rx.container(height='5px'),
rx.text(crater.content, width="100%",fontSize = '15px'), # 트윗 내용
rx.container(height='10px'),
width = '100%',
),
py=4,
gap=1,
width='98%',
margin = '10px',
),
align_items='start',
width='97%',
border = '2px solid #7a7a73',
border_radius = '20px',
box_shadow = '5px 5px 5px #7a7a73',
),
rx.container(height='5px'),
margin_left = '25px',
align_items='start',
width='auto',
)
# 피드 영역
def feed(HomeState):
"""The feed."""
return rx.box(
feed_header(HomeState),
composer(HomeState),
rx.container(height='10px'),
rx.cond(
HomeState.craters,
rx.foreach(
HomeState.craters,
crater
),
rx.vstack(
rx.button(
rx.icon(
tag="repeat",
mr=1,
),
rx.text("Click to load crater"),
on_click=HomeState.get_craters,
), # 트윗을 불러오는 버튼
p=4,
),
),
h="100%",
overflow = 'auto',
)
# 홈 페이지
def home():
State.check_login
return rx.vstack(
rx.grid(
tabs(),
feed(HomeState),
sidebar(HomeState),
grid_template_columns="2fr 5fr 2fr",
width='97%',
h="90vh",
gap=4,
),
rx.grid(
rx.vstack(
rx.container(height='5px'),
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
width = '80%',
_hover={"bg": "orange.400"},
),
width = '100%',
),
rx.vstack(
rx.hstack(
tab_button('/Home.png','/'),
tab_button('/profile.png','/profile'),
tab_button('/map.png','/map'),
tab_button('/chat.png','/chat'),
tab_button('/Aichat.png','/aichat'),
tab_button('/diary.png','/diary'),
tab_button('/video.png','/video'),
tab_button('/game.png','/game'),
tab_button('/music.png','/music'),
tab_button('/weather.png','/weather'),
tab_button('/setting.png','/setting'),
margin_right='5px',
border="1px solid #000000",
border_radius="full",
box_Shadow = '10px 10px 5px #3083f0',
),
width = '100%',
),
rx.vstack(
rx.container(height='5px'),
rx.button(
"Sign out",
on_click=State.logout,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
width = '80%',
),
width = '100%',
),
width='97%',
grid_template_columns="2fr 5fr 2fr",
),
)
※pages/map.py 전체 코드
# lunar.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from lunar.state.base import State
from lunar.state.home import HomeState
# 컴포넌트를 가져옵니다.
from ..components import container
color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(imagepath, href):
"""A tab switcher button."""
return rx.link(
rx.image(
src=imagepath,
height='40px',
width='40px',
),
display="inline-flex",
align_items="center",
py=3,
px=2,
href=href, # 버튼 클릭 시 이동할 경로
)
def hotplace(hotplace):
return rx.box(
rx.button(
f'{hotplace.search_place}',
width='250px',
bg = '#9debf5',
),
rx.container(height='5px'),
align='start',
padding='5px', # 테두리와 내용 사이의 여백 지정
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.vstack(
rx.container(
rx.hstack(
rx.image(
src='/moon.png',
height='60px',
width='60px',
),
rx.text(
"Lunar",
style={
"fontSize": "40px",
"fontWeight": "bolder",
"fontFamily": "Calibri, Calibri",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
rx.vstack(
rx.hstack(
rx.container(width='5px'),
rx.vstack(
rx.container(height='10px'),
rx.vstack(
rx.button('Hot place!(24H)',Font_size = '20px',on_click = HomeState.hotplaces,bg = '#ebf564'),
),
rx.container(height='5px'),
rx.foreach(
HomeState.map_hotplaces,
hotplace,
),
rx.container(height='4px'),
width ='100%',
align_items='start',
),
),
align_items = 'start',
margin_left = '20px',
border = '3px solid #000000',
border_radius = '30px',
box_Shadow = '10px 10px 5px #d61c4e',
width = '90%',
),
align_items="start",
gap=4,
),
py=4,
overflow='auto',
)
# 오른쪽에 표시되는 사이드바
def sidebar(HomeState):
"""The sidebar displayed on the right."""
return rx.vstack(
rx.vstack(
rx.text('Route search',font_size='35px'),
rx.hstack(
rx.image(src='/startpoint.png',height='35px',width='35px'),
rx.text('origin',font_size = '20px'),
align_items='start',
width = '100%',
),
rx.input(
on_change=HomeState.set_start_location_x,
placeholder="starting point longitude",
width="100%",
border = "3px solid #000000",
),
rx.input(
on_change=HomeState.set_start_location_y,
placeholder="starting point latitude",
width="100%",
border = "3px solid #000000",
),
rx.hstack(
rx.image(src='/endpoint.png',height='35px',width='35px'),
rx.text('Destination',font_size='20px'),
align_items='start',
width='100%',
),
rx.input(
on_change=HomeState.set_end_location_x,
placeholder="end point longitude",
width="100%",
border = "3px solid #000000",
),
rx.input(
on_change=HomeState.set_end_location_y,
placeholder="end point latitude",
width="100%",
border = "3px solid #000000",
),
rx.vstack(
rx.button(
'Search',
on_click = HomeState.get_directions,
bg="#e85e1e",
color="white",
_hover={"bg": "orange.900"},
),
align_items='left',
width='100%',
),
rx.container(height='30px'),
border = '3px solid #000000',
box_Shadow = '10px 10px 5px #307849',
border_radius = '20px',
width = '90%',
),
rx.container(height='40px'),
rx.vstack(
rx.vstack(
rx.text('Route search result',font_size='30px'),
),
rx.vstack(
rx.text(HomeState.distance,font_size = '25px'),
rx.text(HomeState.path_time,font_size ='25px'),
rx.text(HomeState.taxi_fee, font_size = '20px'),
rx.text(HomeState.toll_fee, font_size = '20px'),
align_items='start',
),
border = '3px solid #000000',
border_radius = '20px',
box_Shadow = '10px 10px 5px #973dba',
width = '90%',
),
align_items="start",
gap=4,
h="100%",
width = '100%',
py=4,
overflow='auto',
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.image(src='/find1.png',height='35px',width='35px'),
rx.input(on_change=HomeState.set_map_search_input, placeholder="Search place..!"),
rx.button('search', on_click = HomeState.map_search),
rx.button('clear',on_click = HomeState.map_clear),
justify="space-between",
p=4,
border_bottom="3px solid #000000",
)
# 피드 영역
def feed(HomeState):
"""The feed."""
return rx.box(
feed_header(HomeState),
rx.container(height='10px'),
rx.vstack(
rx.html(
HomeState.time_map_iframe,
width = '100%',
),
width = '95%',
border= '3px solid #000000',
box_shadow = '10px 10px 5px #85d647'
),
rx.container(height='20px'),
rx.box(
rx.data_table(
data=HomeState.df,
font_size = '8px',
width='100%',
),
),
overflow='auto',
)
# 홈 페이지
def map():
State.check_login
return rx.vstack(
rx.grid(
tabs(),
feed(HomeState),
sidebar(HomeState),
grid_template_columns="2fr 5fr 2fr",
width='97%',
h="90vh",
gap=4,
),
rx.grid(
rx.vstack(
rx.container(height='5px'),
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
width = '80%',
_hover={"bg": "orange.400"},
),
width = '100%',
),
rx.vstack(
rx.hstack(
tab_button('/Home.png','/'),
tab_button('/profile.png','/profile'),
tab_button('/map.png','/map'),
tab_button('/chat.png','/chat'),
tab_button('/Aichat.png','/aichat'),
tab_button('/diary.png','/diary'),
tab_button('/video.png','/video'),
tab_button('/game.png','/game'),
tab_button('/music.png','/music'),
tab_button('/weather.png','/weather'),
tab_button('/setting.png','/setting'),
margin_right='5px',
border="1px solid #000000",
border_radius="full",
box_Shadow = '10px 10px 5px #3083f0',
),
width = '100%',
),
rx.vstack(
rx.container(height='5px'),
rx.button(
"Sign out",
on_click=State.logout,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
width = '80%',
),
width = '100%',
),
width='97%',
grid_template_columns="2fr 5fr 2fr",
),
)
※pages/music.py 전체 코드
# lunar.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from lunar.state.base import State
from lunar.state.home import HomeState
# 컴포넌트를 가져옵니다.
from ..components import container
color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(imagepath, href):
"""A tab switcher button."""
return rx.link(
rx.image(
src=imagepath,
height='40px',
width='40px',
),
display="inline-flex",
align_items="center",
py=3,
px=2,
href=href, # 버튼 클릭 시 이동할 경로
)
def music_chart(chart):
return rx.box(
rx.button(
rx.hstack(
rx.vstack(
rx.heading(
f"{chart['rank']}",
font_Size = '20px',
font_weight='border',
),
),
rx.container(width = '5px'),
rx.vstack(
rx.text(
f"{chart['title']}",
# style={'white-space': 'normal'},
font_weight='border',
font_Size='20px',
overflow='hidden',
),
rx.text(
f"{chart['artist']}",
font_Size='15px',
overflow='hidden',
),
align_items='start',
),
width='215px',
height='auto',
justify_content='flex-start',
overflow='hidden',
),
height='auto',
),
rx.container(height='5px'),
align='start',
padding='2px', # 테두리와 내용 사이의 여백 지정
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.vstack(
rx.container(
rx.hstack(
rx.image(
src='/moon.png',
height='60px',
width='60px',
),
rx.text(
"Lunar",
style={
"fontSize": "40px",
"fontWeight": "bolder",
"fontFamily": "Calibri, Calibri",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
rx.vstack(
rx.hstack(
rx.container(width='5px'),
rx.vstack(
rx.container(height='10px'),
rx.vstack(
rx.button('Music chart 100!',Font_size = '20px',on_click = HomeState.music_chart,bg = '#7ad65e'),
),
rx.container(height='5px'),
rx.foreach(
HomeState.music_chart_info,
music_chart,
),
width ='100%',
align_items='start',
),
),
align_items = 'start',
margin_left = '20px',
border = '3px solid #000000',
border_radius = '30px',
box_Shadow = '10px 10px 5px #d61c4e',
width = '90%',
),
align_items="start",
gap=4,
),
py=4,
overflow='auto',
)
def saved_music(music):
return rx.vstack(
rx.flex(
rx.center(
rx.button(
f'{music.music_title[:20] + "..."}',
# style={'white-space': 'normal'},
align='start',
width = '90%',
),
),
rx.spacer(),
rx.center(
rx.button(
rx.icon(tag = 'minus',size = 'sm'),
on_click = HomeState.remove_music_playlist(music.music_title, music.music_album, music.music_artist),
),
),
width = '100%',
),
rx.container(height='5px'),
width = '100%',
)
# 오른쪽에 표시되는 사이드바
def sidebar(HomeState):
"""The sidebar displayed on the right."""
return rx.vstack(
rx.heading('Music Playlist',Font_size='25px',Font_weight='border',bg = 'green.400'),
rx.vstack(
rx.cond(
HomeState.saved_music_results,
rx.foreach(
HomeState.saved_music_results,
saved_music
),
rx.vstack(
rx.button(
rx.icon(
tag="repeat",
mr=1,
),
rx.text("load",Font_size = '20px',),
on_click=HomeState.get_saved_music,
),
p=4,
),
),
),
align_items="start",
gap=4,
h="100%",
max_width = '100%',
py=4,
overflow='auto',
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.image(src='/find1.png',height='35px',width='35px'),
rx.input(on_change=HomeState.set_search_singer, placeholder="Search singer..!"),
rx.button('search', on_click = HomeState.melon_singer_crawling),
justify="space-between",
p=4,
border_bottom="3px solid #000000",
)
def singer_search(result):
return rx.box(
rx.hstack(
rx.vstack(
rx.button(
rx.flex(
rx.center(
rx.vstack(
rx.heading(
result['SONG NAME'],
font_Size = '20px',
font_weight='border',
),
rx.text(
result['ALBUM NAME'],
font_Size = '15px',
font_weight='bold',
),
align_items='start',
),
),
rx.spacer(),
rx.center(
rx.text(
result['ARTIST NAME'],
font_Size = '15px',
font_weight='bolder',
),
),
width='100%',
),
border_radius='25px',
width = '100%',
height='auto',
),
width = '95%',
border_radius = '25px',
border = '2px solid #000000',
box_shadow = '5px 5px 5px #665e5e',
),
rx.button(
rx.icon(tag = 'add',size = 'sm'),
on_click = HomeState.add_music_playlist(result['SONG NAME'], result['ALBUM NAME'],result['ARTIST NAME']),
),
width = '100%',
),
rx.container(height='20px'),
width = '100%',
)
# 피드 영역
def feed(HomeState):
"""The feed."""
return rx.box(
feed_header(HomeState),
rx.container(height='10px'),
rx.vstack(
rx.foreach(
HomeState.search_singer_result,
singer_search,
),
),
rx.container(height='20px'),
overflow='auto',
)
# 홈 페이지
def music():
State.check_login
return rx.vstack(
rx.grid(
tabs(),
feed(HomeState),
sidebar(HomeState),
grid_template_columns="2fr 5fr 2fr",
width='97%',
h="90vh",
gap=4,
),
rx.grid(
rx.vstack(
rx.container(height='5px'),
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
width = '80%',
_hover={"bg": "orange.400"},
),
width = '100%',
),
rx.vstack(
rx.hstack(
tab_button('/Home.png','/'),
tab_button('/profile.png','/profile'),
tab_button('/map.png','/map'),
tab_button('/chat.png','/chat'),
tab_button('/Aichat.png','/aichat'),
tab_button('/diary.png','/diary'),
tab_button('/video.png','/video'),
tab_button('/game.png','/game'),
tab_button('/music.png','/music'),
tab_button('/weather.png','/weather'),
tab_button('/setting.png','/setting'),
margin_right='5px',
border="1px solid #000000",
border_radius="full",
box_Shadow = '10px 10px 5px #3083f0',
),
width = '100%',
),
rx.vstack(
rx.container(height='5px'),
rx.button(
"Sign out",
on_click=State.logout,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
width = '80%',
),
width = '100%',
),
width='97%',
grid_template_columns="2fr 5fr 2fr",
),
)
※pages/video.py 전체코드
# lunar.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from lunar.state.base import State
from lunar.state.home import HomeState
# 컴포넌트를 가져옵니다.
from ..components import container
color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(imagepath, href):
"""A tab switcher button."""
return rx.link(
rx.image(
src=imagepath,
height='40px',
width='40px',
),
display="inline-flex",
align_items="center",
py=3,
px=2,
href=href, # 버튼 클릭 시 이동할 경로
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.vstack(
rx.container(
rx.hstack(
rx.image(
src='/moon.png',
height='60px',
width='60px',
),
rx.text(
"Lunar",
style={
"fontSize": "40px",
"fontWeight": "bolder",
"fontFamily": "Calibri, Calibri",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
align_items="left",
gap=4,
),
py=4,
overflow='auto',
)
def saved_video(video):
return rx.vstack(
rx.hstack(
rx.video(
url = video.video_url,
width = '150px',
height= '100px',
),
rx.button(
f'{video.video_title[:20] + "..."}',
style={'white-space': 'normal'},
align='start',
max_width='200px',
height='100px',
on_click = HomeState.popup_video(video.video_url,video.video_title),
),
rx.alert_dialog(
rx.alert_dialog_overlay(
rx.alert_dialog_content(
rx.alert_dialog_header("Video"),
rx.alert_dialog_body(
rx.video(
url = HomeState.popup_video_url,
width = '700px',
height= '500px',
),
rx.heading(
HomeState.popup_video_title,
Font_size='20px',
)
),
rx.alert_dialog_footer(
rx.button(
"Close",
on_click=HomeState.popup_video(video.video_url,video.video_title),
)
),
),
),
size = '3xl',
is_open=HomeState.show,
),
),
rx.button(
'Save cancel',
width='100%',
border_radius = '20px',
bg = '#ecf065',
_hover={'bg':'orange.400'},
on_click = HomeState.remove_video_playlist(video.video_url)
),
rx.container(height='5px'),
max_width='100%',
)
# 오른쪽에 표시되는 사이드바
def sidebar(HomeState):
"""The sidebar displayed on the right."""
return rx.vstack(
rx.heading('Saved video',Font_size='25px',Font_weight='border',bg = 'green.400'),
rx.vstack(
rx.cond(
HomeState.saved_video_results,
rx.foreach(
HomeState.saved_video_results,
saved_video
),
rx.vstack(
rx.button(
rx.icon(
tag="repeat",
mr=1,
),
rx.text("load",Font_size = '20px',),
on_click=HomeState.get_saved_video,
),
p=4,
),
),
),
align_items="start",
gap=4,
h="100%",
max_width = '100%',
py=4,
overflow='auto',
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.image(src='/find1.png',height='35px',width='35px'),
rx.input(on_change=HomeState.set_search_video, placeholder="video search..!"),
rx.button('search', on_click = HomeState.get_youtube_links),
justify="space-between",
p=4,
border_bottom="3px solid #000000",
)
def get_video(video):
result = video.split(',')
return rx.box(
rx.vstack(
rx.video(
url = result[1],
width = '100%',
height = '500px',
playing = False,
loop = True,
),
rx.hstack(
rx.heading(result[0],Font_size = '25px'),
rx.spacer(),
rx.button(
'Save',
on_click = HomeState.add_video_playlist(result[1],result[0]),
border_radius = '1em',
bg = '#95de98',
_hover={"bg": "blue.400"},
),
width='100%',
align_items='start',
),
rx.container(height='10px'),
width = '100%'
),
)
# 피드 영역
def feed(HomeState):
"""The feed."""
return rx.box(
feed_header(HomeState),
rx.foreach(
HomeState.youtube_results,
get_video,
),
overflow='auto',
)
# 홈 페이지
def video():
State.check_login
return rx.vstack(
rx.grid(
tabs(),
feed(HomeState),
sidebar(HomeState),
grid_template_columns="2fr 5fr 2fr",
width='97%',
h="90vh",
gap=4,
),
rx.grid(
rx.vstack(
rx.container(height='5px'),
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
width = '80%',
_hover={"bg": "orange.400"},
),
width = '100%',
),
rx.vstack(
rx.hstack(
tab_button('/Home.png','/'),
tab_button('/profile.png','/profile'),
tab_button('/map.png','/map'),
tab_button('/chat.png','/chat'),
tab_button('/Aichat.png','/aichat'),
tab_button('/diary.png','/diary'),
tab_button('/video.png','/video'),
tab_button('/game.png','/game'),
tab_button('/music.png','/music'),
tab_button('/weather.png','/weather'),
tab_button('/setting.png','/setting'),
margin_right='5px',
border="1px solid #000000",
border_radius="full",
box_Shadow = '10px 10px 5px #3083f0',
),
width = '100%',
),
rx.vstack(
rx.container(height='5px'),
rx.button(
"Sign out",
on_click=State.logout,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
width = '80%',
),
width = '100%',
),
width='97%',
grid_template_columns="2fr 5fr 2fr",
),
)
※pages/weather.py 전체코드
# lunar.state.home 모듈에서 필요한 State 및 HomeState를 가져옵니다.
import reflex as rx
from lunar.state.base import State
from lunar.state.home import HomeState
from PIL import Image
# 컴포넌트를 가져옵니다.
from ..components import container
color = "rgb(107,99,246)"
# 탭 버튼을 생성하는 함수
def tab_button(imagepath, href):
"""A tab switcher button."""
return rx.link(
rx.image(
src=imagepath,
height='40px',
width='40px',
),
display="inline-flex",
align_items="center",
py=3,
px=2,
href=href, # 버튼 클릭 시 이동할 경로
)
def message(message):
return rx.box(
rx.button(
rx.vstack(
rx.box(
rx.text(
message['date'],
style={'white-space': 'normal'},
font_Size = '15px',
font_weight= 'bolder',
),
bg = '#dec445',
),
rx.text(),
rx.text(
message['area'],
style={'white-space': 'normal'},
font_Size = '13px',
font_weight='bold',
),
rx.divider(variant="dashed", border_color="black"),
rx.text(
message['text'],
style={'white-space': 'normal'},
font_size = '15px',
),
width = '100%',
),
height='auto',
width='90%',
),
rx.container(height='5px'),
align='start',
padding='5px', # 테두리와 내용 사이의 여백 지정
)
# 왼쪽에 표시되는 탭 스위처
def tabs():
"""The tab switcher displayed on the left."""
return rx.box(
rx.vstack(
rx.container(
rx.hstack(
rx.image(
src='/moon.png',
height='60px',
width='60px',
),
rx.text(
"Lunar",
style={
"fontSize": "40px",
"fontWeight": "bolder",
"fontFamily": "Calibri, Calibri",
"background": "-webkit-linear-gradient(-45deg, #e04a3f, #4e8be6)",
"-webkit-background-clip": "text",
"color": "transparent",
},
center_content=True,
), # 앱 이름
),
),
rx.vstack(
rx.hstack(
rx.container(width='5px'),
rx.vstack(
rx.container(height='10px'),
rx.vstack(
rx.button('Disaster',Font_size = '20px',on_click = HomeState.climate_message,bg = '#eb7373'),
),
rx.container(height='5px'),
rx.foreach(
HomeState.weather_message_result,
message,
),
rx.container(height='4px'),
align_items='start',
width ='100%',
),
),
align_items = 'start',
margin_left = '20px',
border = '3px solid #000000',
border_radius = '30px',
box_Shadow = '10px 10px 5px #d61c4e',
width = '90%',
),
align_items="start",
gap=4,
),
py=4,
overflow='auto',
)
# 오른쪽에 표시되는 사이드바
def sidebar(HomeState):
"""The sidebar displayed on the right."""
return rx.vstack(
rx.container(height='10px'),
rx.heading(
'Weather sites',
font_Size = '30px',
font_weight='bolder',
bg = 'blue.400',
),
rx.hstack(
rx.container(width='1px'),
rx.vstack(
rx.link(
rx.button("대한민국 기상청"),
href="https://www.weather.go.kr/w/index.do",
color="rgb(107,99,246)",
button=True,
),
rx.link(
rx.button("일본 기상청"),
href="https://www.data.jma.go.jp/multi/index.html?lang=kr",
color="rgb(107,99,246)",
button=True,
),
rx.link(
rx.button("미국 기상청"),
href="https://worldweather.wmo.int/kr/country.html?countryCode=93",
color="rgb(107,99,246)",
button=True,
),
rx.link(
rx.button("Windy"),
href="https://www.windy.com/?36.342,127.389,5",
color="rgb(107,99,246)",
button=True,
),
rx.link(
rx.button("AccuWeather"),
href="https://www.accuweather.com/",
color="rgb(107,99,246)",
button=True,
),
align_items='start',
width ='100%',
),
border = '2px solid #000000',
border_radius = '30px',
box_Shadow = '10px 10px 5px #307849',
width='80%',
),
align_items="start",
gap=4,
height='100%',
width = '100%',
py=4,
overflow='auto',
)
# 피드의 헤더
def feed_header(HomeState):
"""The header of the feed."""
return rx.hstack(
rx.image(src='/find1.png',height='35px',width='35px'),
rx.input(on_change=HomeState.set_weather_search, placeholder="Search place..!"),
rx.button('search', on_click = HomeState.climate_websearch),
justify="space-between",
p=4,
border_bottom="3px solid #000000",
)
# 피드 영역
def feed(HomeState):
"""The feed."""
return rx.box(
feed_header(HomeState),
rx.container(height='10px'),
rx.vstack(
rx.cond(
HomeState.weather_search_show,
rx.vstack(
rx.hstack(
rx.heading(
HomeState.weather_search,
as_='mark',
font_Size = '50px',
),
margin_left = '5%',
),
rx.hstack(
rx.vstack(
rx.text(
f"현재 기온 : {HomeState.status_temperature}'C",
font_Size = '25px',
font_weight='bold',
),
rx.text(
f'현재 날씨 : {HomeState.status_climate}',
font_Size = '25px',
font_weight='bolder',
),
rx.text(
f"체감 온도 : {HomeState.status_feel_temperature}'C",
font_Size = '25px',
font_weight='bolder',
),
rx.text(
f"최저 온도 : {HomeState.today_min_temperature}'C",
font_Size = '25px',
font_weight='bolder',
color = 'blue',
),
rx.text(
f"최고 온도 : {HomeState.today_max_temperature}'C",
font_Size = '25px',
font_weight='bolder',
color = 'red',
),
rx.text(
f'현재 습도 : {HomeState.status_humidity}%',
font_Size = '25px',
font_weight='bolder',
),
rx.text(
f'현재 기압 : {HomeState.status_atmospheric_pressure}hpa',
font_Size = '25px',
font_weight='bolder',
),
rx.text(
f'풍속 : {HomeState.status_wind_speed}m/s',
font_Size = '25px',
font_weight='bolder',
),
align_items='start',
margin_left = '5%',
),
rx.container(width='5%'),
rx.vstack(
rx.image(
src = HomeState.image,
height='400px',
width = 'auto',
)
)
),
width = '90%',
margin_left = '5%',
align_items='start',
border = '2px solid #000000',
border_radius = '30px',
box_Shadow = '10px 10px 10px #575050',
),
rx.vstack(
rx.heading(
'Enter the area where you want to search for weather.',
font_Size = '40px',
font_weight='border',
),
align_items='start',
width = '100%',
)
)
),
rx.container(height='20px'),
overflow='auto',
)
# 홈 페이지
def weather():
State.check_login
return rx.vstack(
rx.grid(
tabs(),
feed(HomeState),
sidebar(HomeState),
grid_template_columns="2fr 5fr 2fr",
width='97%',
h="90vh",
gap=4,
),
rx.grid(
rx.vstack(
rx.container(height='5px'),
rx.button(
rx.icon(tag="moon"),
on_click=rx.toggle_color_mode,
width = '80%',
_hover={"bg": "orange.400"},
),
width = '100%',
),
rx.vstack(
rx.hstack(
tab_button('/Home.png','/'),
tab_button('/profile.png','/profile'),
tab_button('/map.png','/map'),
tab_button('/chat.png','/chat'),
tab_button('/Aichat.png','/aichat'),
tab_button('/diary.png','/diary'),
tab_button('/video.png','/video'),
tab_button('/game.png','/game'),
tab_button('/music.png','/music'),
tab_button('/weather.png','/weather'),
tab_button('/setting.png','/setting'),
margin_right='5px',
border="1px solid #000000",
border_radius="full",
box_Shadow = '10px 10px 5px #3083f0',
),
width = '100%',
),
rx.vstack(
rx.container(height='5px'),
rx.button(
"Sign out",
on_click=State.logout,
bg="#212963",
color="white",
_hover={"bg": "blue.600"},
width = '80%',
),
width = '100%',
),
width='97%',
grid_template_columns="2fr 5fr 2fr",
),
)
728x90
'Projects' 카테고리의 다른 글
Lunar-(16)ai chat(구글 Gemini api 키 이용) (1) | 2024.01.21 |
---|---|
Lunar-(15)전체코드 중간정리2(함수 부분) (0) | 2024.01.08 |
Lunar-(13)날씨(실시간 재난문자, 전세계 지역 현재 날씨 검색, 기상관련 사이트 링크) (1) | 2024.01.08 |
Lunar-(12)멜론 차트 top100 가져오기, 가수 크롤링 검색결과 (1) | 2024.01.03 |
Lunar-(11)현재 수정중인 작업, 기능추가예정작업 (0) | 2024.01.01 |