react-icons/fi#FiClock TypeScript Examples
The following examples show how to use
react-icons/fi#FiClock.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Message.tsx From meshtastic-web with GNU General Public License v3.0 | 5 votes |
Message = ({
lastMsgSameUser,
message,
ack,
rxTime,
sender,
}: MessageProps): JSX.Element => {
return (
<div className="group mb-3 hover:bg-gray-200 dark:hover:bg-tertiaryDark">
{lastMsgSameUser ? (
<div
className={`mx-6 -mt-3 flex justify-between ${
lastMsgSameUser ? '' : 'py-1'
}`}
>
<div className="flex gap-2">
<Tooltip content={rxTime.toString()}>
<div className="my-auto ml-auto w-8 pt-1 text-xs text-transparent group-hover:text-gray-500 dark:group-hover:text-gray-400">
{rxTime
.toLocaleTimeString(undefined, {
hour: '2-digit',
minute: '2-digit',
})
.replace('AM', '')
.replace('PM', '')}
</div>
</Tooltip>
<div
className={`my-auto dark:text-gray-300 ${
ack ? '' : 'animate-pulse dark:text-gray-500'
}`}
>
{message}
</div>
</div>
<Tooltip content="Response time">
<div className="flex gap-1 pt-1 text-xs text-transparent group-hover:text-gray-500 dark:group-hover:text-gray-400">
<FiClock className="mt-0.5" />
<div>25s</div>
</div>
</Tooltip>
</div>
) : (
<div className="mx-6 flex gap-2">
<div className="my-auto w-8">
<Hashicon value={(sender?.num ?? 0).toString()} size={32} />
</div>
<div>
<div className="flex gap-2">
<div className="cursor-default text-sm font-semibold hover:underline dark:text-white">
{sender?.user?.longName ?? 'UNK'}
</div>
<div className="my-auto text-xs dark:text-gray-400">
{rxTime.toLocaleTimeString(undefined, {
hour: '2-digit',
minute: '2-digit',
})}
</div>
</div>
<div
className={`dark:text-gray-300 ${
ack ? '' : 'animate-pulse dark:text-gray-400'
}`}
>
{message}
</div>
</div>
</div>
)}
</div>
);
}
Example #2
Source File: index.tsx From nlw-03-omnistack with MIT License | 5 votes |
export default function Orphanage() {
return (
<div id="page-orphanage">
<Sidebar />
<main>
<div className="orphanage-details">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
<div className="images">
<button className="active" type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
</div>
<div className="orphanage-details-content">
<h1>Lar das meninas</h1>
<p>Presta assistência a crianças de 06 a 15 anos que se encontre em situação de risco e/ou vulnerabilidade social.</p>
<div className="map-container">
<Map
interactive={false}
center={[-27.2092052,-49.6401092]}
zoom={16}
style={{ width: '100%', height: 280 }}
>
<Marker interactive={false} icon={happyMapIcon} position={[-27.2092052,-49.6401092]} />
</Map>
<footer>
<a href="">Ver rotas no Google Maps</a>
</footer>
</div>
<hr />
<h2>Instruções para visita</h2>
<p>Venha como se sentir mais à vontade e traga muito amor para dar.</p>
<div className="open-details">
<div className="hour">
<FiClock size={32} color="#15B6D6" />
Segunda à Sexta <br />
8h às 18h
</div>
<div className="open-on-weekends">
<FiInfo size={32} color="#39CC83" />
Atendemos <br />
fim de semana
</div>
</div>
<PrimaryButton type="button">
<FaWhatsapp size={20} color="#FFF" />
Entrar em contato
</PrimaryButton>
</div>
</div>
</main>
</div>
);
}
Example #3
Source File: CreateOrphanage.tsx From NLW-3.0 with MIT License | 4 votes |
export default function Orphanage() {
const params = useParams<OrphanageParams>();
const [orphanage, setOrphanage] = useState<Orphanage>();
const [activeImageIndex, setActiveImageIndex] = useState(0);
useEffect(() => {
api.get(`orphanages/${params.id}`).then(response => {
setOrphanage(response.data);
});
}, [params.id]);
if (!orphanage) {
return <p>Carregando...</p>
}
return (
<div id="page-orphanage">
<Sidebar />
<main>
<div className="orphanage-details">
<img src={orphanage.images[activeImageIndex].url} alt={orphanage.name} />
<div className="images">
{orphanage.images.map((image, index) => (
<button
key={image.id}
className={activeImageIndex === index ? 'active' : ''}
type="button"
onClick={() => {
setActiveImageIndex(index);
}}
>
<img src={image.url} alt={orphanage.name} />
</button>
))}
</div>
<div className="orphanage-details-content">
<h1>{orphanage.name}</h1>
<p>{orphanage.about}</p>
<div className="map-container">
<Map
center={[orphanage.latitude, orphanage.longitude]}
zoom={16}
style={{ width: '100%', height: 280 }}
dragging={false}
touchZoom={false}
zoomControl={false}
scrollWheelZoom={false}
doubleClickZoom={false}
>
<TileLayer
url={`https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/256/{z}/{x}/{y}@2x?access_token=${process.env.REACT_APP_MAPBOX_TOKEN}`}
/>
<Marker interactive={false} icon={mapIcon} position={[orphanage.latitude, orphanage.longitude]} />
</Map>
<footer>
<a target="_blank" rel="noopener noreferrer" href={`https://www.google.com/maps/dir/?api=1&destination=${orphanage.latitude},${orphanage.longitude}`}>Ver rotas no Google Maps</a>
</footer>
</div>
<hr />
<h2>Instruções para visita</h2>
<p>{orphanage.instructions}</p>
<div className="open-details">
<div className="hour">
<FiClock size={32} color="#15B6D6" />
Segunda à Sexta <br />
{orphanage.opening_hours}
</div>
{orphanage.open_on_weekends ? (
<div className="open-on-weekends">
<FiInfo size={32} color="#39CC83" />
Atendemos <br />
fim de semana
</div>
) : (
<div className="open-on-weekends dont-open">
<FiInfo size={32} color="#FF6690" />
Não Atendemos <br />
fim de semana
</div>
)}
</div>
</div>
</div>
</main>
</div>
);
}
Example #4
Source File: Orphanage.tsx From NLW-3.0 with MIT License | 4 votes |
export default function Orphanage() {
const { goBack } = useHistory();
return (
<div id="page-orphanage">
<aside>
<img src={mapMarkerImg} alt="Happy" />
<footer>
<button type="button" onClick={goBack}>
<FiArrowLeft size={24} color="#FFF" />
</button>
</footer>
</aside>
<main>
<div className="orphanage-details">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
<div className="images">
<button className="active" type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
<button type="button">
<img src="https://www.gcd.com.br/wp-content/uploads/2020/08/safe_image.jpg" alt="Lar das meninas" />
</button>
</div>
<div className="orphanage-details-content">
<h1>Lar das meninas</h1>
<p>Presta assistência a crianças de 06 a 15 anos que se encontre em situação de risco e/ou vulnerabilidade social.</p>
<div className="map-container">
<Map
center={[-27.2092052, -49.6401092]}
zoom={16}
style={{ width: '100%', height: 280 }}
dragging={false}
touchZoom={false}
zoomControl={false}
scrollWheelZoom={false}
doubleClickZoom={false}
>
<TileLayer
url={`https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/256/{z}/{x}/{y}@2x?access_token=${process.env.REACT_APP_MAPBOX_TOKEN}`}
/>
<Marker interactive={false} icon={happyMapIcon} position={[-27.2092052, -49.6401092]} />
</Map>
<footer>
<a href="">Ver rotas no Google Maps</a>
</footer>
</div>
<hr />
<h2>Instruções para visita</h2>
<p>Venha como se sentir mais à vontade e traga muito amor para dar.</p>
<div className="open-details">
<div className="hour">
<FiClock size={32} color="#15B6D6" />
Segunda à Sexta <br />
8h às 18h
</div>
<div className="open-on-weekends">
<FiInfo size={32} color="#39CC83" />
Atendemos <br />
fim de semana
</div>
</div>
<button type="button" className="contact-button">
<FaWhatsapp size={20} color="#FFF" />
Entrar em contato
</button>
</div>
</div>
</main>
</div>
);
}
Example #5
Source File: index.tsx From gobarber-web with MIT License | 4 votes |
Dashboard: React.FC = () => {
const { signOut, user } = useAuth();
const [selectedDate, setSelectedDate] = useState(new Date());
const [currentMonth, setCurrentMonth] = useState(new Date());
const [monthAvailability, setMonthAvailability] = useState<
MonthAvailabilityItem[]
>([]);
const [appointments, setAppointments] = useState<Appointment[]>([]);
const handleDateChange = useCallback((day: Date, modifiers: DayModifiers) => {
if (modifiers.available && !modifiers.disabled) {
setSelectedDate(day);
}
}, []);
const handleMonthChange = useCallback((month: Date) => {
setCurrentMonth(month);
}, []);
useEffect(() => {
api
.get(`/providers/${user.id}/month-availability`, {
params: {
year: currentMonth.getFullYear(),
month: currentMonth.getMonth() + 1,
},
})
.then(response => setMonthAvailability(response.data));
}, [currentMonth, user.id]);
useEffect(() => {
api
.get<Appointment[]>('/appointments/me', {
params: {
year: selectedDate.getFullYear(),
month: selectedDate.getMonth() + 1,
day: selectedDate.getDate(),
},
})
.then(response => {
const appointmentsFormatted = response.data.map(appointment => ({
...appointment,
hourFormatted: format(parseISO(appointment.date), 'HH:mm'),
}));
setAppointments(appointmentsFormatted);
});
}, [selectedDate]);
const disableDays = useMemo(() => {
return monthAvailability
.filter(monthDay => monthDay.available === false)
.map(monthDay => {
const year = currentMonth.getFullYear();
const month = currentMonth.getMonth();
return new Date(year, month, monthDay.day);
});
}, [currentMonth, monthAvailability]);
const selectedDateAsText = useMemo(() => {
return format(selectedDate, "'Dia' dd 'de' MMMM", { locale: ptBR });
}, [selectedDate]);
const selectedWeekDay = useMemo(() => {
return format(selectedDate, 'cccc', { locale: ptBR });
}, [selectedDate]);
const morningAppointments = useMemo(() => {
return appointments.filter(appointment => {
return parseISO(appointment.date).getHours() < 12;
});
}, [appointments]);
const afternoonAppointments = useMemo(() => {
return appointments.filter(appointment => {
return parseISO(appointment.date).getHours() >= 12;
});
}, [appointments]);
const nextAppointment = useMemo(() => {
return appointments.find(appointment =>
isAfter(parseISO(appointment.date), new Date()),
);
}, [appointments]);
return (
<S.Container>
<S.Header>
<S.HeaderContent>
<img src={logoImg} alt="Logo GoBarber" />
<S.HeaderProfile>
<img
src={
user.avatar_url ||
'https://api.adorable.io/avatars/56/[email protected]'
}
alt={user.name}
/>
<div>
<span>Bem-vindo,</span>
<Link to="/profile">
<strong>{user.name}</strong>
</Link>
</div>
</S.HeaderProfile>
<button type="button" onClick={signOut}>
<FiPower size={20} />
</button>
</S.HeaderContent>
</S.Header>
<S.Content>
<S.Schedule>
<h1>Horários agendados</h1>
<p>
{isToday(selectedDate) && <span>Hoje</span>}
<span>{selectedDateAsText}</span>
<span>{`${selectedWeekDay}-feira`}</span>
</p>
{isToday(selectedDate) && nextAppointment && (
<S.NextAppointment>
<strong>Atendimento a seguir</strong>
<div>
<img
src={
nextAppointment.user.avatar_url ||
'https://api.adorable.io/avatars/80/[email protected]'
}
alt={nextAppointment.user.name}
/>
<strong>{nextAppointment.user.name}</strong>
<span>
<FiClock size={24} />
{nextAppointment.hourFormatted}
</span>
</div>
</S.NextAppointment>
)}
<S.Section>
<strong>Manhã</strong>
{morningAppointments.length === 0 && (
<p>Nenhum agendamento neste período</p>
)}
{morningAppointments.map(appointment => (
<S.Appointment key={appointment.id}>
<span>
<FiClock size={20} />
{appointment.hourFormatted}
</span>
<div>
<img
src={
appointment.user.avatar_url ||
'https://api.adorable.io/avatars/56/[email protected]'
}
alt={appointment.user.name}
/>
<strong>{appointment.user.name}</strong>
</div>
</S.Appointment>
))}
</S.Section>
<S.Section>
<strong>Tarde</strong>
{afternoonAppointments.length === 0 && (
<p>Nenhum agendamento neste período</p>
)}
{afternoonAppointments.map(appointment => (
<S.Appointment key={appointment.id}>
<span>
<FiClock size={20} />
{appointment.hourFormatted}
</span>
<div>
<img
src={
appointment.user.avatar_url ||
'https://api.adorable.io/avatars/56/[email protected]'
}
alt={appointment.user.name}
/>
<strong>{appointment.user.name}</strong>
</div>
</S.Appointment>
))}
</S.Section>
</S.Schedule>
<S.Calendar>
<DayPicker
weekdaysShort={['D', 'S', 'T', 'Q', 'Q', 'S', 'S']}
fromMonth={new Date()}
disabledDays={[{ daysOfWeek: [0, 6] }, ...disableDays]}
modifiers={{
available: { daysOfWeek: [1, 2, 3, 4, 5] },
}}
onMonthChange={handleMonthChange}
selectedDays={selectedDate}
onDayClick={handleDateChange}
months={[
'Janeiro',
'Fevereiro',
'Março',
'Abril',
'Maio',
'Junho',
'Julho',
'Agosto',
'Setembro',
'Outubro',
'Novembro',
'Dezembro',
]}
/>
</S.Calendar>
</S.Content>
</S.Container>
);
}
Example #6
Source File: Orphanage.tsx From happy with MIT License | 4 votes |
export default function Orphanage() {
const params = useParams<OrphanageParams>();
const [orphanage, setOrphanage] = useState<Orphanage>();
const [activeImageIndex, setActiveImageIndex] = useState(0);
useEffect(() => {
api.get(`orphanages/${params.id}`).then(response => {
setOrphanage(response.data);
});
}, [params.id]);
if (!orphanage) {
return <p>Carregando...</p>
}
return (
<div id="page-orphanage">
<Sidebar />
<main>
<div className="orphanage-details">
<img src={orphanage.images[activeImageIndex].url} alt={orphanage.name} />
<div className="images">
{orphanage.images.map((image, index) => (
<button
key={image.id}
className={activeImageIndex === index ? 'active' : ''}
type="button"
onClick={() => {
setActiveImageIndex(index);
}}
>
<img src={image.url} alt={orphanage.name} />
</button>
))}
</div>
<div className="orphanage-details-content">
<h1>{orphanage.name}</h1>
<p>{orphanage.about}</p>
<div className="map-container">
<Map
center={[orphanage.latitude, orphanage.longitude]}
zoom={16}
style={{ width: '100%', height: 280 }}
dragging={false}
touchZoom={false}
zoomControl={false}
scrollWheelZoom={false}
doubleClickZoom={false}
>
<TileLayer
url={`https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/256/{z}/{x}/{y}@2x?access_token=${process.env.REACT_APP_MAPBOX_TOKEN}`}
/>
<Marker interactive={false} icon={mapIcon} position={[orphanage.latitude, orphanage.longitude]} />
</Map>
<footer>
<a target="_blank" rel="noopener noreferrer" href={`https://www.google.com/maps/dir/?api=1&destination=${orphanage.latitude},${orphanage.longitude}`}>Ver rotas no Google Maps</a>
</footer>
</div>
<hr />
<h2>Instruções para visita</h2>
<p>{orphanage.instructions}</p>
<div className="open-details">
<div className="hour">
<FiClock size={32} color="#15B6D6" />
Segunda à Sexta <br />
{orphanage.opening_hours}
</div>
{ orphanage.open_on_weekends ? (
<div className="open-on-weekends">
<FiInfo size={32} color="#39CC83" />
Atendemos <br />
fim de semana
</div>
) : (
<div className="open-on-weekends dont-open">
<FiInfo size={32} color="#FF6690" />
Não Atendemos <br />
fim de semana
</div>
) }
</div>
{/* <button type="button" className="contact-button">
<FaWhatsapp size={20} color="#FFF" />
Entrar em contato
</button> */}
</div>
</div>
</main>
</div>
);
}
Example #7
Source File: index.tsx From space-traveling with MIT License | 4 votes |
export default function Home({
postsPagination,
preview,
}: HomeProps): ReactElement {
function getReadTime(item: Post): number {
const totalWords = item.data.content.reduce((total, contentItem) => {
total += contentItem.heading.split(' ').length;
const words = contentItem.body.map(i => i.text.split(' ').length);
words.map(word => (total += word));
return total;
}, 0);
return Math.ceil(totalWords / 200);
}
const formattedPost = postsPagination.results.map(post => {
const readTime = getReadTime(post);
return {
...post,
data: {
...post.data,
readTime,
},
first_publication_date: format(
new Date(post.first_publication_date),
'dd MMM yyyy',
{
locale: ptBR,
}
),
};
});
const [posts, setPosts] = useState<Post[]>(formattedPost);
const [nextPage, setNextPage] = useState(postsPagination.next_page);
const [currentPage, setCurrentPage] = useState(1);
async function handleNextPage(): Promise<void> {
if (currentPage !== 1 && nextPage === null) {
return;
}
const postsResults = await fetch(`${nextPage}`).then(response =>
response.json()
);
setNextPage(postsResults.next_page);
setCurrentPage(postsResults.page);
const newPosts = postsResults.results.map((post: Post) => {
const readTime = getReadTime(post);
return {
uid: post.uid,
first_publication_date: format(
new Date(post.first_publication_date),
'dd MMM yyyy',
{
locale: ptBR,
}
),
data: {
title: post.data.title,
subtitle: post.data.subtitle,
author: post.data.author,
readTime,
},
};
});
setPosts([...posts, ...newPosts]);
}
return (
<>
<Head>
<title>Home | spacetraveling</title>
</Head>
<main className={commonStyles.container}>
<Header />
<div className={styles.posts}>
{posts.map(post => (
<Link href={`/post/${post.uid}`} key={post.uid}>
<a className={styles.post}>
<strong>{post.data.title}</strong>
<p>{post.data.subtitle}</p>
<ul>
<li>
<FiCalendar />
{post.first_publication_date}
</li>
<li>
<FiUser />
{post.data.author}
</li>
<li>
<FiClock />
{`${post.data.readTime} min`}
</li>
</ul>
</a>
</Link>
))}
{nextPage && (
<button type="button" onClick={handleNextPage}>
Carregar mais posts
</button>
)}
</div>
{preview && (
<aside>
<Link href="/api/exit-preview">
<a className={commonStyles.preview}>Sair do modo Preview</a>
</Link>
</aside>
)}
</main>
</>
);
}
Example #8
Source File: [slug].tsx From space-traveling with MIT License | 4 votes |
export default function Post({
post,
navigation,
preview,
}: PostProps): JSX.Element {
const router = useRouter();
if (router.isFallback) {
return <h1>Carregando...</h1>;
}
const totalWords = post.data.content.reduce((total, contentItem) => {
total += contentItem.heading.split(' ').length;
const words = contentItem.body.map(item => item.text.split(' ').length);
words.map(word => (total += word));
return total;
}, 0);
const readTime = Math.ceil(totalWords / 200);
const formatedDate = format(
new Date(post.first_publication_date),
'dd MMM yyyy',
{
locale: ptBR,
}
);
const isPostEdited =
post.first_publication_date !== post.last_publication_date;
let editionDate;
if (isPostEdited) {
editionDate = format(
new Date(post.last_publication_date),
"'* editado em' dd MMM yyyy', às' H':'m",
{
locale: ptBR,
}
);
}
return (
<>
<Head>
<title>SpaceTraveling | {post.data.title}</title>
</Head>
<Header />
<img src={post.data.banner.url} alt="imagem" className={styles.banner} />
<main className={commonStyles.container}>
<div className={styles.post}>
<div className={styles.postTop}>
<h1>{post.data.title}</h1>
<ul>
<li>
<FiCalendar />
{formatedDate}
</li>
<li>
<FiUser />
{post.data.author}
</li>
<li>
<FiClock />
{`${readTime} min`}
</li>
</ul>
<span>{isPostEdited && editionDate}</span>
</div>
{post.data.content.map(content => {
return (
<article key={content.heading}>
<h2>{content.heading}</h2>
<div
className={styles.postContent}
dangerouslySetInnerHTML={{
__html: RichText.asHtml(content.body),
}}
/>
</article>
);
})}
</div>
<section className={`${styles.navigation} ${commonStyles.container}`}>
{navigation?.prevPost.length > 0 && (
<div>
<h3>{navigation.prevPost[0].data.title}</h3>
<Link href={`/post/${navigation.prevPost[0].uid}`}>
<a>Post anterior</a>
</Link>
</div>
)}
{navigation?.nextPost.length > 0 && (
<div>
<h3>{navigation.nextPost[0].data.title}</h3>
<Link href={`/post/${navigation.nextPost[0].uid}`}>
<a>Próximo post</a>
</Link>
</div>
)}
</section>
<Comments />
{preview && (
<aside>
<Link href="/api/exit-preview">
<a className={commonStyles.preview}>Sair do modo Preview</a>
</Link>
</aside>
)}
</main>
</>
);
}
Example #9
Source File: index.tsx From NextLevelWeek with MIT License | 4 votes |
Orphanage: React.FC = () => {
const params = useParams<IOrphanageParams>();
const [orphanage, setOrphanage] = useState<IOpharnage>();
const [activeImageIndex, setActiveImageIndex] = useState(0);
useEffect(() => {
api.get(`/orphanages/${params.id}`).then(res => {
// console.log(res.data);
setOrphanage(res.data);
});
}, [params.id]);
if (!orphanage) {
return <p>Carregando..</p>;
// Fazer em Shimmer
}
return (
<Container>
<Sidebar />
<Content>
<DetailsContainer>
<img src={orphanage.images[activeImageIndex].url} alt={orphanage.name} />
<ImagesContainer>
{orphanage.images.map((image, index) => {
return (
<ButtonImage
key={image.id}
type="button"
active={activeImageIndex === index}
onClick={() => {
setActiveImageIndex(index);
}}
>
<img src={image.url} alt={orphanage.name} />
</ButtonImage>
);
})}
</ImagesContainer>
<OrphanageDetails>
<h1>{orphanage.name}</h1>
<p>{orphanage.about}</p>
<MapContainer>
<Map
center={[orphanage.latitude, orphanage.longitude]}
zoom={16}
style={{ width: '100%', height: 280 }}
dragging={false}
touchZoom={false}
zoomControl={false}
scrollWheelZoom={false}
doubleClickZoom={false}
>
<TileLayer
url={`https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/256/{z}/{x}/{y}@2x?access_token=${process.env.REACT_APP_MAPBOX_TOKEN}`}
/>
<Marker interactive={false} icon={happyMapIcon} position={[orphanage.latitude, orphanage.longitude]} />
</Map>
<footer>
<a target="_blank" rel="noopener noreferrer" href={`https://www.google.com/maps/dir/?api=1&destination=${orphanage.latitude},${orphanage.longitude}`}>Ver rotas no Google Maps</a>
</footer>
</MapContainer>
<hr />
<h2>Instruções para visita</h2>
<p>{orphanage.instructions}</p>
<OpenDetails>
<OpeningHoursContainer>
<FiClock size={32} color="#15B6D6" />
Segunda à Sexta <br />
{orphanage.opening_hours}
</OpeningHoursContainer>
{orphanage.open_on_weekends ? (
<OpenWeekends open={orphanage.open_on_weekends}>
<FiInfo size={32} />
Atendemos <br />
fim de semanada
</OpenWeekends>
) : (
<OpenWeekends open={orphanage.open_on_weekends}>
<FiInfo size={32} />
Não atendemos <br />
no fim de semanada
</OpenWeekends>
)
}
<button type="button">
<FaWhatsapp size={20} color="#FFF" />
Entrar em contato
</button>
</OpenDetails>
</OrphanageDetails>
</DetailsContainer>
</Content>
</Container>
);
}
Example #10
Source File: index.tsx From gobarber-project with MIT License | 4 votes |
Dashboard: React.FC = () => {
const { user, signOut } = useAuth();
const [selectedDate, setSelectedDate] = useState(new Date());
const [currentMonth, setCurrentMonth] = useState(new Date());
const [monthAvailability, setMonthAvailability] = useState<
MonthAvailabilityItem[]
>([]);
const [appointments, setAppointments] = useState<Appointments[]>([]);
const handleDateChange = useCallback((day: Date, modifiers: DayModifiers) => {
if (modifiers.available && !modifiers.disabled) {
setSelectedDate(day);
}
}, []);
const handleMonthChange = useCallback((month: Date) => {
setCurrentMonth(month);
}, []);
useEffect(() => {
api
.get(`/providers/${user.id}/month-availability`, {
params: {
year: currentMonth.getFullYear(),
month: currentMonth.getMonth() + 1,
},
})
.then(response => {
setMonthAvailability(response.data);
});
}, [currentMonth, user.id]);
useEffect(() => {
api
.get<Appointments[]>('/appointments/me', {
params: {
year: selectedDate.getFullYear(),
month: selectedDate.getMonth() + 1,
day: selectedDate.getDate(),
},
})
.then(response => {
const appointmentsFormatted = response.data.map(appointment => {
return {
...appointment,
hourFormatted: format(parseISO(appointment.date), 'HH:mm'),
};
});
setAppointments(appointmentsFormatted);
});
}, [selectedDate]);
const disabledDays = useMemo(() => {
const dates = monthAvailability
.filter(monthDay => monthDay.available === false)
.map(monthDay => {
const year = currentMonth.getFullYear();
const month = currentMonth.getMonth();
return new Date(year, month, monthDay.day);
});
return dates;
}, [currentMonth, monthAvailability]);
const selectedDateAsText = useMemo(() => {
return format(selectedDate, "'Dia' dd 'de' MMMM", {
locale: ptBR,
});
}, [selectedDate]);
const selectedWeekDay = useMemo(() => {
return format(selectedDate, 'cccc', {
locale: ptBR,
});
}, [selectedDate]);
const morningAppointments = useMemo(() => {
return appointments.filter(appointment => {
return parseISO(appointment.date).getHours() < 12;
});
}, [appointments]);
const afternoonAppointments = useMemo(() => {
return appointments.filter(appointment => {
return parseISO(appointment.date).getHours() >= 12;
});
}, [appointments]);
const nextAppointment = useMemo(() => {
return appointments.find(appointment =>
isAfter(parseISO(appointment.date), new Date()),
);
}, [appointments]);
return (
<Container>
<Header>
<HeaderContent>
<img src={logo} alt="GoBarber" />
<Profile>
<img src={user.avatar_url} alt={user.name} />
<div>
<span>Bem-vindo,</span>
<Link to="/profile">
<strong>{user.name}</strong>
</Link>
</div>
</Profile>
<button type="button" onClick={signOut}>
<FiPower />
</button>
</HeaderContent>
</Header>
<Content>
<Schedule>
<h1>Horários agendados</h1>
<p>
{isToday(selectedDate) && <span>Hoje</span>}
<span>{selectedDateAsText}</span>
<span>{selectedWeekDay}</span>
</p>
{isToday(selectedDate) && nextAppointment && (
<NextAppointment>
<strong>Agendamento a seguir</strong>
<div>
<img
src={nextAppointment.user.avatar_url}
alt={nextAppointment.user.name}
/>
<strong>{nextAppointment.user.name}</strong>
<span>
<FiClock />
{nextAppointment.hourFormatted}
</span>
</div>
</NextAppointment>
)}
<Section>
<strong>Manhã</strong>
{morningAppointments.length === 0 && (
<p>Nenhum agendamento no horário da manhã</p>
)}
{morningAppointments.map(appointment => (
<Appointment key={appointment.id}>
<span>
<FiClock />
{appointment.hourFormatted}
</span>
<div>
<img
src={appointment.user.avatar_url}
alt={appointment.user.name}
/>
<strong>{appointment.user.name}</strong>
</div>
</Appointment>
))}
</Section>
<Section>
<strong>Tarde</strong>
{afternoonAppointments.length === 0 && (
<p>Nenhum agendamento no horário da tarde</p>
)}
{afternoonAppointments.map(appointment => (
<Appointment key={appointment.id}>
<span>
<FiClock />
{appointment.hourFormatted}
</span>
<div>
<img
src={appointment.user.avatar_url}
alt={appointment.user.name}
/>
<strong>{appointment.user.name}</strong>
</div>
</Appointment>
))}
</Section>
</Schedule>
<Calender>
<DayPicker
weekdaysShort={['D', 'S', 'T', 'Q', 'Q', 'S', 'S']}
fromMonth={new Date()}
disabledDays={[{ daysOfWeek: [0, 6] }, ...disabledDays]}
modifiers={{
available: { daysOfWeek: [1, 2, 3, 4, 5] },
}}
onMonthChange={handleMonthChange}
selectedDays={selectedDate}
onDayClick={handleDateChange}
months={[
'Janeiro',
'Fevereiro',
'Março',
'Abril',
'Maio',
'Junho',
'Julho',
'Agosto',
'Setembro',
'Outubro',
'Novembro',
'Dezembro',
]}
/>
</Calender>
</Content>
</Container>
);
}
Example #11
Source File: index.tsx From GoBarber with MIT License | 4 votes |
Dashboard: React.FC = () => {
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
const [currentMonth, setCurrentMonth] = useState<Date>(new Date());
const [appointments, setAppointments] = useState<ScheduleAppointment[]>([]);
const [monthAvailability, setMonthAvailability] = useState<
MonthAvailabilityItem[]
>([]);
const { user } = useAuth();
useEffect(() => {
api
.get<MonthAvailabilityItem[]>(
`/providers/${user.id}/month-availability`,
{
params: {
year: currentMonth.getFullYear(),
month: currentMonth.getMonth() + 1,
},
},
)
.then((response) => {
setMonthAvailability(response.data);
});
}, [currentMonth, user.id]);
useEffect(() => {
api
.get<ScheduleAppointment[]>('/appointments/me', {
params: {
year: selectedDate.getFullYear(),
month: selectedDate.getMonth() + 1,
day: selectedDate.getDate(),
},
})
.then((response) => {
const appointmentsFormatted = response.data.map((appointment) => {
return {
...appointment,
hourFormatted: format(parseISO(appointment.date), 'HH:mm'),
};
});
setAppointments(appointmentsFormatted);
});
}, [selectedDate]);
const handleDateChange = useCallback((day: Date, modifiers: DayModifiers) => {
if (modifiers.available && !modifiers.disabled) {
setSelectedDate(day);
}
}, []);
const handleMonthChange = useCallback((month: Date) => {
setCurrentMonth(month);
}, []);
const disabledDays = useMemo(() => {
const dates = monthAvailability
.filter((monthDay) => monthDay.available === false)
.map((monthDay) => {
const year = currentMonth.getFullYear();
const month = currentMonth.getMonth();
return new Date(year, month, monthDay.day);
});
return dates;
}, [currentMonth, monthAvailability]);
const selectedDateAsText = useMemo(() => {
return format(selectedDate, "'Dia' dd 'de' MMMM", {
locale: ptBR,
});
}, [selectedDate]);
const selectedWeekDay = useMemo(() => {
return format(selectedDate, 'cccc', {
locale: ptBR,
});
}, [selectedDate]);
const morningAppointments = useMemo(() => {
return appointments.filter((appointment) => {
return parseISO(appointment.date).getHours() < 12;
});
}, [appointments]);
const afternoonAppointments = useMemo(() => {
return appointments.filter((appointment) => {
return parseISO(appointment.date).getHours() >= 12;
});
}, [appointments]);
const nextAppointment = useMemo(() => {
return appointments.find((appointment) =>
isAfter(parseISO(appointment.date), new Date()),
);
}, [appointments]);
return (
<Container>
<Header />
<Content>
<Schedule>
<h1>Horários agendados</h1>
<p>
{isToday(selectedDate) && <span>Hoje</span>}
<span>{selectedDateAsText}</span>
<span>{selectedWeekDay}</span>
</p>
{isToday(selectedDate) && nextAppointment && (
<NextAppointment>
<strong>Agendamento a seguir</strong>
<div>
<img
src={nextAppointment.user.avatar_url}
alt={nextAppointment.id}
/>
<strong>{nextAppointment.user.name}</strong>
<span>
<FiClock />
{nextAppointment.hourFormatted}
</span>
</div>
</NextAppointment>
)}
<Section>
<strong>Manhã</strong>
{morningAppointments.length === 0 && (
<p>Nenhum agendamento marcado nesse período</p>
)}
{morningAppointments.map((appointment) => (
<Appointment key={appointment.id}>
<span>
<FiClock />
{appointment.hourFormatted}
</span>
<div>
<img
src={appointment.user.avatar_url || blankAvatar}
alt={appointment.user.name}
/>
<strong>{appointment.user.name}</strong>
</div>
</Appointment>
))}
</Section>
<Section>
<strong>Tarde</strong>
{afternoonAppointments.length === 0 && (
<p>Nenhum agendamento marcado nesse período</p>
)}
{afternoonAppointments.map((appointment) => (
<Appointment key={appointment.id}>
<span>
<FiClock />
{appointment.hourFormatted}
</span>
<div>
<img
src={appointment.user.avatar_url || blankAvatar}
alt={appointment.user.name}
/>
<strong>{appointment.user.name}</strong>
</div>
</Appointment>
))}
</Section>
</Schedule>
<Calendar>
<DayPicker
weekdaysShort={['D', 'S', 'T', 'Q', 'Q', 'S', 'S']}
fromMonth={new Date()}
selectedDays={selectedDate}
disabledDays={[{ daysOfWeek: [0, 6] }, ...disabledDays]}
modifiers={{
available: { daysOfWeek: [1, 2, 3, 4, 5] },
}}
onDayClick={handleDateChange}
onMonthChange={handleMonthChange}
months={[
'Janeiro',
'Fevereiro',
'Março',
'Abril',
'Maio',
'Junho',
'Julho',
'Agosto',
'Setembro',
'Outubro',
'Novembro',
'Dezembro',
]}
/>
</Calendar>
</Content>
</Container>
);
}
Example #12
Source File: Orphanage.tsx From happy with MIT License | 4 votes |
export default function Orphanage() {
const params = useParams<OrphanageParams>();
const [orphanage, setOrphaange] = useState<Orphanage>();
const [activeImageIndex, setActiveImageIndex] = useState(0);
useEffect(() => {
api.get(`/orphanages/${params.id}`).then(res => {
setOrphaange(res.data);
});
}, [params.id]);
if (!orphanage) {
return <p>Carregando...</p>
}
return (
<div id="page-orphanage">
<Sidebar />
<main>
<div className="orphanage-details">
<img src={orphanage.images[activeImageIndex].url} alt={orphanage.name} />
<div className="images">
{orphanage.images.map((image, index) => {
return (
<button
key={image.id}
className={activeImageIndex === index ? "active" : ""}
type="button"
onClick={() => {
setActiveImageIndex(index);
}}
>
<img src={image.url} alt={orphanage.name} />
</button>
)
})}
</div>
<div className="orphanage-details-content">
<h1>{orphanage.name}</h1>
<p>{orphanage.about}</p>
<div className="map-container">
<Map
center={[orphanage.latitude, orphanage.longitude]}
zoom={16}
style={{ width: '100%', height: 280 }}
dragging={false}
touchZoom={false}
zoomControl={false}
scrollWheelZoom={false}
doubleClickZoom={false}
>
<TileLayer
url={`https://api.mapbox.com/styles/v1/mapbox/light-v10/tiles/256/{z}/{x}/{y}@2x?access_token=${process.env.REACT_APP_MAPBOX_TOKEN}`}
/>
<Marker interactive={false} icon={mapIcon} position={[orphanage.latitude, orphanage.longitude]} />
</Map>
<footer>
<a target="_blank" rel="noopener noreferrer" href={`https://google.com/maps/dir/?api=1&destination=${orphanage.latitude},${orphanage.longitude}`}>Ver rotas no Google Maps</a>
</footer>
</div>
<hr />
<h2>Instruções para visita</h2>
<p>{orphanage.instructions}</p>
<div className="open-details">
<div className="hour">
<FiClock size={32} color="#15B6D6" />
Segunda à Sexta <br />
{orphanage.opening_hours}
</div>
{orphanage.open_on_weekends ? (
<div className="open-on-weekends">
<FiInfo size={32} color="#39CC83" />
Atendemos <br />
fim de semana
</div>
) : (
<div className="open-on-weekends dont-open">
<FiInfo size={32} color="#FF6690" />
Não Atendemos <br />
fim de semana
</div>
)}
</div>
{/* <button type="button" className="contact-button">
<FaWhatsapp size={20} color="#FFF" />
Entrar em contato
</button> */}
</div>
</div>
</main>
</div>
);
}