海外TECH |
Ars Technica |
BlackBerry sells mobile and messaging patents for $600 million |
https://arstechnica.com/?p=1830549
|
catapult |
2022-01-31 19:12:34 |
海外TECH |
MakeUseOf |
How to Cancel Your Nintendo Switch Online Subscription |
https://www.makeuseof.com/how-to-cancel-nintendo-switch-online/
|
cancel |
2022-01-31 19:45:22 |
海外TECH |
MakeUseOf |
How to Fix the "Local Adapter Does Not Support An Important Low Energy Controller State" Error on Windows |
https://www.makeuseof.com/windows-local-adapter-does-not-support-important-low-energy-controller-state-error-fix/
|
How to Fix the amp quot Local Adapter Does Not Support An Important Low Energy Controller State amp quot Error on WindowsIf you re getting a weird amp quot Local Adapter Does Not Support An Important Low Energy Controller State amp quot error message here s how to fix it |
2022-01-31 19:15:12 |
海外TECH |
DEV Community |
Create a Url Shortener using NextJs, Tailwind CSS and Strapi |
https://dev.to/strapi/create-a-url-shortener-using-nextjs-tailwind-css-and-strapi-29la
|
Create a Url Shortener using NextJs Tailwind CSS and StrapiAuthor Chibuike NwachukwuEver since the dawn of the internet age links have played an integral part in how we interact and visit web pages It has acted as a means of access to various resources online Its human friendly readable format as opposed to knowing a webpage s actual IP address has contributed immensely to its broad usage Its popularity brought with it some slight issues as more people started creating and hosting websites for their various needs ranging from a company to blogs to events there has been a rapid increase in domain name URLs People now have to remember long URLs in order to visit sites later This is one major issue that URL Shortener came to eliminate Simply put a URL shortener is a service that reduces the length of a URL It achieves this by saving this URL to its records assigning an alias short text to it then redirecting any request made to this alias on its record to the host URL Webpage This tutorial will show you how to build a URL Shortener Service using Next js and Tailwind CSS for frontend and Strapi Headless CMS for backend You can find the link to the completed frontend code here and as well as the completed backend code here Advantages of Using a Shortened URLIt is necessary that before we proceed further into this article we have a clearer understanding of what a URL Shortener does Some of the advantages include Aesthetic appeal Isn t it great to see an invite for an event bearing just the event name in the link as opposed to a long link containing the date location in its URL Analytics tracking As an application that can be deployed in multiple places it reduces the cost of running a large number of customer care representatives Link Swapping Since most URL shortener services allow the editing of the real URL we can always be consistent in the link we share while being flexible with the webpage the link leads to Easier to remember Since most shorteners domains are short e g bit ly TinyURL it is easier for people to recall the URL once it is shared with them PrerequisitesBefore starting this tutorial you need to have Node js installed on your local machine v Check this tutorial for instructions on how to install Node jsBasic understanding of Strapi Get started with this quick guideBasic knowledge of Next jsBasic knowledge of Tailwind CSS What is Next JsNext js is an awesome React framework for building highly dynamic applications It comes with pre rendering server side rendering automatic code splitting amongst many other great features out of the box What is Tailwind CSSTailwind CSS is a utility first CSS framework for rapidly building custom user interfaces With Tailwind CSS we write our CSS directly in our HTML classes This is quite useful as we don t need to import an external stylesheet or use a separate library for UI designs What is StrapiStrapi is a Node js open source headless CMS that allows us to develop APIs and manage content easily without the hassle of building out a project from scratch It allows for customization and self hosting as opposed to the rigid traditional CMS we are used to We can easily build out APIs faster and consume the contents via APIs using any REST API client or GraphQL Scaffolding a Strapi ProjectTo set up a new Strapi Project is quite straightforward as running these few commands npx create strapi app strapi tutorial shortner quickstartChange strapi tutorial shortner to the preferred name of your project This would install and create a Strapi project locally After installation the browser would open a page on localhost which would prompt to set up the first admin account to proceed with Strapi Building the Shortener CollectionNext we will create a new collection type that will store the details of each question and their respective answers Hence we create a collection type called shortner that has these four fields fields alias url visit user Clicking “Continue would bring up another screen to select the fields for this collection Choose the “Text field from the list and provide alias as its name Next we select the Short Text type in the Base Settings as alias is meant to be a short string Next we proceed to the “Advanced settings tab and check the “Required field box to ensure this field is required Also we check the “Unique field box to prevent having the same alias in our record We click on the Add another field to add the answer field Below is a table showing the properties for all the fields we need in this collection Field NameField TypeRequiredUniquealiasShort texttruetrueurlShort texttruefalsevisitNumber integer falsefalseuserNumber integer truefalse Allowing Public accessBy default whenever you create an API they re all going to be restricted from public access We need to tell Strapi that you re okay with exposing these checked endpoints to the public Go to Settings gt Users amp Permissions Plugin gt Roles and click to edit the Public Role Next scroll down to Permissions gt Shortner and tick the find checkbox We would also be exposing some endpoints to the authenticated user Click the “Go Back button and then click edit the Authenticated Role The image below shows the endpoints which would be exposed to the authenticated user Customizing the Shortner ControllerWe customize the shortner controller which is found at src api shortner controllers shortner js to add more functionality to it to cater to our needs For the find method we have the following scenarios If it is called by an authenticated user we only show records that belong to that user This would generally be called by the front end when it wants to display records on the dashboard If it is called by an unauthenticated user we filter based on the query provided this would generally be called by the front end when it wants to check if an alias exists in our record If found we also increment the visit field in the shortner collection to track the visit For the create method we use it to create a new record as well as assign the user field in the shortner collection to the authenticated user s ID Hence only authenticated users have access to this endpoint For the delete method we use it to remove a record from the shortner collection only a user that created a record is allowed to delete it That also means only authenticated users have access to this endpoint Hence replace the code of the file with the code below use strict shortner controller const createCoreController require strapi strapi factories module exports createCoreController api shortner shortner strapi gt async find ctx let query ctx const user ctx state user let entity if user query user eq user id entity await strapi service api shortner shortner find filters query else query alias eq query alias entity await strapi service api shortner shortner find filters query if entity results length let id entity results id let visit Number entity results visit await strapi service api shortner shortner update id data visit const sanitizedEntity await this sanitizeOutput entity ctx return this transformResponse sanitizedEntity async create ctx const data ctx request body const user ctx state user let entity data user user id entity await strapi service api shortner shortner create data const sanitizedEntity await this sanitizeOutput entity ctx return this transformResponse sanitizedEntity async delete ctx let id ctx params const user ctx state user let entity let query user eq user id id eq id entity await strapi service api shortner shortner find filters query if entity results length return ctx badRequest null messages id You can delete someone else content entity await strapi service api shortner shortner delete id const sanitizedEntity await this sanitizeOutput entity ctx return this transformResponse sanitizedEntity Scaffolding a Next js projectCreating a Next js appTo create a Next js app open your terminal cd into the directory you d like to create the app in and run the following command npx create next app e with tailwindcss nextjs shortnerThis would also configure Tailwind CSS with the project Running the Next js Development ServerNext we cd into the newly created directory in our case that would be nextjs shortner cd nextjs shortnerAfter which we start up the development server by running this command npm run devIf everything was set up fine the Next js server should now be running on localhost and we should see the following page on our browser Building Next js ComponentsNext we open up any text editor of our choice to write code for the rest of the application Open up the installed project and we should have a folder structure such as this To begin the design of the interface we would remove all of the code in the index js file and add the code below import React useContext useEffect from react import MyContext from lib context import useRouter from next router export default function Home const isLoggedIn user useContext MyContext const router useRouter useEffect gt if isLoggedIn return router push dashboard return router push login isLoggedIn return null The above code makes use of React Context API to check if the user is authenticated This determines which page gets shown to the user As can also be seen we are importing a context file from the lib folder We need to create this file Go to the root of the project and create a folder called lib then create a file called context js in it Inside this context js we create the context and also assign the default value of false to isLoggedIn import React from react const MyContext React createContext isLoggedIn false export default MyContext Next we head straight to create the two files we would conditionally be redirecting to the Login and Register files Next js creates routes for files under the pages directory The route points to the files themselves their documentation explains it quite well This means if we created a file called dashboard js in the pages directory we can access it by visiting localhost dashboard without needing to create an additional routing mechanism Great right So we simply create the two files Login and Register in this pages directory However before we dive into these two pages we would need to first update the content of the app js page This page is used by Next js to initialize other pages so we could use it to achieve persistent layout between pages custom error handling and in our case keeping a global state among pages Read more about this page here Create an app js file if it doesn t exist in the pages director Remove everything in it and replace its code with the code below import React useState useEffect from react import MyContext from lib context import Cookie from js cookie import tailwindcss tailwind css export default function App Component pageProps const user setUser useState null const urls setUrls useState useEffect gt const jwt Cookie get jwt if jwt fetch process env NEXT PUBLIC API URL api users me headers Authorization Bearer jwt then async res gt if res ok Cookie remove jwt setUser null const user await res json setUser user return lt MyContext Provider value user user isLoggedIn user setUser setUrls urls gt lt Component pageProps gt lt MyContext Provider gt The above code simply wraps itself around all pages and handles the global state by using React Context API We also use the js cookie npm package to store our token to persist a session even when the user refreshes the page To get it installed we run the npm i js cookie command Then we import it into our file import Cookie from js cookie We make use of the useEffect hook to check if there is a stored token meaning the user is logged in If a token is found we make a request to the Strapi API to get the details of this user If there are no errors we store the user in the user state else we delete the token and assign null to the user state useEffect gt const jwt Cookie get jwt if jwt fetch process env NEXT PUBLIC API URL api users me headers Authorization Bearer jwt then async res gt if res ok Cookie remove jwt setUser null const user await res json setUser user As can also be seen we have two states user and urls created using the useState hook We have seen the use of the user state already we use the urls state to store the array of shorteners that we got from the Strapi API Lastly we wrap the Component with the Context API provider similar to how we do it in Redux Next we set the values of the Context API to our state variables as well as functions such as setUrls setUser so that other pages components would be able to access them Finally we create a new variable called isLoggedIn this would be used to check if there exists an authenticated user return lt MyContext Provider value user user isLoggedIn user setUser setUrls urls gt lt Component pageProps gt lt MyContext Provider gt Now we would go on to create the Register file Add the content below to the newly created pages register js file import Head from next head import Link from next link import React useState useContext useEffect from react import MyContext from lib context import register from lib auth import useRouter from next router export default function Register const isLoggedIn setUser useContext MyContext const router useRouter let username setUsername useState let email setEmail useState let password setPassword useState const loading setLoading useState false const errors setErrors useState useEffect gt if isLoggedIn return router push dashboard isLoggedIn const submit async gt if username trim return setErrors username Username must not be empty if email return setErrors email Email must not be empty if password return setErrors password Password must not be empty setLoading true const reg await register username email password setLoading false if reg jwt setUser reg user router push dashboard else setErrors server reg error message Error from server return lt div className flex flex col items center justify center min h screen py gt lt Head gt lt title gt Create Next App lt title gt lt link rel icon href favicon ico gt lt Head gt lt main className flex flex col items center justify center w full flex px text center gt lt h className text xl font bold text blue gt Url Shortener lt h gt lt div className flex flex wrap items center justify around max w xl mt sm w full gt lt form className w full max w lg mt onSubmit e gt e preventDefault submit gt lt div className flex flex wrap mx mb gt lt div className w full px mb md mb gt lt input onChange e gt setUsername e target value placeholder Enter username className appearance none block w full text gray mb border rounded py px leading tight focus outline none focus bg white focus border gray errors username border red border gray id grid username type text gt errors username lt p className text red text xs italic gt errors username lt p gt lt div gt lt div gt lt div className flex flex wrap mx mb gt lt div className w full px mb md mb gt lt input onChange e gt setEmail e target value placeholder Enter email className appearance none block w full text gray mb border rounded py px leading tight focus outline none focus bg white focus border gray errors email border red border gray id grid email type email gt errors email lt p className text red text xs italic gt errors email lt p gt lt div gt lt div gt lt div className flex flex wrap mx mb gt lt div className w full px gt lt span className w full inline flex items center rounded border border r text gray mb text sm focus outline none focus bg white focus border gray errors password border red border gray gt lt input onChange e gt setPassword e target value placeholder className appearance none block rounded w full py px leading tight id grid password type password gt lt span gt errors password lt p className text red text xs italic gt errors password lt p gt lt div gt lt div gt errors server lt p className text red text xs italic gt errors server lt p gt lt div className flex flex row flex wrap justify between gt lt span className text blue hover text gray pt md p gt lt Link href login gt Back to Login lt Link gt lt span gt lt button disabled loading className w full md w mt flex justify center hover bg gray hover text gray rounded md px py uppercase loading bg gray text black cursor not allowed bg gray text white cursor pointer gt loading lt gt loading amp nbsp lt gt Register lt button gt lt div gt lt form gt lt div gt lt main gt lt div gt The above code registers users to the platform allowing us to create a secured page later for people to come in create manage and track their shortened URLs We also use the useContext hook to get our state values and functions import React useState useContext useEffect from react import MyContext from lib context const isLoggedIn setUser useContext MyContext Also we use the useEffect hook to apply middleware on the page so that only the unauthenticated user can access the page We achieve this using the isLoggedIn state import React useState useContext useEffect from react useEffect gt if isLoggedIn return router push dashboard isLoggedIn If a user is authenticated we redirect them back to their dashboard The submit method handles user registration validates and sets the user state to the signed user if successful and then redirects the user to their dashboard const submit async gt if username trim return setErrors username Username must not be empty if email return setErrors email Email must not be empty if password return setErrors password Password must not be empty setLoading true const reg await register username email password setLoading false if reg jwt setUser reg user router push dashboard else setErrors server reg error message Error from server As can be seen we make use of a function called register which handles the sending of a request to the Strapi API import register from lib auth const reg await register username email password We proceed to create this file auth js in the lib folder This file makes authenticated requests to our API and handles other auth related functions like logout Add the content below into the file import Cookie from js cookie const API URL process env NEXT PUBLIC API URL http localhost export const register async username email password gt try let response await fetch API URL api auth local register method POST body JSON stringify username email password headers Content Type application json response await response json if response Cookie set jwt response jwt return response catch e return error An error occured export const login async identifier password gt try let response await fetch API URL api auth local method POST body JSON stringify identifier password headers Content Type application json response await response json if response Cookie set jwt response jwt return response catch e return error An error occured export const logout gt Cookie remove jwt As can be seen we use the js cookie package to assign the jwt once a user is logged in or registered as well as delete this token once the user logs out This also leads us to create a env at the root of our project Inside it we would have NEXT PUBLIC API URL http localhost Now we would go on to create the Login file Add the content below to the newly create pages login js file import Head from next head import React useState useEffect useContext from react import MyContext from lib context import useRouter from next router import login from lib auth import Link from next link export default function Login let email setEmail useState let password setPassword useState const loading setLoading useState false const errors setErrors useState const isLoggedIn setUser useContext MyContext const router useRouter const signIn async gt if email return setErrors email Email must not be empty if password return setErrors password Password must not be empty setLoading true const reg await login email password setLoading false if reg jwt setUser reg user router push else setErrors server reg error message Error from server useEffect gt if isLoggedIn return router push dashboard isLoggedIn return lt div className flex flex col items center justify center min h screen py gt lt Head gt lt title gt Create Next App lt title gt lt link rel icon href favicon ico gt lt Head gt lt main className flex flex col items center justify center w full flex px text center gt lt h className text xl font bold text blue gt Url Shortener lt h gt lt div className flex flex wrap items center justify around max w xl mt sm w full gt lt form className w full max w lg mt onSubmit e gt e preventDefault signIn email password gt lt div className flex flex wrap mx mb gt lt div className w full px mb md mb gt lt input onChange e gt setEmail e target value placeholder Enter email className appearance none block w full text gray mb border rounded py px leading tight focus outline none focus bg white focus border gray errors email border red border gray id grid email type email gt errors email lt p className text red text xs italic gt errors email lt p gt lt div gt lt div gt lt div className flex flex wrap mx mb gt lt div className w full px gt lt span className w full inline flex items center rounded border border r text gray mb text sm focus outline none focus bg white focus border gray errors password border red border gray gt lt input onChange e gt setPassword e target value placeholder className appearance none block rounded w full py px leading tight id grid password type password gt lt span gt errors password lt p className text red text xs italic gt errors password lt p gt lt div gt lt div gt errors server lt p className text red text xs italic gt errors server lt p gt lt div className flex flex row flex wrap justify between gt lt button disabled loading className w full md w mt flex justify center align center hover bg gray hover text gray rounded md px py uppercase loading bg gray text black cursor not allowed bg gray text white cursor pointer gt loading lt gt loading amp nbsp lt gt LOG IN lt button gt lt span className text blue hover text gray pt md p gt lt Link href register gt Register lt Link gt lt span gt lt div gt lt form gt lt div gt lt main gt lt div gt The above code allows users to login and get access to the secured dashboard It is similar to the register only that it doesn t create users but checks their existence in the record and authenticates them This also makes use of the lib auth js file which we have seen already The remaining pages we would be looking at now are the Dashboard page We would use this to handle the deletion and viewing of the shortened URLs Add Url page This is used to add a shortened URL Alias page This is used to redirect to the URL if the alias is found in our record Building the Dashboard PageAs discussed earlier this page shows all created records as well as enables the user to test them and delete them Proceed to create a file called dashboard js in the pages folder pages dashboard js Insert the code below as its content import Head from next head import React useEffect useContext useState from react import MyContext from lib context import useRouter from next router import Link from next link import logout from lib auth import get deleteAlias from lib shortener export default function Dashboard const isLoggedIn setUser user setUrls urls useContext MyContext const router useRouter const getAll async gt let short await get if short return setUrls short data attributes results null const deleteShort async id gt if id return let deleted await deleteAlias id if deleted data amp amp deleted error await getAll useEffect gt if isLoggedIn return router push login getAll urls length const signOut gt logout setUser null router push login return lt div className flex flex col items center justify center min h screen py gt lt Head gt lt title gt Dashboard lt title gt lt link rel icon href favicon ico gt lt Head gt lt header className flex justify between align center p h w full text xl font bold text blue gt lt h className text xl font bold text blue gt Url Shortener lt h gt lt span className text sm font bold text red cursor pointer onClick gt signOut gt Logout lt span gt lt header gt lt main className flex flex col items center w full mt flex px text center gt lt p className flex flex wrap w full text lg font bold gt Welcome user username lt p gt lt div className flex flex wrap items center justify around max w xl mt sm w full gt lt div className shadow border b w full overflow hidden border gray sm rounded lg gt lt table className min w full divide y divide gray gt lt thead gt lt tr gt lt th scope col className px py bg gray text center text xs font medium text gray uppercase tracking wider gt Url lt th gt lt th scope col className px py bg gray text center text xs font medium text gray uppercase tracking wider gt Alias Shortned lt th gt lt th scope col className px py bg gray text center text xs font medium text gray uppercase tracking wider gt No of hits lt th gt lt th scope col className px py bg gray gt lt span className sr only gt Remove lt span gt lt th gt lt tr gt lt thead gt lt tbody className bg white divide y divide gray gt urls urls length amp amp lt tr gt lt td colSpan className px py whitespace nowrap cursor pointer gt No record found lt td gt lt tr gt urls amp amp urls map short gt lt tr className hover bg gray key short id gt lt td className px py whitespace nowrap cursor pointer title Open Url onClick gt window open short url blank gt lt div className text sm text gray gt short url N A lt div gt lt td gt lt td className px py whitespace nowrap cursor pointer title Test Alias onClick gt window open short alias blank gt lt div className text sm text gray gt short alias N A lt div gt lt td gt lt td className px py whitespace nowrap cursor pointer gt lt span className px text xs leading font semibold rounded full gt lt div className text sm text gray gt short visit lt div gt lt span gt lt td gt lt td className px py whitespace nowrap text center text sm font medium gt lt button onClick gt deleteShort short id className text red hover text red mx gt Delete lt button gt lt td gt lt tr gt lt tbody gt lt table gt lt div gt lt div gt lt main gt lt Link href addUrl gt lt button className absolute rounded full text white font bold text lg p bg blue w h m right bottom hover bg blue gt lt button gt lt Link gt lt div gt In a nutshell we use this to show users their shortened URLs As can be seen we use the useEffect hook to help prevent unauthenticated users from accessing the page Also we have functions to handle deleting a record getting all records and logout users The functions that handle the delete and get call a central shortener helper file called shortener js import get deleteAlias from lib shortener We use this file to handle all shortener related functionalities Hence we proceed to create this file inside the lib folder lib shortener js and add the code below as its content import Cookie from js cookie const API URL process env NEXT PUBLIC API URL http localhost export const get async gt const token Cookie get jwt try let response await fetch API URL api shortners method GET headers Content Type application json Authorization Bearer token response await response json return response catch e return error An error occured export const getSingle async alias gt try let response await fetch API URL api shortners alias alias method GET headers Content Type application json response await response json return response catch e return error An error occured export const create async url alias gt const token Cookie get jwt try let response await fetch API URL api shortners method POST body JSON stringify data url alias headers Content Type application json Authorization Bearer token response await response json return response catch e return error An error occured export const deleteAlias async id gt const token Cookie get jwt try let response await fetch API URL api shortners id method DELETE headers Content Type application json Authorization Bearer token response await response json return response catch e return error An error occured Building the Add URL PageAs discussed earlier this page handles the creation of shortened URLs Proceed to create a file called addUrl js inside the pages folder pages addUrl js Next add the content below as its new content import Head from next head import Link from next link import React useEffect useContext useState from react import MyContext from lib context import useRouter from next router import logout from lib auth import create from lib shortener export default function AddUrl const isLoggedIn setUser useContext MyContext const url setUrl useState const alias setAlias useState const loading setLoading useState false const errors setErrors useState const router useRouter useEffect gt if isLoggedIn return router push login isLoggedIn const shorten async gt if url return setErrors url Url must not be empty if alias return setErrors alias Alias must not be empty setLoading true const short await create url alias setLoading false if short data amp amp short error router push dashboard else setErrors server short error message Error from server const signOut gt logout setUser null router push login return lt div className flex flex col items center justify center min h screen py gt lt Head gt lt title gt Add Url lt title gt lt link rel icon href favicon ico gt lt Head gt lt header className flex justify between align center p h w full text xl font bold text blue gt lt h className text xl font bold text blue gt Url Shortener lt h gt lt span className text sm font bold text red cursor pointer onClick gt signOut gt Logout lt span gt lt header gt lt main className flex flex col items center w full mt flex px text center gt lt p className flex flex wrap w full text lg font bold gt Fill the form lt p gt lt div className flex flex wrap items center justify around max w xl mt sm w full gt lt form className w full max w lg mt onSubmit e gt e preventDefault shorten gt lt div className flex flex wrap mx mb gt lt div className w full px mb md mb gt lt input onChange e gt setUrl e target value placeholder Enter url className appearance none block w full text gray mb border rounded py px leading tight focus outline none focus bg white focus border gray errors url border red border gray id grid url type text gt errors url lt p className text red text xs italic gt errors url lt p gt lt div gt lt div gt lt div className flex flex wrap mx mb gt lt div className w full px mb md mb gt lt input onChange e gt setAlias e target value placeholder Enter alias className appearance none block w full text gray mb border rounded py px leading tight focus outline none focus bg white focus border gray errors alias border red border gray id grid alias type text gt errors alias lt p className text red text xs italic gt errors alias lt p gt lt div gt lt div gt errors server lt p className text red text xs italic gt errors server lt p gt lt div className flex flex row flex wrap justify between gt lt span className text blue hover text gray pt md p gt lt Link href dashboard gt Back to Dashboard lt Link gt lt span gt lt button disabled loading className w full md w mt flex justify center hover bg gray hover text gray rounded md px py uppercase loading bg gray text black cursor not allowed bg gray text white cursor pointer gt loading lt gt loading amp nbsp lt gt Shorten lt button gt lt div gt lt form gt lt div gt lt main gt lt div gt This is quite straightforward to understand we simply make use of the shortener file in the lib folder to make a request to our Strapi API to add the record We also make use of the useEffect hook to prevent unauthenticated users from accessing the page Building the Alias PageThis page is the one which is in charge of checking if the alias exists in our record and redirecting the user accordingly Subsequently if an alias is found in our record the Strapi API records that as a visit to the alia giving us the ability to see analytics ofa particular alias We proceed to create a file called alias js in the pages folder pages alias js If this looks strange check how to build pages with dynamic routes in the Next js Next insert the content below as the content of this file import useRouter from next router import useEffect from react import getSingle from lib shortener const AliasView error gt const router useRouter useEffect gt if error return router push return null export async function getServerSideProps params const url await getSingle params alias if url data amp amp url data attributes results false amp amp url error return redirect destination url data attributes results url permanent false return props error error export default AliasView As can be seen we use the getServerSideProps to check if the alias exists in our record if so we redirect to the actual URL export async function getServerSideProps params const url await getSingle params alias if url data amp amp url data attributes results false amp amp url error return redirect destination url data attributes results url permanent false return props error error If we can t find it we pass the error prop to the actual component return props error error Then in our component we redirect the user to the home page since the alias isn t in our record const AliasView error gt const router useRouter useEffect gt if error return router push return null If the user is authenticated they would get redirected to the Dashboard page else they would get redirected to the Login page Did we implement this feature on the Index js page Yes we did And that s it for the code section of the frontend part of this tutorial If you have come this far I must say you are doing great Enough for all this technical stuff in the next section we would be seeing a demo of the finished app Testing Finished AppThe finished app looks like this ConclusionThe benefits a URL Shortener brings can t be over emphasized This is seen in the rapid outbreak of companies playing in this space You can go ahead to add more features to this project by simply forking the repo found at beginning of this tutorial and getting your hands dirty It s best left to the imagination what you can achieve This tutorial demonstrated how easily you can build a URL Shortener Service in about minutes using technologies like Next js and Strapi Once again Strapi has shown us that it is equal to the task when it comes to creating great APIs |
2022-01-31 19:15:58 |
Apple |
AppleInsider - Frontpage News |
New iMac Pro coming later than expected with modified mini LED backlights, says new report |
https://appleinsider.com/articles/22/01/31/new-imac-pro-coming-later-than-expected-with-modified-mini-led-backlights-says-new-report?utm_medium=rss
|
New iMac Pro coming later than expected with modified mini LED backlights says new reportApple s iMac Pro refresh with a mini LED display and an Apple Silicon chip is coming in the summer of instead the spring according to a display analyst Render of the inch iMac Pro with an Apple Silicon chipRoss Young of Display Supply Chain Consultants on Monday said he no longer expects the upcoming iMac Pro refresh to launch in the spring of In a subsequent tweet Young said that panel shipments will start in June but the Apple Silicon iMac Pro itself may not launch until August or September Read more |
2022-01-31 19:13:01 |
Apple |
AppleInsider - Frontpage News |
Apple Watch saves man's life after fall in freezing temperatures |
https://appleinsider.com/articles/22/01/31/apple-watch-credited-for-saving-mans-life-after-fall-in-freezing-temperatures?utm_medium=rss
|
Apple Watch saves man x s life after fall in freezing temperaturesIn the middle of the US east coast cold snap emergency services saved an unconscious man in Morrow Georgia after his Apple Watch detected a fall and alerted local authorities Apple s latest ads for the Apple Watch Series have concentrated on how the device can automatically call for help in emergencies Now yet another example of this feature saving a life has been reported in the City of Morrow Clayton County Georgia According to local CB News Atlanta an elderly resident fell while outside his property on January His Watch detected the fall and when he failed to respond that he was okay alerted the Clayton County Emergency Communications Center Read more |
2022-01-31 19:53:37 |
海外TECH |
Engadget |
MLB The Show is coming to Switch for the first time |
https://www.engadget.com/mlb-the-show-2-nintendo-switch-xbox-game-pass-192041042.html?src=rss
|
MLB The Show is coming to Switch for the first timeMLB The Show nbsp will arrive on April th and for the first time in the series you ll be able to play on Nintendo Switch There will be full cross platform support between Switch PlayStation and Xbox You ll be able to transfer Road to the Show or Franchise save files between platforms and have access to items across various consoles though Xbox Series X S and PS exclusive content will remain locked to those systems As with last year s edition which was the first to land on Xbox MLB The Show is coming to Xbox Game Pass on its release day That continues an unusual arrangement where a Sony published title is available to Game Pass members at no extra cost Subscribers can play via the cloud as well as on consoles This year s cover athlete is Los Angeles Angels megastar Shohei Ohtani The pitcher and designated hitter had an incredible season racking up home runs and strikeouts It s pretty hard to imagine anyone else gracing MLB The Show s nbsp cover |
2022-01-31 19:20:41 |
海外TECH |
Engadget |
Sony is buying Destiny studio Bungie |
https://www.engadget.com/sony-buy-bungie-destiny-studio-180905449.html?src=rss
|
Sony is buying Destiny studio BungieSony has plans to acquire Bungie the studio behind the hit sci fi MMO Destiny in a deal worth billion Bungie will join the Sony Interactive Entertainment family which includes Insomniac Games Naughty Dog Guerrilla Games Sucker Punch Productions Bluepoint Games and a handful of other prominent studios Bungie is positioning the acquisition as the start of a new era for the company ーone focused on global multi media entertainment not just games Bungie will retain creative control over its franchises and continue to develop for multiple platforms not just PlayStation according to a blog post by CEO Pete Parsons quot We will continue to independently publish and creatively develop our games quot he wrote quot We will continue to drive one unified Bungie community Our games will continue to be where our community is wherever they choose to play quot The deal follows news on January th that Microsoft is buying Activision Blizzard for billion and it s the latest sign that the video game industry has entered the consolidation stage Massive companies including Microsoft Sony and Tencent are in the process of sweeping up as many studios as they can in a battle for exclusive experiences As console makers Sony and Microsoft hold particular power in these negotiations with built in audiences of millions on the PlayStation and Xbox platforms These deals give the acquired studios financial stability production support and wide reaching marketing plans though they ll have to operate within a corporate ecosystem and potentially tie their games to specific platforms Bungie it seems has plans to publish outside of Sony s PlayStation universe though time will tell what that looks like in practice Sony s purchase of Bungie is surprising given where the studio started Bungie is the original home of the Halo franchise and it was part of the Microsoft family from to Halo was and is a pivotal series for Xbox consoles and Bungie was its arbiter for nearly a decade under Microsoft The studios split in and Bungie went private and in it signed a publishing agreement with Activision for the Destiny franchise That deal lasted through when Bungie moved its publishing process in house Just two weeks ago Microsoft announced it was acquiring Activision Blizzard bringing the two former Bungie publishers under one roof And now Bungie has Microsoft s biggest rival Sony in its back pocket These relationships are only going to get more complicated as the consolidation era runs its course through the video game industry so buckle up for more multibillion dollar deals and exclusivity clauses over the coming years |
2022-01-31 19:12:44 |
海外TECH |
CodeProject Latest Articles |
Using CodeProject SenseAI with Blue Iris |
https://www.codeproject.com/Articles/5323944/Using-CodeProject-SenseAI-with-Blue-Iris
|
system |
2022-01-31 19:56:00 |
海外科学 |
NYT > Science |
Biden Administration to Reinstate Mercury Pollution Rules Weakened Under Trump |
https://www.nytimes.com/2022/01/31/climate/epa-mercury-pollution-coal.html
|
Biden Administration to Reinstate Mercury Pollution Rules Weakened Under TrumpThe E P A will resume enforcing limits on the release of mercury a neurotoxin linked to developmental damage in children from coal burning power plants |
2022-01-31 19:14:02 |
医療系 |
医療介護 CBnews |
「かかりつけ」との関係強化は病院の喫緊の経営課題-連携と横展開が病院経営を強くする(4) |
https://www.cbnews.jp/news/entry/20220131170052
|
代表取締役 |
2022-02-01 05:00:00 |
ニュース |
BBC News - Home |
Covid: Ministers to consult over NHS jab requirement for England |
https://www.bbc.co.uk/news/uk-60207436?at_medium=RSS&at_campaign=KARANGA
|
omicron |
2022-01-31 19:23:56 |
ニュース |
BBC News - Home |
Aubameyang to have Barcelona medical as they agree free transfer from Arsenal |
https://www.bbc.co.uk/sport/football/60186125?at_medium=RSS&at_campaign=KARANGA
|
arsenal |
2022-01-31 19:47:35 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
【青森・岩手・秋田】14信金信組「勝ち残り」ランキング!ワースト2位は岩手・水沢信金、1位は? - 銀行信金信組勝ち残りランキング |
https://diamond.jp/articles/-/292466
|
信用組合 |
2022-02-01 04:55:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
マッキンゼー流!他社比較やM&Aに必須の「DCF法・マルチプル法」の真髄を解説【動画】 - マッキンゼー流!リーダーの新教科書 ―戦略とファイナンス― |
https://diamond.jp/articles/-/292533
|
企業価値 |
2022-02-01 04:50:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
環境が変わると結果が出せない人と、成果を出し続ける人の「決定的な差」 - トンデモ人事部が会社を壊す |
https://diamond.jp/articles/-/294862
|
目標達成 |
2022-02-01 04:45:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
漫画『二月の勝者』に学ぶ、「中学受験生はかわいそう」の大矛盾 - 『二月の勝者』になる!乱世の中学受験術 |
https://diamond.jp/articles/-/293952
|
中学受験 |
2022-02-01 04:40:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
日本はインフレ加速の世界がうらやむ「物価優等生」!?物価安定が“弱み”に転じる条件 - 政策・マーケットラボ |
https://diamond.jp/articles/-/294861
|
日本企業 |
2022-02-01 04:35:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
【成蹊高校】華麗なる卒業生人脈!安倍晋三、三菱商事元社長の槙原稔、俳優の中井貴一… - 日本を動かす名門高校人脈 |
https://diamond.jp/articles/-/293974
|
三菱商事 |
2022-02-01 04:30:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
岸田内閣の支持率低下、菅政権へのコロナ対応「痛烈批判」が大ブーメラン - DOL特別レポート |
https://diamond.jp/articles/-/294897
|
|
2022-02-01 04:22:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
ユニクロだけじゃない、日本企業が「取引先の人権リスク調査」を迫られる深刻な理由 - DOL特別レポート |
https://diamond.jp/articles/-/294268
|
対中姿勢 |
2022-02-01 04:20:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
外資が強いペットフード業界で、日本メーカーが見いだした「独自路線」 - News&Analysis |
https://diamond.jp/articles/-/293871
|
newsampampanalysis |
2022-02-01 04:15:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
韓国景気は半導体特需で回復しているのに、若者の不満が爆発寸前の理由 - 今週のキーワード 真壁昭夫 |
https://diamond.jp/articles/-/294859
|
|
2022-02-01 04:10:00 |
ビジネス |
ダイヤモンド・オンライン - 新着記事 |
会社に内緒の副業。バイト先で怪我をしたら、労災は下りるのか? - 組織を壊す「自分ファースト」な社員たち 木村政美 |
https://diamond.jp/articles/-/294738
|
自分ファースト |
2022-02-01 04:05:00 |
ビジネス |
不景気.com |
東京電力の22年3月期は410億円の赤字へ、インバランス還元損失 - 不景気.com |
https://www.fukeiki.com/2022/02/tepco-2022-loss2.html
|
東京電力 |
2022-01-31 19:15:59 |
ビジネス |
東洋経済オンライン |
「2022年3月ダイヤ改正で引退」の鉄道車両6選 全国のJRから私鉄まで、大人気列車も姿を消す | 経営 | 東洋経済オンライン |
https://toyokeizai.net/articles/-/505325?utm_source=rss&utm_medium=http&utm_campaign=link_back
|
東洋経済オンライン |
2022-02-01 04:30:00 |
GCP |
Cloud Blog |
Smarter applications with Document AI, Workflows and Cloud Functions |
https://cloud.google.com/blog/topics/developers-practitioners/smarter-applications-document-ai-workflows-and-cloud-functions/
|
Smarter applications with Document AI Workflows and Cloud FunctionsAt enterprises across industries documents are at the center of core business processes Documents store a treasure trove of valuable information whether it s a company s invoices HR documents tax forms and much more However the unstructured nature of documents make them difficult to work with as a data source We call this dark data or unstructured data that businesses collect process and store but do not utilize for purposes such as analytics monetization etc These documents in pdf or image formats often trigger complex processes that have historically relied on fragmented technology and manual steps With compute solutions on Google Cloud and Document AI you can create seamless integrations and easy to use applications for your users Document AI is a platform and a family of solutions that help businesses to transform documents into structured data backed by machine learning In this blog post we ll walk you through how to use Serverless technology to process documents with Cloud Functions and with workflows of business processes orchestrating microservices API calls and functions thanks to Workflows At Cloud Next we presented how to build easy AI powered applications with Google Cloud We introduced a sample application for handling incoming expense reports analyzing expense receipts with Procurement Document AI a DocAI solution for automating procurement data capture from forms including invoices utility statements and more Then organizing the logic of a report approval process with Workflows and used Cloud Functions as glue to invoke the workflow and do analysis of the parsed document We also open sourced the code on this Github repository if you re interested in learning more about this application In the above diagram there are two user journeys the employee submitting an expense report where multiple receipts are processed at once and the manager validating or rejecting the expense report First the employee goes to the website powered by Vue js for the frontend progressive JavaScript framework and Shoelace for the library of web components The website is hosted via Firebase Hosting The frontend invokes an HTTP function that triggers the execution of our business workflow defined using the Workflows YAML syntax Workflows is able to handle long running operations without any additional code required in our case we are asynchronously processing a set receipt files Here the Document AI connector directly calls the batch processing endpoint for service This API returns a long running operation if you poll the API the operation state will be RUNNING until it has reached a SUCCEEDED or FAILED state You would have to wait for its completion However Workflows connectors handle such long running operations without you having to poll the API multiple times till the state changes Here s how we call the batch processing operation of the Document AI connector Machine learning uses state of the art Vision and Natural Language Processing models to intelligently extract schematized data from documents with Document AI As a developer you don t have to figure out how to fine tune or reframe the receipt pictures or how to find the relevant field and information in the receipt It s Document AI s job to help you here it will return a JSON document whose fields are line item currency supplier name total amount etc Document AI is capable of understanding standardized papers and forms including invoices lending documents pay slips driver licenses and more A cloud function retrieves all the relevant fields of the receipts and makes its own tallies before submitting the expense report for approval to the manager Another useful feature of Workflows is put to good use Callbacks that we introduced last year In the workflow definition we create a callback endpoint and the workflow execution will wait for the callback to be called to continue its flow thanks to those two instructions In this example application we combined the intelligent capabilities of Document AI to transform complex image documents into usable structured data with Cloud Functions for data transformation process triggering and callback handling logic and Workflows enabled us to orchestrate the underlying business process and its service call logic Going further If you re looking to make sense of your documents turning dark data into structured information be sure to check out what Document AI offers You can also get your hands on a codelab to get started quickly in which you ll get a chance at processing handwritten forms If you want to explore Workflows quickstarts are available to guide you through your first steps and likewise another codelab explores the basics of Workflows As mentioned earlier for a concrete example the source code of our smart expense application is available on Github Don t hesitate to reach out to us at glaforge and asrivas dev to discuss smart scalable apps with us Related ArticleCustomers cut document processing time and costs with DocAI solutions now generally availableDocument AI platform Lending DocAI and Procurement DocAI are generally available Read Article |
2022-01-31 20:00:00 |
コメント
コメントを投稿